200 lines
6.0 KiB
C#
200 lines
6.0 KiB
C#
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<Player> 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<CardDTO>(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<Card> 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<Card> 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;
|
|
}
|
|
} |