using System; using System.Collections.Generic; using System.Collections.ObjectModel; 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("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) { 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; private decimal currentBet = 0; private decimal currentProfit = 0; private Database db = new Database(); private ObservableCollection users; public Busfahrer() { InitializeComponent(); users = db.GetUser(); UpdateAccountDisplay(); StartNewGame(); } private void UpdateAccountDisplay() { users = db.GetUser(); Konto.Text = users[MainWindow.currentUser].Geld.ToString(); } private void BtnStart_Click(object sender, RoutedEventArgs e) { StartNewGame(); } private void StartNewGame() { decimal currentgeld = users[MainWindow.currentUser].Geld; // 1. Einsatz sofort auf dem Konto abziehen & in der Datenbank speichern currentgeld -= Convert.ToInt32(currentBet); db.UpdateGeld(users[MainWindow.currentUser].ID, currentgeld); UpdateAccountDisplay(); currentProfit = 0; UpdateWinDisplay(); 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(); currentProfit = 0; UpdateWinDisplay(); SetPhaseUI(); 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; } UpdateWinDisplay(); UpdateHandUI(); SetPhaseUI(); // Automatische Auszahlung bei Gewinn von Runde 4 if (currentPhase == 4) { var currentUser = users[MainWindow.currentUser]; currentUser.Geld += Convert.ToInt32(currentProfit); db.UpdateGeld(currentUser.ID, currentUser.Geld); UpdateAccountDisplay(); } } private void UpdateWinDisplay() { BtnCashOut.Content = $"Cash Out (${currentProfit:F2})"; } // CASH OUT BUTTON private void BtnCashOut_Click(object sender, RoutedEventArgs e) { if (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(); } } // 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) { Card targetCard = handCards[0]; bool ok = (chosenColor == CardColor.Red && targetCard.IsRed) || (chosenColor == CardColor.Black && !targetCard.IsRed); ProcessGuess(ok); } 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) { 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); } } private void SetPhaseUI() { PanelRedBlack.Visibility = Visibility.Collapsed; PanelHigherLower.Visibility = Visibility.Collapsed; PanelInsideOutside.Visibility = Visibility.Collapsed; if (PanelSuit != null) PanelSuit.Visibility = Visibility.Collapsed; BtnCashOut.Visibility = (currentPhase > 0 && currentPhase < 4 && currentProfit > 0) ? 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; } } 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 VALIDATION // ======================= private static readonly Regex _regex = new Regex("^[0-9]"); private void TxtBet_PreviewTextInput(object sender, TextCompositionEventArgs e) { e.Handled = !_regex.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))) { var text = (String)e.DataObject.GetData(typeof(String)); if (!_regex.IsMatch((string)text)) { e.CancelCommand(); } } } } }