diff --git a/Casino/Busfahrer.xaml b/Casino/Busfahrer.xaml
index 9633e83..70d10c5 100644
--- a/Casino/Busfahrer.xaml
+++ b/Casino/Busfahrer.xaml
@@ -5,10 +5,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Casino"
mc:Ignorable="d"
- Title="Bus Driver" Height="1080" Width="1960"
+ Title="Bus Driver"
+ Height="1080"
+ Width="1960"
WindowState="Maximized"
WindowStyle="None"
Background="#2C3E50">
+
@@ -25,67 +28,267 @@
+
-
-
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
\ No newline at end of file
+
diff --git a/Casino/Busfahrer.xaml.cs b/Casino/Busfahrer.xaml.cs
index 55f4b4b..4399f75 100644
--- a/Casino/Busfahrer.xaml.cs
+++ b/Casino/Busfahrer.xaml.cs
@@ -4,6 +4,7 @@ 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;
@@ -22,11 +23,12 @@ namespace Casino
public ImageSource Image { get; set; } = null!;
public int NumericValue { get; set; }
- public bool IsRed => FarbeRaw.Equals("Hearts", StringComparison.OrdinalIgnoreCase) ||
- FarbeRaw.Equals("Diamonds", StringComparison.OrdinalIgnoreCase) ||
- FarbeRaw.Equals("Diamond", StringComparison.OrdinalIgnoreCase) ||
- FarbeRaw.Equals("Herz", StringComparison.OrdinalIgnoreCase) ||
- FarbeRaw.Equals("Karo", StringComparison.OrdinalIgnoreCase);
+ public bool IsRed =>
+ FarbeRaw.Equals("Hearts", StringComparison.OrdinalIgnoreCase) ||
+ FarbeRaw.Equals("Diamonds", StringComparison.OrdinalIgnoreCase) ||
+ FarbeRaw.Equals("Diamond", StringComparison.OrdinalIgnoreCase) ||
+ FarbeRaw.Equals("Herz", StringComparison.OrdinalIgnoreCase) ||
+ FarbeRaw.Equals("Karo", StringComparison.OrdinalIgnoreCase);
public Card(int id, string wert, string farbe, byte[] imgBytes)
{
@@ -34,31 +36,29 @@ namespace Casino
WertRaw = wert;
FarbeRaw = farbe;
NumericValue = ParseValue(wert);
+
if (imgBytes != null && imgBytes.Length > 0)
{
Image = ByteArrayToImage(imgBytes);
}
}
- private int ParseValue(string wert)
+ private static int ParseValue(string wert)
{
return wert.Trim() switch
{
- "Jack" => 11,
- "Bube" => 11,
- "Queen" => 12,
- "Dame" => 12,
- "King" => 13,
- "König" => 13,
- "Ace" => 14,
- "Ass" => 14,
- _ => int.TryParse(wert, out int v) ? v : 0
+ "Jack" or "Bube" => 11,
+ "Queen" or "Dame" => 12,
+ "King" or "König" => 13,
+ "Ace" or "Ass" => 14,
+ _ => int.TryParse(wert, out int value) ? value : 0
};
}
private static BitmapImage ByteArrayToImage(byte[] bytes)
{
BitmapImage image = new BitmapImage();
+
using (MemoryStream ms = new MemoryStream(bytes))
{
image.BeginInit();
@@ -66,229 +66,431 @@ namespace Casino
image.StreamSource = ms;
image.EndInit();
}
+
image.Freeze();
return image;
}
}
- public enum CardColor { Red, Black }
+ private readonly Database db = new Database();
+ private ObservableCollection users;
- private List deck = new();
- private List handCards = new();
+ private List deck = new List();
+ private List handCards = new List();
private ImageSource cardBackImage = null!;
private int currentPhase = 0;
private decimal currentBet = 0;
private decimal currentProfit = 0;
+ private bool roundRunning = false;
- private Database db = new Database();
- private ObservableCollection users;
+ private static readonly Regex NumberRegex = new Regex("^[0-9]+$");
public Busfahrer()
{
InitializeComponent();
- users = db.GetUser();
+ users = db.GetUser();
UpdateAccountDisplay();
-
- StartNewGame();
+
+ ShowWaitingState();
}
+ private User CurrentUser => users[MainWindow.currentUser];
+
+ // =========================
+ // KONTO
+ // =========================
+
private void UpdateAccountDisplay()
{
- users = db.GetUser();
- Konto.Text = users[MainWindow.currentUser].Geld.ToString();
+ Konto.Text = CurrentUser.Geld.ToString();
}
+ private void SaveAccount()
+ {
+ db.UpdateGeld(CurrentUser.ID, CurrentUser.Geld);
+ UpdateAccountDisplay();
+ }
+
+ // =========================
+ // SPIEL STARTEN
+ // =========================
+
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
- StartNewGame();
+ StartGameFromInput();
}
- private void StartNewGame()
+ private void StartGameFromInput()
{
+ if (roundRunning)
+ {
+ return;
+ }
- decimal currentgeld = users[MainWindow.currentUser].Geld;
+ 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;
+ }
- // 1. Einsatz sofort auf dem Konto abziehen & in der Datenbank speichern
- db.UpdateGeld(users[MainWindow.currentUser].ID, currentgeld);
- UpdateAccountDisplay();
+ 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();
+ }
+
+ private void StartRound()
+ {
+ if (currentBet <= 0 || currentBet > CurrentUser.Geld)
+ {
+ ShowWaitingState();
+ return;
+ }
+
+ // Einsatz vom Konto abziehen
+ CurrentUser.Geld -= Convert.ToInt32(currentBet);
+ SaveAccount();
currentProfit = 0;
- UpdateWinDisplay();
+ currentPhase = 0;
+ roundRunning = true;
+ TxtBet.IsEnabled = false;
+
+ LoadCards();
+ UpdateHandUI();
+ UpdateWinDisplay();
+ SetPhaseUI();
+ }
+
+ private void LoadCards()
+ {
+ deck = db.GetAllCards()
+ .OrderBy(_ => Random.Shared.Next())
+ .ToList();
- deck = db.GetAllCards();
byte[] backBytes = db.GetCardBackImage();
- if (backBytes != null)
+ if (backBytes != null && backBytes.Length > 0)
{
cardBackImage = ByteArrayToImage(backBytes);
}
- Random ran = new Random();
- deck = deck.OrderBy(_ => ran.Next()).ToList();
-
handCards.Clear();
- currentPhase = 0;
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4 && deck.Count > 0; i++)
{
- if (deck.Count > 0)
- {
- handCards.Add(DrawCard());
- }
+ handCards.Add(DrawCard());
}
-
- UpdateHandUI();
- SetPhaseUI();
}
private Card DrawCard()
{
- var card = deck[0];
+ Card card = deck[0];
deck.RemoveAt(0);
return card;
}
+ // =========================
+ // KARTEN ANZEIGEN
+ // =========================
+
private void UpdateHandUI()
{
- Bild_1.Source = (currentPhase > 0) ? handCards[0].Image : cardBackImage;
- Bild_2.Source = (currentPhase > 1) ? handCards[1].Image : cardBackImage;
- Bild_3.Source = (currentPhase > 2) ? handCards[2].Image : cardBackImage;
- Bild_4.Source = (currentPhase > 3) ? handCards[3].Image : cardBackImage;
+ 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;
+ }
}
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;
+ 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;
}
}
- private void ProcessGuess(bool success)
+ // =========================
+ // SPIELLOGIK
+ // =========================
+
+ private async Task ProcessGuessAsync(bool success)
{
+ if (!roundRunning)
+ {
+ return;
+ }
+
+ RevealCurrentCard();
+
if (!success)
{
- RevealCurrentCard();
+ roundRunning = false;
currentProfit = 0;
UpdateWinDisplay();
SetPhaseUI();
- StartNewGame();
+
+ await Task.Delay(1000);
+
+ // Nächste Runde mit demselben Einsatz
+ if (currentBet <= CurrentUser.Geld)
+ {
+ StartRound();
+ }
+ else
+ {
+ ShowWaitingState();
+ }
+
return;
}
currentPhase++;
- switch (currentPhase)
- {
- case 1: currentProfit = currentBet * 1.75m; break;
- case 2: currentProfit = currentBet * 2.5m; break;
- case 3: currentProfit = currentBet * 5.0m; break;
- case 4: currentProfit = currentBet * 20.0m; break;
- }
+ currentProfit = CalculateCurrentProfit();
- UpdateWinDisplay();
UpdateHandUI();
+ UpdateWinDisplay();
SetPhaseUI();
- // Automatische Auszahlung bei Gewinn von Runde 4
+ // Vierte Frage richtig -> automatisch auszahlen
if (currentPhase == 4)
{
- var currentUser = users[MainWindow.currentUser];
- currentUser.Geld += Convert.ToInt32(currentProfit);
- db.UpdateGeld(currentUser.ID, currentUser.Geld);
- UpdateAccountDisplay();
+ roundRunning = false;
+ PayoutCurrentProfit();
+
+ await Task.Delay(1000);
+
+ // Neue Runde automatisch starten
+ if (currentBet <= CurrentUser.Geld)
+ {
+ StartRound();
+ }
+ else
+ {
+ ShowWaitingState();
+ }
}
}
- private void UpdateWinDisplay()
+ private decimal CalculateCurrentProfit()
{
- BtnCashOut.Content = $"Cash Out (${currentProfit:F2})";
+ return currentPhase switch
+ {
+ 1 => currentBet * 1.75m,
+ 2 => currentBet * 2.5m,
+ 3 => currentBet * 5.0m,
+ 4 => currentBet * 20.0m,
+ _ => 0
+ };
}
- // CASH OUT BUTTON
+ // =========================
+ // FRAGEN
+ // =========================
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ private static bool IsSameSuit(string cardSuit, string chosenSuit)
+ {
+ if (cardSuit.Equals(chosenSuit, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ return chosenSuit switch
+ {
+ "Hearts" => cardSuit.Equals("Herz", StringComparison.OrdinalIgnoreCase),
+ "Diamonds" => cardSuit.Equals("Karo", StringComparison.OrdinalIgnoreCase) ||
+ cardSuit.Equals("Diamond", StringComparison.OrdinalIgnoreCase),
+ "Spades" => cardSuit.Equals("Pik", StringComparison.OrdinalIgnoreCase),
+ "Clubs" => cardSuit.Equals("Kreuz", StringComparison.OrdinalIgnoreCase),
+ _ => false
+ };
+ }
+
+ private enum CardColor
+ {
+ Red,
+ Black
+ }
+
+ // =========================
+ // CASH OUT
+ // =========================
+
private void BtnCashOut_Click(object sender, RoutedEventArgs e)
{
- if (currentProfit > 0)
+ if (!roundRunning || currentProfit <= 0)
{
- var currentUser = users[MainWindow.currentUser];
- currentUser.Geld += Convert.ToInt32(currentProfit);
- db.UpdateGeld(currentUser.ID, currentUser.Geld);
- UpdateAccountDisplay();
-
- MessageBox.Show($"Du hast dir ${currentProfit:F2} auszahlen lassen!", "Cash Out", MessageBoxButton.OK, MessageBoxImage.Information);
-
- currentProfit = 0;
- UpdateWinDisplay();
- SetPhaseUI();
+ return;
}
+
+ roundRunning = false;
+
+ decimal payout = currentProfit;
+ PayoutCurrentProfit();
+
+ MessageBox.Show(
+ $"Du hast ${payout:F2} ausgezahlt bekommen!",
+ "Cash Out",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+
+ ShowWaitingState();
}
- // RUNDEN BUTTONS
- private void BtnRed_Click(object sender, RoutedEventArgs e) => GuessColor(CardColor.Red);
- private void BtnBlack_Click(object sender, RoutedEventArgs e) => GuessColor(CardColor.Black);
-
- private void GuessColor(CardColor chosenColor)
+ private void PayoutCurrentProfit()
{
- Card targetCard = handCards[0];
- bool ok = (chosenColor == CardColor.Red && targetCard.IsRed) ||
- (chosenColor == CardColor.Black && !targetCard.IsRed);
- ProcessGuess(ok);
- var currentUser = users[MainWindow.currentUser];
- currentBet -= Convert.ToInt32(TxtBet.Text);
- db.UpdateGeld(currentUser.ID, currentUser.Geld);
- UpdateAccountDisplay();
-
- }
-
- private void BtnHigher_Click(object sender, RoutedEventArgs e) => GuessHigherLower(true);
- private void BtnLower_Click(object sender, RoutedEventArgs e) => GuessHigherLower(false);
-
- private void GuessHigherLower(bool higher)
- {
- Card card1 = handCards[0];
- Card card2 = handCards[1];
-
- bool ok = higher ? card2.NumericValue > card1.NumericValue : card2.NumericValue < card1.NumericValue;
- ProcessGuess(ok);
- }
-
- private void BtnInside_Click(object sender, RoutedEventArgs e) => GuessInside(true);
- private void BtnOutside_Click(object sender, RoutedEventArgs e) => GuessInside(false);
-
- private void GuessInside(bool inside)
- {
- Card card3 = handCards[2];
- int min = Math.Min(handCards[0].NumericValue, handCards[1].NumericValue);
- int max = Math.Max(handCards[0].NumericValue, handCards[1].NumericValue);
-
- bool isBetween = card3.NumericValue > min && card3.NumericValue < max;
- bool ok = inside ? isBetween : !isBetween;
- ProcessGuess(ok);
- }
-
- private void BtnSuit_Click(object sender, RoutedEventArgs e)
- {
- if (sender is Button btn && btn.Tag != null)
+ if (currentProfit <= 0)
{
- string chosenSuit = btn.Tag.ToString()!;
- Card card4 = handCards[3];
-
- bool ok = card4.FarbeRaw.Equals(chosenSuit, StringComparison.OrdinalIgnoreCase) ||
- (chosenSuit.Equals("Hearts", StringComparison.OrdinalIgnoreCase) && card4.FarbeRaw.Equals("Herz", StringComparison.OrdinalIgnoreCase)) ||
- (chosenSuit.Equals("Diamonds", StringComparison.OrdinalIgnoreCase) && (card4.FarbeRaw.Equals("Karo", StringComparison.OrdinalIgnoreCase) || card4.FarbeRaw.Equals("Diamond", StringComparison.OrdinalIgnoreCase))) ||
- (chosenSuit.Equals("Spades", StringComparison.OrdinalIgnoreCase) && card4.FarbeRaw.Equals("Pik", StringComparison.OrdinalIgnoreCase)) ||
- (chosenSuit.Equals("Clubs", StringComparison.OrdinalIgnoreCase) && card4.FarbeRaw.Equals("Kreuz", StringComparison.OrdinalIgnoreCase));
-
- ProcessGuess(ok);
+ return;
}
+
+ CurrentUser.Geld += Convert.ToInt32(currentProfit);
+ SaveAccount();
}
+ // =========================
+ // UI
+ // =========================
+
private void SetPhaseUI()
{
PanelRedBlack.Visibility = Visibility.Collapsed;
@@ -296,27 +498,72 @@ namespace Casino
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; break;
- case 3: PanelSuit.Visibility = Visibility.Visible; break;
+ 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;
}
}
+ private void ShowWaitingState()
+ {
+ roundRunning = false;
+ currentPhase = 0;
+ currentProfit = 0;
+
+ UpdateWinDisplay();
+ SetPhaseUI();
+
+ BtnStart.Visibility = Visibility.Visible;
+ TxtBet.IsEnabled = true;
+ }
+
+ private void UpdateWinDisplay()
+ {
+ BtnCashOut.Content = $"Cash Out (${currentProfit:F2})";
+ }
+
+ // =========================
+ // HAUPTMENÜ
+ // =========================
+
private void Hauptmenue(object sender, RoutedEventArgs e)
{
Close();
}
+ // =========================
+ // BILD AUS BYTE[]
+ // =========================
+
private static BitmapImage ByteArrayToImage(byte[] bytes)
{
- if (bytes == null || bytes.Length == 0) return null!;
-
BitmapImage image = new BitmapImage();
+
using (MemoryStream ms = new MemoryStream(bytes))
{
image.BeginInit();
@@ -324,18 +571,18 @@ namespace Casino
image.StreamSource = ms;
image.EndInit();
}
+
image.Freeze();
return image;
}
- // =======================
- // NUMBER FIELD VALIDATION
- // =======================
- private static readonly Regex _regex = new Regex("^[0-9]");
+ // =========================
+ // EINSATZ VALIDIERUNG
+ // =========================
private void TxtBet_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
- e.Handled = !_regex.IsMatch(e.Text);
+ e.Handled = !NumberRegex.IsMatch(e.Text);
}
private void TxtBet_PreviewKeyDown(object sender, KeyEventArgs e)
@@ -344,20 +591,22 @@ namespace Casino
{
e.Handled = true;
}
-
}
private void TxtBet_Pasting(object sender, DataObjectPastingEventArgs e)
{
- if (e.DataObject.GetDataPresent(typeof(String)))
+ if (!e.DataObject.GetDataPresent(typeof(string)))
{
- var text = (String)e.DataObject.GetData(typeof(String));
- if (!_regex.IsMatch((string)text))
- {
- e.CancelCommand();
- }
+ e.CancelCommand();
+ return;
+ }
+
+ string text = (string)e.DataObject.GetData(typeof(string));
+
+ if (!NumberRegex.IsMatch(text))
+ {
+ e.CancelCommand();
}
}
-
}
-}
\ No newline at end of file
+}