Better messaging and better rule implementation
All checks were successful
All checks were successful
This commit is contained in:
128
Mau/Game.cs
128
Mau/Game.cs
@@ -11,6 +11,8 @@ public class Game : RoomType
|
||||
{
|
||||
private readonly Deck _deck = new();
|
||||
private readonly TurnManager _turnManager = new();
|
||||
public readonly List<Card> MauCardBuffer = new();
|
||||
public CardType? NextAllowedCardType { get; set; }
|
||||
|
||||
public Game(Room.Room room, IEnumerable<ConnectionInstance> connections) : base(room)
|
||||
{
|
||||
@@ -69,7 +71,7 @@ public class Game : RoomType
|
||||
public override void OnConnect(ConnectionInstance connection)
|
||||
{
|
||||
// Broadcast that a player joined
|
||||
var joinMessage = new JoinMessage(connection.Id, connection.Name + " has joined the room.");
|
||||
var joinMessage = new JoinMessage(_room.Connections, connection);
|
||||
_room.BroadCast(new RoomMessage<JoinMessage>("JOIN", joinMessage));
|
||||
|
||||
// Create a new player, give them a new hand and add them to the game
|
||||
@@ -88,7 +90,7 @@ public class Game : RoomType
|
||||
public override void OnDisconnect(ConnectionInstance connection)
|
||||
{
|
||||
// Broadcast that the player left
|
||||
var leaveMessage = new LeaveMessage(connection.Id, connection.Name + " has left the room.");
|
||||
var leaveMessage = new LeaveMessage(connection);
|
||||
_room.BroadCast(new RoomMessage<LeaveMessage>("LEAVE", leaveMessage));
|
||||
|
||||
// Get the player that left
|
||||
@@ -127,24 +129,11 @@ public class Game : RoomType
|
||||
return;
|
||||
}
|
||||
|
||||
// Does the current card require the next player to draw cards?
|
||||
var isCardGivingCard = _deck.CurrentCard.CardType == CardType.JOKER || _deck.CurrentCard.CardValue == CardValue.TWO;
|
||||
|
||||
// Can the player that received a card giving card counter the card?
|
||||
var skippedPlayerCanPlay = player.CanPlayCard(_deck.CurrentCard);
|
||||
|
||||
// If the card is a card giving card and the player cannot counter it, skip the next player
|
||||
var shouldSkipPlayer = isCardGivingCard && !skippedPlayerCanPlay;
|
||||
var nextPlayer = shouldSkipPlayer
|
||||
? _turnManager.GetNextPlayer(2)
|
||||
: _turnManager.GetNextPlayer();
|
||||
|
||||
// TODO: Not make it a jack, as it would not work when a Joker was played
|
||||
// Set the new current card
|
||||
_deck.CurrentCard = new Card(cardType, CardValue.JACK);
|
||||
// Set the next card type that is allowed to be played
|
||||
NextAllowedCardType = cardType;
|
||||
|
||||
// Change the turns
|
||||
_turnManager.ChangeTurnTo(nextPlayer);
|
||||
_turnManager.ChangeTurnTo();
|
||||
|
||||
// Broadcast new game state
|
||||
SendGameState();
|
||||
@@ -157,23 +146,43 @@ public class Game : RoomType
|
||||
* <item>Could not play a card and had to draw a card</item>
|
||||
* <item>Chose to draw a card as a strategic move</item>
|
||||
* </list>
|
||||
* When there are multiple mau cards played, the player has to draw the combined amount of mau cards played.
|
||||
* </summary>
|
||||
* <param name="player">The player that drew a card</param>
|
||||
* <param name="data">A string that can be serialized to a drawcard instance</param>
|
||||
*/
|
||||
private void Draw(Player player)
|
||||
{
|
||||
// Draw a card from the deck
|
||||
var drawnCard = _deck.DrawCard();
|
||||
|
||||
// Give the card to the player
|
||||
player.GiveCard(drawnCard);
|
||||
|
||||
// Change the player if the drawn card cannot be played
|
||||
if (!drawnCard.CanBePlayedOn(_deck.CurrentCard))
|
||||
// If there are cards in the MauCardBuffer, this means there are multiple cards that need to be drawn
|
||||
// Otherwise, just draw a single card
|
||||
if (MauCardBuffer.Count > 0)
|
||||
{
|
||||
// Count the amount of cards that need to be drawn
|
||||
var totalCards = CountMauCardBuffer();
|
||||
|
||||
// Draw the cards from the deck
|
||||
var drawnCards = _deck.DrawCards(totalCards);
|
||||
|
||||
// Give the cards to the player
|
||||
player.GiveCards(drawnCards);
|
||||
|
||||
// Change the turn
|
||||
_turnManager.ChangeTurnTo();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw a card from the deck
|
||||
var drawnCard = _deck.DrawCard();
|
||||
|
||||
// Give the card to the player
|
||||
player.GiveCard(drawnCard);
|
||||
|
||||
// Change the player if the drawn card cannot be played
|
||||
if (!drawnCard.CanBePlayedOn(_deck.CurrentCard))
|
||||
{
|
||||
_turnManager.ChangeTurnTo();
|
||||
}
|
||||
}
|
||||
|
||||
// Broadcast new game state
|
||||
SendGameState();
|
||||
@@ -208,14 +217,34 @@ public class Game : RoomType
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the played card is compatible with the current card
|
||||
// If not, ignore the play
|
||||
if (!playerCard.CanBePlayedOn(_deck.CurrentCard))
|
||||
|
||||
// Check if there is a specific card type that is allowed to be played
|
||||
if (NextAllowedCardType != null)
|
||||
{
|
||||
return;
|
||||
// If the card is not the allowed card type, not the same value or a joker, ignore the message
|
||||
if (playerCard.CardType != NextAllowedCardType && playerCard.CardType != CardType.JOKER && playerCard.CardValue != _deck.CurrentCard.CardValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Reset the allowed card type, so the next player has the normal same type and same value rules
|
||||
NextAllowedCardType = null;
|
||||
} else if (MauCardBuffer.Count > 0)
|
||||
{
|
||||
// If there are queued mau cards, the player can only another mau card (or draw)
|
||||
if (playerCard.CardType != CardType.JOKER && playerCard.CardValue != CardValue.TWO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Check if the card can be played on the current card, if not, ignore the message
|
||||
if (!playerCard.CanBePlayedOn(_deck.CurrentCard))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the card from the player's hand
|
||||
player.Hand.Remove(playerCard);
|
||||
|
||||
@@ -251,14 +280,14 @@ public class Game : RoomType
|
||||
case CardValue.RED:
|
||||
case CardValue.BLACK:
|
||||
{
|
||||
_turnManager.GetNextPlayer().GiveCards(_deck.DrawCards(5));
|
||||
MauCardBuffer.Add(card);
|
||||
_turnManager.CurrentPlayer.State = PlayerState.CHOOSE;
|
||||
break;
|
||||
}
|
||||
case CardValue.TWO:
|
||||
{
|
||||
_turnManager.GetNextPlayer().GiveCards(_deck.DrawCards(2));
|
||||
_turnManager.ChangeTurnTo(_turnManager.GetNextPlayer(2));
|
||||
MauCardBuffer.Add(card);
|
||||
_turnManager.ChangeTurnTo();
|
||||
break;
|
||||
}
|
||||
case CardValue.SEVEN:
|
||||
@@ -290,6 +319,33 @@ public class Game : RoomType
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <summary>
|
||||
* Count the amount of cards that need to be drawn from the MauCardBuffer. This method also clears the buffer.
|
||||
* </summary>
|
||||
* <returns>The amount of cards that need to be drawn</returns>
|
||||
*/
|
||||
private int CountMauCardBuffer()
|
||||
{
|
||||
var totalCards = 0;
|
||||
foreach (var card in MauCardBuffer)
|
||||
{
|
||||
if (card.CardType == CardType.JOKER)
|
||||
{
|
||||
totalCards += 5;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (card.CardValue == CardValue.TWO)
|
||||
{
|
||||
totalCards += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
MauCardBuffer.Clear();
|
||||
return totalCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* <summary>
|
||||
* Create a game state for each player and send it to them.
|
||||
@@ -300,7 +356,7 @@ public class Game : RoomType
|
||||
{
|
||||
foreach (var player in _turnManager.Players)
|
||||
{
|
||||
var gameState = new GameState(player, _deck.CurrentCard, _turnManager.CurrentPlayer, _turnManager.Players);
|
||||
var gameState = new GameState(player, _deck.CurrentCard, NextAllowedCardType, _turnManager.CurrentPlayer, _turnManager.Players);
|
||||
player.Connection.SendMessageAsync(JsonConvert.SerializeObject(new RoomMessage<GameState>("GAME", gameState)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user