Files
MauMau-Server/Mau/Game.cs
DTieman 0c2cb8272d
All checks were successful
Build Mau & Deploy Mau / build (push) Successful in 1m25s
Build Mau & Deploy Mau / deploy (push) Has been skipped
Build Mau & Deploy Mau / build (pull_request) Successful in 1m6s
Build Mau & Deploy Mau / deploy (pull_request) Has been skipped
Better lobby system
2024-04-22 21:51:35 +02:00

208 lines
6.1 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;
private readonly Room _room;
public Game(Room room)
{
_room = room;
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;
}
CurrentPlayer.State = PlayerState.WAIT;
CurrentPlayer = CurrentCard.CardType == CardType.JOKER ? GetNextPlayer(2) : GetNextPlayer();
CurrentPlayer.State = PlayerState.TURN;
CurrentCard = new Card(cardType, CardValue.JACK);
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;
if (hand.Count == 0)
{
_room.EndGame(player);
return;
}
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);
}
HandleNextPlayer(CurrentPlayer, GetNextPlayer(2));
break;
}
case CardValue.SEVEN:
case CardValue.KING:
break;
case CardValue.EIGHT:
HandleNextPlayer(CurrentPlayer, GetNextPlayer(2));
break;
case CardValue.ACE:
if (Players.Count > 2)
{
TurnDirection *= -1;
HandleNextPlayer(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:
HandleNextPlayer(CurrentPlayer, GetNextPlayer());
break;
}
}
private void HandleNextPlayer(Player current, Player next)
{
current.State = PlayerState.WAIT;
next.State = PlayerState.TURN;
CurrentPlayer = next;
}
private void DrawCard(Player player)
{
player.Hand.Add(Deck.DrawCard());
HandleNextPlayer(player, GetNextPlayer());
}
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;
}
}