using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; 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 { 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); 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); } } private 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 }; } 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; } } public enum CardColor { Red, Black } private List deck = new(); private List handCards = new(); private ImageSource cardBackImage = null!; private int currentPhase = 0; // 0: Red/Black, 1: Higher/Lower, 2: In Between/Outside, 3: Suit, 4: Won private double currentBet = 0; private double currentProfit = 0; public Busfahrer() { InitializeComponent(); StartNewGame(); } private void BtnStart_Click(object sender, RoutedEventArgs e) { StartNewGame(); } private void StartNewGame() { UpdateWinDisplay(); Database db = new Database(); deck = db.GetAllCards(); byte[] backBytes = db.GetCardBackImage(); if (backBytes != null) { cardBackImage = ByteArrayToImage(backBytes); } Random ran = new Random(); deck = deck.OrderBy(_ => ran.Next()).ToList(); handCards.Clear(); currentPhase = 0; for (int i = 0; i < 4; i++) { if (deck.Count > 0) { handCards.Add(DrawCard()); } } UpdateHandUI(); SetPhaseUI(); } private Card DrawCard() { var card = deck[0]; deck.RemoveAt(0); return card; } 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; } private void RevealCurrentCard() { 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; } } private void ProcessGuess(bool success) { if (!success) { RevealCurrentCard(); MessageBox.Show("Wrong guess! You lost your bet. Game will restart.", "Bus Driver", MessageBoxButton.OK, MessageBoxImage.Information); StartNewGame(); return; } // Gewinn-Multiplikatoren currentPhase++; switch (currentPhase) { case 1: currentProfit = currentBet * 1.75; break; // Runde 1 bestanden case 2: currentProfit = currentBet * 2.5; break; // Runde 2 bestanden case 3: currentProfit = currentBet * 5.0; break; // Runde 3 bestanden case 4: currentProfit = currentBet * 20.0; break; // Runde 4 bestanden } UpdateWinDisplay(); UpdateHandUI(); SetPhaseUI(); } private void UpdateWinDisplay() { BtnCashOut.Content = $"Cash Out (${currentProfit:F2})"; } // --- CASH OUT BUTTON EVENT --- private void BtnCashOut_Click(object sender, RoutedEventArgs e) { if (currentProfit > 0) { StartNewGame(); } } // --- BUTTON EVENTS --- // ROUND 1: Red / Black 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) { Card targetCard = handCards[0]; bool ok = (chosenColor == CardColor.Red && targetCard.IsRed) || (chosenColor == CardColor.Black && !targetCard.IsRed); ProcessGuess(ok); } // ROUND 2: Higher / Lower 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); } // ROUND 3: In Between / Outside 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); } // ROUND 4: Suit private void BtnSuit_Click(object sender, RoutedEventArgs e) { if (sender is Button btn && btn.Tag != null) { 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("Hearts", StringComparison.OrdinalIgnoreCase)) || (chosenSuit.Equals("Diamond", StringComparison.OrdinalIgnoreCase) && (card4.FarbeRaw.Equals("Diamond", StringComparison.OrdinalIgnoreCase))) || (chosenSuit.Equals("Spades", StringComparison.OrdinalIgnoreCase) && card4.FarbeRaw.Equals("Spades", StringComparison.OrdinalIgnoreCase)) || (chosenSuit.Equals("Clubs", StringComparison.OrdinalIgnoreCase) && card4.FarbeRaw.Equals("Clubs", StringComparison.OrdinalIgnoreCase)); ProcessGuess(ok); } } // --- BUTTON VISIBILITY CONTROL --- private void SetPhaseUI() { PanelRedBlack.Visibility = Visibility.Collapsed; PanelHigherLower.Visibility = Visibility.Collapsed; PanelInsideOutside.Visibility = Visibility.Collapsed; if (PanelSuit != null) PanelSuit.Visibility = Visibility.Collapsed; BtnNextPyramid.Visibility = Visibility.Collapsed; // Zeige den Auszahlungs-Button ab Runde 1 (nach dem ersten Gewinn) an BtnCashOut.Visibility = (currentPhase > 1 && currentPhase < 4) ? Visibility.Visible : Visibility.Collapsed; switch (currentPhase) { case 0: PanelRedBlack.Visibility = Visibility.Visible; break; case 1: PanelHigherLower.Visibility = Visibility.Visible; break; case 2: PanelInsideOutside.Visibility = Visibility.Visible; break; case 3: if (PanelSuit != null) PanelSuit.Visibility = Visibility.Visible; break; case 4: BtnNextPyramid.Visibility = Visibility.Visible; break; } } private void Hauptmenue(object sender, RoutedEventArgs e) { Close(); } 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(); image.CacheOption = BitmapCacheOption.OnLoad; image.StreamSource = ms; image.EndInit(); } image.Freeze(); return image; } // ============= // NUMBER FIELD // ============= private static readonly Regex _regex = new Regex("^[0-9]"); private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { e.Handled = !_regex.IsMatch(e.Text); } private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Space) { e.Handled = true; } } private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(String))) { var text = (String)e.DataObject.GetData(typeof(String)); if (!_regex.IsMatch((string)text)) { e.CancelCommand(); } } } } }