598 lines
17 KiB
C#
598 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
|
|
namespace Casino
|
|
{
|
|
public partial class Busfahrer : Window
|
|
{
|
|
public class Card //Colin Langer
|
|
{
|
|
public int Id { get; set; }
|
|
public string WertRaw { get; set; } = string.Empty;
|
|
public string FarbeRaw { get; set; } = string.Empty;
|
|
public ImageSource Image { get; set; } = null!;
|
|
public int NumericValue { get; set; }
|
|
|
|
public bool IsRed =>
|
|
FarbeRaw.Equals("Hearts", StringComparison.OrdinalIgnoreCase) ||
|
|
FarbeRaw.Equals("Diamond", StringComparison.OrdinalIgnoreCase);
|
|
|
|
//Colin Langer
|
|
public Card(int id, string wert, string farbe, byte[] imgBytes)
|
|
{
|
|
Id = id;
|
|
WertRaw = wert;
|
|
FarbeRaw = farbe;
|
|
NumericValue = ParseValue(wert);
|
|
|
|
if (imgBytes != null && imgBytes.Length > 0)
|
|
{
|
|
Image = ByteArrayToImage(imgBytes);
|
|
}
|
|
}
|
|
//Colin Langer
|
|
//verwandelt den textwert in punktwert um
|
|
private static int ParseValue(string wert)
|
|
{
|
|
return wert.Trim() switch
|
|
{
|
|
"Jack" => 11,
|
|
"Queen" => 12,
|
|
"King" => 13,
|
|
"Ace" => 14,
|
|
_ => int.TryParse(wert, out int value) ? value : 0
|
|
};
|
|
}
|
|
//Colin Langer
|
|
//konvertiert das Bild von der Datenbank um
|
|
private static BitmapImage ByteArrayToImage(byte[] bytes)
|
|
{
|
|
BitmapImage image = new BitmapImage();
|
|
|
|
using (MemoryStream ms = new MemoryStream(bytes))
|
|
{
|
|
image.BeginInit();
|
|
image.CacheOption = BitmapCacheOption.OnLoad;
|
|
image.StreamSource = ms;
|
|
image.EndInit();
|
|
}
|
|
|
|
image.Freeze();
|
|
return image;
|
|
}
|
|
}
|
|
|
|
private readonly Database db = new Database();
|
|
private ObservableCollection<User> users;
|
|
|
|
private List<Card> deck = new List<Card>();
|
|
private List<Card> handCards = new List<Card>();
|
|
private ImageSource cardBackImage = null!;
|
|
Audioplayer music = new Audioplayer();
|
|
|
|
private int currentPhase = 0;
|
|
private decimal currentBet = 0;
|
|
private decimal currentProfit = 0;
|
|
private bool roundRunning = false;
|
|
|
|
public Busfahrer()
|
|
{
|
|
InitializeComponent();
|
|
|
|
users = db.GetUser();
|
|
UpdateAccountDisplay();
|
|
|
|
ShowWaitingState();
|
|
music.PlayLoopingSound_2(db.GetSound(20));
|
|
}
|
|
|
|
private User CurrentUser => users[MainWindow.currentUser];
|
|
|
|
// Lenard Gerdes
|
|
private void UpdateAccountDisplay()
|
|
{
|
|
Konto.Text = CurrentUser.Geld.ToString();
|
|
}
|
|
// Lenard Gerdes
|
|
private void SaveAccount()
|
|
{
|
|
db.UpdateGeld(CurrentUser.ID, CurrentUser.Geld);
|
|
UpdateAccountDisplay();
|
|
}
|
|
//Colin Langer
|
|
private void BtnStart_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
StartGameFromInput();
|
|
}
|
|
//Colin Langer
|
|
private void StartGameFromInput()
|
|
{
|
|
if (roundRunning)
|
|
{
|
|
return;
|
|
}
|
|
//Prüfen die eingabe
|
|
if (!int.TryParse(TxtBet.Text, out int bet) || bet <= 0)
|
|
{
|
|
MessageBox.Show(
|
|
"Bitte gib einen gültigen Einsatz ein.",
|
|
"Ungültiger Einsatz",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Warning);
|
|
|
|
return;
|
|
}
|
|
|
|
if (bet > CurrentUser.Geld)
|
|
{
|
|
MessageBox.Show(
|
|
"Du hast nicht genug Geld für diesen Einsatz.",
|
|
"Zu wenig Geld",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Warning);
|
|
|
|
return;
|
|
}
|
|
|
|
currentBet = bet;
|
|
StartRound();
|
|
}
|
|
//Colin Langer
|
|
private void StartRound()
|
|
{
|
|
try
|
|
{
|
|
if (currentBet <= 0 || currentBet > CurrentUser.Geld)
|
|
{
|
|
ShowWaitingState();
|
|
return;
|
|
}
|
|
|
|
CurrentUser.Geld -= Convert.ToInt32(currentBet);
|
|
SaveAccount();
|
|
|
|
currentProfit = 0;
|
|
currentPhase = 0;
|
|
roundRunning = true;
|
|
TxtBet.IsEnabled = false;
|
|
|
|
LoadCards();
|
|
UpdateHandUI();
|
|
UpdateWinDisplay();
|
|
SetPhaseUI();
|
|
}
|
|
catch (NullReferenceException)
|
|
{
|
|
MessageBox.Show(
|
|
"Bitte ein Betrag eingeben",
|
|
"Fehlermeldung 101",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Information);
|
|
}
|
|
}
|
|
//Colin Langer
|
|
// lädt und mischt die karten aus der datenbank
|
|
private void LoadCards()
|
|
{
|
|
deck = db.GetAllCards()
|
|
.OrderBy(_ => Random.Shared.Next())
|
|
.ToList();
|
|
|
|
byte[] backBytes = db.GetCardBackImage();
|
|
|
|
if (backBytes != null && backBytes.Length > 0)
|
|
{
|
|
cardBackImage = ByteArrayToImage(backBytes);
|
|
}
|
|
|
|
handCards.Clear();
|
|
|
|
for (int i = 0; i < 4 && deck.Count > 0; i++)
|
|
{
|
|
handCards.Add(DrawCard());
|
|
}
|
|
}
|
|
//Colin Langer
|
|
// nimmt die oberste karte
|
|
private Card DrawCard()
|
|
{
|
|
Card card = deck[0];
|
|
deck.RemoveAt(0);
|
|
return card;
|
|
}
|
|
|
|
//Colin Langer
|
|
private void UpdateHandUI()
|
|
{
|
|
Bild_1.Source = cardBackImage;
|
|
Bild_2.Source = cardBackImage;
|
|
Bild_3.Source = cardBackImage;
|
|
Bild_4.Source = cardBackImage;
|
|
|
|
if (handCards.Count < 4)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (currentPhase >= 1)
|
|
{
|
|
Bild_1.Source = handCards[0].Image;
|
|
}
|
|
|
|
if (currentPhase >= 2)
|
|
{
|
|
Bild_2.Source = handCards[1].Image;
|
|
}
|
|
|
|
if (currentPhase >= 3)
|
|
{
|
|
Bild_3.Source = handCards[2].Image;
|
|
}
|
|
|
|
if (currentPhase >= 4)
|
|
{
|
|
Bild_4.Source = handCards[3].Image;
|
|
}
|
|
}
|
|
//Colin Langer
|
|
// dreht die karten je nach runde um
|
|
private void RevealCurrentCard()
|
|
{
|
|
if (handCards.Count < 4)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (currentPhase)
|
|
{
|
|
case 0:
|
|
Bild_1.Source = handCards[0].Image;
|
|
break;
|
|
|
|
case 1:
|
|
Bild_2.Source = handCards[1].Image;
|
|
break;
|
|
|
|
case 2:
|
|
Bild_3.Source = handCards[2].Image;
|
|
break;
|
|
|
|
case 3:
|
|
Bild_4.Source = handCards[3].Image;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Lenard Gerdes
|
|
private async Task ProcessGuessAsync(bool success)
|
|
{
|
|
if (!roundRunning)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RevealCurrentCard();
|
|
|
|
if (!success)
|
|
{
|
|
roundRunning = false;
|
|
currentProfit = 0;
|
|
UpdateWinDisplay();
|
|
SetPhaseUI();
|
|
|
|
await Task.Delay(100);
|
|
|
|
// Nächste Runde mit demselben Einsatz
|
|
if (currentBet <= CurrentUser.Geld)
|
|
{
|
|
StartRound();
|
|
}
|
|
else
|
|
{
|
|
ShowWaitingState();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
currentPhase++;
|
|
currentProfit = CalculateCurrentProfit();
|
|
|
|
UpdateHandUI();
|
|
UpdateWinDisplay();
|
|
SetPhaseUI();
|
|
|
|
if (currentPhase == 4)
|
|
{
|
|
roundRunning = false;
|
|
|
|
PayoutCurrentProfit();
|
|
|
|
await Task.Delay(100);
|
|
|
|
if (currentBet <= CurrentUser.Geld)
|
|
{
|
|
StartRound();
|
|
}
|
|
else
|
|
{
|
|
ShowWaitingState();
|
|
}
|
|
}
|
|
}
|
|
//Colin Langer
|
|
private decimal CalculateCurrentProfit()
|
|
{
|
|
return currentPhase switch
|
|
{
|
|
1 => currentBet * 1.75m,
|
|
2 => currentBet * 2.5m,
|
|
3 => currentBet * 5.0m,
|
|
4 => currentBet * 20.0m,
|
|
_ => 0
|
|
};
|
|
}
|
|
//Colin Langer
|
|
// passt die buttons an je nach runde
|
|
private async void ColorButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CardColor chosenColor =
|
|
button.Tag?.ToString() == "Red"
|
|
? CardColor.Red
|
|
: CardColor.Black;
|
|
|
|
Card card = handCards[0];
|
|
|
|
bool success =
|
|
chosenColor == CardColor.Red
|
|
? card.IsRed
|
|
: !card.IsRed;
|
|
|
|
await ProcessGuessAsync(success);
|
|
}
|
|
//Colin Langer
|
|
private async void HigherLowerButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool higher = button.Tag?.ToString() == "Higher";
|
|
|
|
Card firstCard = handCards[0];
|
|
Card secondCard = handCards[1];
|
|
|
|
bool success = higher
|
|
? secondCard.NumericValue > firstCard.NumericValue
|
|
: secondCard.NumericValue < firstCard.NumericValue;
|
|
|
|
await ProcessGuessAsync(success);
|
|
}
|
|
//Colin Langer
|
|
private async void InsideOutsideButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is not Button button)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool inside = button.Tag?.ToString() == "Inside";
|
|
|
|
int firstValue = handCards[0].NumericValue;
|
|
int secondValue = handCards[1].NumericValue;
|
|
int thirdValue = handCards[2].NumericValue;
|
|
|
|
int min = Math.Min(firstValue, secondValue);
|
|
int max = Math.Max(firstValue, secondValue);
|
|
|
|
bool isBetween = thirdValue > min && thirdValue < max;
|
|
bool success = inside ? isBetween : !isBetween;
|
|
|
|
await ProcessGuessAsync(success);
|
|
}
|
|
//Colin Langer
|
|
private async void BtnSuit_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is not Button button || button.Tag == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string chosenSuit = button.Tag.ToString()!;
|
|
Card card = handCards[3];
|
|
|
|
bool success = IsSameSuit(card.FarbeRaw, chosenSuit);
|
|
|
|
await ProcessGuessAsync(success);
|
|
}
|
|
//Colin Langer
|
|
private static bool IsSameSuit(string cardSuit, string chosenSuit)
|
|
{
|
|
if (cardSuit.Equals(chosenSuit, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return chosenSuit switch
|
|
{
|
|
"Hearts" => cardSuit.Equals("Hearts", StringComparison.OrdinalIgnoreCase),
|
|
"Diamonds" => cardSuit.Equals("Diamond", StringComparison.OrdinalIgnoreCase),
|
|
"Spades" => cardSuit.Equals("Spades", StringComparison.OrdinalIgnoreCase),
|
|
"Clubs" => cardSuit.Equals("Clubs", StringComparison.OrdinalIgnoreCase),
|
|
_ => false
|
|
};
|
|
}
|
|
//Colin Langer
|
|
private enum CardColor
|
|
{
|
|
Red,
|
|
Black
|
|
}
|
|
//Colin Langer
|
|
private void BtnCashOut_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (!roundRunning || currentProfit <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
roundRunning = false;
|
|
|
|
decimal payout = currentProfit;
|
|
PayoutCurrentProfit();
|
|
|
|
MessageBox.Show(
|
|
$"Du hast ${payout:F2} ausgezahlt bekommen!",
|
|
"Cash Out",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Information);
|
|
|
|
ShowWaitingState();
|
|
}
|
|
//Colin Langer
|
|
private void PayoutCurrentProfit()
|
|
{
|
|
if (currentProfit <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CurrentUser.Geld += Convert.ToInt32(currentProfit);
|
|
SaveAccount();
|
|
}
|
|
|
|
//Colin Langer
|
|
// blendet die buttons der jewaligen runde ein
|
|
private void SetPhaseUI()
|
|
{
|
|
PanelRedBlack.Visibility = Visibility.Collapsed;
|
|
PanelHigherLower.Visibility = Visibility.Collapsed;
|
|
PanelInsideOutside.Visibility = Visibility.Collapsed;
|
|
PanelSuit.Visibility = Visibility.Collapsed;
|
|
|
|
BtnCashOut.Visibility = Visibility.Collapsed;
|
|
BtnStart.Visibility = Visibility.Collapsed;
|
|
|
|
if (!roundRunning)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (currentPhase)
|
|
{
|
|
case 0:
|
|
PanelRedBlack.Visibility = Visibility.Visible;
|
|
break;
|
|
|
|
case 1:
|
|
PanelHigherLower.Visibility = Visibility.Visible;
|
|
BtnCashOut.Visibility = Visibility.Visible;
|
|
break;
|
|
|
|
case 2:
|
|
PanelInsideOutside.Visibility = Visibility.Visible;
|
|
BtnCashOut.Visibility = Visibility.Visible;
|
|
break;
|
|
|
|
case 3:
|
|
PanelSuit.Visibility = Visibility.Visible;
|
|
BtnCashOut.Visibility = Visibility.Visible;
|
|
break;
|
|
}
|
|
}
|
|
//Colin Langer
|
|
// wartet kurz falls ein neuer einsatz eingegeben wird
|
|
private void ShowWaitingState()
|
|
{
|
|
roundRunning = false;
|
|
currentPhase = 0;
|
|
currentProfit = 0;
|
|
|
|
UpdateWinDisplay();
|
|
SetPhaseUI();
|
|
|
|
BtnStart.Visibility = Visibility.Visible;
|
|
TxtBet.IsEnabled = true;
|
|
}
|
|
//Colin Langer
|
|
private void UpdateWinDisplay()
|
|
{
|
|
BtnCashOut.Content = $"Cash Out (${currentProfit:F2})";
|
|
}
|
|
//Colin Langer
|
|
private void Hauptmenue(object sender, RoutedEventArgs e)
|
|
{
|
|
music.Stop();
|
|
Close();
|
|
}
|
|
//Colin Langer
|
|
// verwandelt das bild aus der datenbank um in eine bild für die oberfläche
|
|
private static BitmapImage ByteArrayToImage(byte[] bytes)
|
|
{
|
|
BitmapImage image = new BitmapImage();
|
|
|
|
using (MemoryStream ms = new MemoryStream(bytes))
|
|
{
|
|
image.BeginInit();
|
|
image.CacheOption = BitmapCacheOption.OnLoad;
|
|
image.StreamSource = ms;
|
|
image.EndInit();
|
|
}
|
|
|
|
image.Freeze();
|
|
return image;
|
|
}
|
|
|
|
// =========================
|
|
// EINSATZFELD Colin Langer
|
|
// =========================
|
|
// In Slots ist die erklärung drin
|
|
|
|
private static readonly Regex NumberRegex = new Regex("^[0-9]+$");
|
|
|
|
private void TxtBet_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
|
{
|
|
e.Handled = !NumberRegex.IsMatch(e.Text);
|
|
}
|
|
|
|
private void TxtBet_PreviewKeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.Key == Key.Space)
|
|
{
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
|
|
private void TxtBet_Pasting(object sender, DataObjectPastingEventArgs e)
|
|
{
|
|
if (!e.DataObject.GetDataPresent(typeof(string)))
|
|
{
|
|
e.CancelCommand();
|
|
return;
|
|
}
|
|
|
|
string text = (string)e.DataObject.GetData(typeof(string));
|
|
|
|
if (!NumberRegex.IsMatch(text))
|
|
{
|
|
e.CancelCommand();
|
|
}
|
|
}
|
|
}
|
|
} |