Files
WIR-MACHEN-ALLE-ARM/Casino/Busfahrer.xaml.cs
T
2026-09-14 14:57:19 +02:00

630 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
{
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 static int ParseValue(string wert)
{
return wert.Trim() switch
{
"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();
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];
// =========================
// KONTO
// =========================
private void UpdateAccountDisplay()
{
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)
{
StartGameFromInput();
}
private void StartGameFromInput()
{
if (roundRunning)
{
return;
}
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();
}
private void StartRound()
{
try
{
if (currentBet <= 0 || currentBet > CurrentUser.Geld)
{
ShowWaitingState();
return;
}
// Einsatz vom Konto abziehen
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);
}
}
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());
}
}
private Card DrawCard()
{
Card card = deck[0];
deck.RemoveAt(0);
return card;
}
// =========================
// KARTEN ANZEIGEN
// =========================
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;
}
}
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;
}
}
// =========================
// SPIELLOGIK
// =========================
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();
// Vierte Frage richtig -> automatisch auszahlen
if (currentPhase == 4)
{
roundRunning = false;
PayoutCurrentProfit();
await Task.Delay(1000);
// Neue Runde automatisch starten
if (currentBet <= CurrentUser.Geld)
{
StartRound();
}
else
{
ShowWaitingState();
}
}
}
private decimal CalculateCurrentProfit()
{
return currentPhase switch
{
1 => currentBet * 1.75m,
2 => currentBet * 2.5m,
3 => currentBet * 5.0m,
4 => currentBet * 20.0m,
_ => 0
};
}
// =========================
// 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 (!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();
}
private void PayoutCurrentProfit()
{
if (currentProfit <= 0)
{
return;
}
CurrentUser.Geld += Convert.ToInt32(currentProfit);
SaveAccount();
}
// =========================
// UI
// =========================
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;
}
}
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)
{
music.Stop();
Close();
}
// =========================
// BILD AUS BYTE[]
// =========================
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;
}
// =========================
// EINSATZ VALIDIERUNG
// =========================
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();
}
}
}
}