basic logic + multiplayer
This commit is contained in:
64
Mau/Game.cs
64
Mau/Game.cs
@@ -1,39 +1,81 @@
|
||||
namespace MauMau_Server.Mau;
|
||||
using System.Net.WebSockets;
|
||||
|
||||
namespace MauMau_Server.Mau;
|
||||
|
||||
public class Game
|
||||
{
|
||||
public readonly Deck Deck = new();
|
||||
public Card CurrentCard;
|
||||
public List<Card> Hand;
|
||||
public List<Player> Players = new();
|
||||
public Player CurrentPlayer;
|
||||
public int TurnDirection = 1;
|
||||
|
||||
public Game()
|
||||
{
|
||||
CurrentCard = Deck.DrawCard();
|
||||
Deck.AddCardToUsedDeck(CurrentCard);
|
||||
Hand = Deck.DrawCards(8);
|
||||
}
|
||||
|
||||
public void PlayCard(Card card)
|
||||
public void AddPlayerToGame(string playerId, WebSocket socket)
|
||||
{
|
||||
if (!IsCardInHand(Hand, card) || !IsCardPlayable(CurrentCard, card)) return;
|
||||
var player = new Player("Koetje " + playerId.Split('-')[0], playerId, socket)
|
||||
{
|
||||
Hand = Deck.DrawCards(8)
|
||||
};
|
||||
Players.Add(player);
|
||||
if (Players.Count == 1) CurrentPlayer = player;
|
||||
}
|
||||
|
||||
public void RemovePlayer(string playerId)
|
||||
{
|
||||
var player = GetPlayer(playerId);
|
||||
Players.Remove(player);
|
||||
}
|
||||
|
||||
public void PlayCard(string playerId, Card card)
|
||||
{
|
||||
var player = GetPlayer(playerId);
|
||||
if (CurrentPlayer != player) return;
|
||||
var hand = player.Hand;
|
||||
if (!IsCardInHand(hand, card) || !IsCardPlayable(CurrentCard, card)) return;
|
||||
Deck.AddCardToUsedDeck(card);
|
||||
Hand.Remove(GetSameCardFromHand(Hand, card));
|
||||
hand.Remove(GetSameCardFromHand(hand, card));
|
||||
CurrentCard = card;
|
||||
CurrentPlayer = GetNextPlayer();
|
||||
}
|
||||
|
||||
private Card GetSameCardFromHand(IEnumerable<Card> hand, Card card)
|
||||
public Player GetNextPlayer()
|
||||
{
|
||||
return hand.FirstOrDefault(handCard => IsSameCardType(handCard, card) && IsSameCardValue(handCard, card));
|
||||
var index = Players.IndexOf(CurrentPlayer);
|
||||
index += TurnDirection;
|
||||
if (index >= Players.Count) index = 0;
|
||||
if (index < 0) index = Players.Count - 1;
|
||||
return Players[index];
|
||||
}
|
||||
|
||||
private bool IsCardPlayable(Card currentCard, Card playedCard)
|
||||
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);
|
||||
}
|
||||
|
||||
private bool IsCardInHand(IEnumerable<Card> hand, Card card)
|
||||
private static bool IsCardInHand(IEnumerable<Card> hand, Card card)
|
||||
{
|
||||
return hand.Any(handCard => IsSameCardType(handCard, card) && IsSameCardValue(handCard, 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)
|
||||
|
||||
@@ -2,15 +2,27 @@
|
||||
|
||||
public class GameState
|
||||
{
|
||||
public string PlayerName { get; set; }
|
||||
public List<string> Hand { get; set; } = new();
|
||||
public string CurrentCard { get; set; }
|
||||
public string CurrentPlayer { get; set; }
|
||||
public List<string> Players { get; set; } = new();
|
||||
|
||||
public GameState(Game game)
|
||||
public GameState(Game game, string playerId)
|
||||
{
|
||||
foreach (var card in game.Hand)
|
||||
var p = game.GetPlayer(playerId);
|
||||
PlayerName = p.Name;
|
||||
foreach (var card in p.Hand)
|
||||
{
|
||||
Hand.Add(card.ToString());
|
||||
}
|
||||
|
||||
foreach (var player in game.Players)
|
||||
{
|
||||
Players.Add(player.Name);
|
||||
}
|
||||
|
||||
CurrentCard = game.CurrentCard.ToString();
|
||||
CurrentPlayer = game.CurrentPlayer.Name;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace MauMau_Server.Mau;
|
||||
|
||||
public class HandDTO
|
||||
{
|
||||
public List<string> Cards { get; set; } = new();
|
||||
|
||||
public HandDTO(List<Card> cards)
|
||||
{
|
||||
foreach (var card in cards)
|
||||
{
|
||||
Cards.Add(card.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public HandDTO()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
20
Mau/Player.cs
Normal file
20
Mau/Player.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Net.WebSockets;
|
||||
|
||||
namespace MauMau_Server.Mau;
|
||||
|
||||
public class Player
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string PlayerId { get; set; }
|
||||
public WebSocket Socket { get; set; }
|
||||
public List<Card> Hand { get; set; } = new();
|
||||
|
||||
public Player(string name, string playerId, WebSocket socket)
|
||||
{
|
||||
Name = name;
|
||||
PlayerId = playerId;
|
||||
Socket = socket;
|
||||
}
|
||||
|
||||
public bool IsMe(string playerId) => PlayerId == playerId;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace MauMau_Server.Websockets;
|
||||
public class Room
|
||||
{
|
||||
private readonly Dictionary<string, WebSocket> _connections = new();
|
||||
private Game _game = new();
|
||||
private readonly Game _game = new();
|
||||
|
||||
public async Task InstantiateConnection(WebSocket socket)
|
||||
{
|
||||
@@ -18,26 +18,28 @@ public class Room
|
||||
|
||||
private async Task HandleConnection(WebSocket socket, string socketId)
|
||||
{
|
||||
BroadcastAsync(JsonSerializer.Serialize(new GameState(_game)));
|
||||
BroadcastGameState();
|
||||
var buffer = EmptyBuffer();
|
||||
var result = await ReceiveAsync(socket, buffer);
|
||||
while (!result.CloseStatus.HasValue)
|
||||
{
|
||||
var slicedBuffer = buffer[0..result.Count];
|
||||
var playedCard = JsonSerializer.Deserialize<CardDTO>(slicedBuffer).ToCard();
|
||||
_game.PlayCard(playedCard);
|
||||
BroadcastAsync(JsonSerializer.Serialize(new GameState(_game)));
|
||||
_game.PlayCard(socketId, playedCard);
|
||||
BroadcastGameState();
|
||||
buffer = EmptyBuffer();
|
||||
result = await ReceiveAsync(socket, buffer);
|
||||
}
|
||||
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
||||
RemoveConnection(socketId);
|
||||
_game.RemovePlayer(socketId);
|
||||
}
|
||||
|
||||
private string AddConnection(WebSocket socket)
|
||||
{
|
||||
var socketId = Guid.NewGuid().ToString();
|
||||
_connections.Add(socketId, socket);
|
||||
_game.AddPlayerToGame(socketId, socket);
|
||||
return socketId;
|
||||
}
|
||||
|
||||
@@ -63,6 +65,16 @@ public class Room
|
||||
return result;
|
||||
}
|
||||
|
||||
private void BroadcastGameState()
|
||||
{
|
||||
foreach (var (id, socket) in GetAllConnections())
|
||||
{
|
||||
var gameState = new GameState(_game, id);
|
||||
var message = JsonSerializer.Serialize(gameState);
|
||||
SendAsync(socket, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void BroadcastAsync(string message)
|
||||
{
|
||||
foreach (var (id, socket) in GetAllConnections())
|
||||
|
||||
Reference in New Issue
Block a user