using System.Text.Json; using MauMau_Server.Websockets; namespace MauMau_Server.Mau; public class Game { public readonly Deck Deck = new(); public Card CurrentCard; public List Players = new(); public Player CurrentPlayer; public int TurnDirection = 1; public Game() { CurrentCard = Deck.DrawCard(); Deck.AddCardToUsedDeck(CurrentCard); } public void AddPlayerToGame(ConnectionInstance connection) { var player = new Player(connection) { Hand = Deck.DrawCards(8) }; Players.Add(player); if (Players.Count > 1) return; CurrentPlayer = player; CurrentPlayer.State = PlayerState.TURN; } public void RemovePlayer(string playerId) { var player = GetPlayer(playerId); Players.Remove(player); } public void HandleAction(string playerId, ActionDTO action) { var player = GetPlayer(playerId); if (CurrentPlayer != player) return; switch (action.Action) { case "PLAYCARD": { if (player.State != PlayerState.TURN) { break; } var card = JsonSerializer.Deserialize(action.Data).ToCard(); PlayCard(player, card); break; } case "CHOOSE": var choice = action.Data; if (!Enum.TryParse(choice, out CardType cardType)) { break; } CurrentCard = new Card(cardType, CardValue.JACK); CurrentPlayer.State = PlayerState.WAIT; CurrentPlayer = CurrentCard.CardType == CardType.JOKER ? GetNextPlayer() : GetNextPlayer(2); CurrentPlayer.State = PlayerState.TURN; break; case "DRAW": if (player.State != PlayerState.TURN) { break; } DrawCard(player); break; } } private void PlayCard(Player player, Card card) { var hand = player.Hand; if (!IsCardInHand(hand, card) || !IsCardPlayable(CurrentCard, card)) return; Deck.AddCardToUsedDeck(card); hand.Remove(GetSameCardFromHand(hand, card)); CurrentCard = card; HandleNextPlayer(card); } private void HandleNextPlayer(Card card) { switch (card.CardValue) { case CardValue.RED: case CardValue.BLACK: { var nextPlayer = GetNextPlayer(); var cardsToDraw = Deck.DrawCards(5); foreach (var drawnCard in cardsToDraw) { nextPlayer.Hand.Add(drawnCard); } CurrentPlayer.State = PlayerState.CHOOSE; break; } case CardValue.TWO: { var nextPlayer = GetNextPlayer(); var cardsToDraw = Deck.DrawCards(2); foreach (var drawnCard in cardsToDraw) { nextPlayer.Hand.Add(drawnCard); } CurrentPlayer.State = PlayerState.WAIT; CurrentPlayer = GetNextPlayer(2); CurrentPlayer.State = PlayerState.TURN; break; } case CardValue.SEVEN: case CardValue.KING: break; case CardValue.EIGHT: CurrentPlayer.State = PlayerState.WAIT; CurrentPlayer = GetNextPlayer(2); CurrentPlayer.State = PlayerState.TURN; break; case CardValue.ACE: if (Players.Count > 2) { TurnDirection *= -1; CurrentPlayer = GetNextPlayer(); } break; case CardValue.JACK: CurrentPlayer.State = PlayerState.CHOOSE; break; case CardValue.THREE: case CardValue.FOUR: case CardValue.FIVE: case CardValue.SIX: case CardValue.NINE: case CardValue.TEN: case CardValue.QUEEN: default: CurrentPlayer = GetNextPlayer(); break; } } private void DrawCard(Player player) { player.Hand.Add(Deck.DrawCard()); CurrentPlayer = GetNextPlayer(); player.State = PlayerState.WAIT; CurrentPlayer.State = PlayerState.TURN; } private Player GetNextPlayer(int numberOfPlayers = 1) { var index = Players.IndexOf(CurrentPlayer); for (var i = 0; i < numberOfPlayers; i++) { index += TurnDirection; if (index >= Players.Count) index = 0; if (index < 0) index = Players.Count - 1; } return Players[index]; } public Player GetPlayer(string playerId) { return Players.FirstOrDefault(p => p.IsMe(playerId)); } private static Card GetSameCardFromHand(IEnumerable hand, Card card) { return hand.FirstOrDefault(handCard => IsSameCard(handCard, card)); } private static bool IsCardPlayable(Card currentCard, Card playedCard) { return IsSameCardType(currentCard, playedCard) || IsSameCardValue(currentCard, playedCard) || playedCard.CardType == CardType.JOKER; } private static bool IsCardInHand(IEnumerable hand, Card card) { return hand.Any(handCard => IsSameCard(handCard, card)); } private static bool IsSameCard(Card card1, Card card2) { return IsSameCardType(card1, card2) && IsSameCardValue(card1, card2); } private static bool IsSameCardType(Card card1, Card card2) { return card1.CardType == card2.CardType; } private static bool IsSameCardValue(Card card1, Card card2) { return card1.CardValue == card2.CardValue; } }