diff --git a/Controllers/RoomController.cs b/Controllers/RoomController.cs index ac24bd7..f9c281b 100644 --- a/Controllers/RoomController.cs +++ b/Controllers/RoomController.cs @@ -51,7 +51,7 @@ public class RoomController : ControllerBase var id = _roomManager.CreateRoom(); return Ok(id); } - + [HttpDelete] public IActionResult Delete() { diff --git a/Mau/Game.cs b/Mau/Game.cs index a8d29a4..1ba09f0 100644 --- a/Mau/Game.cs +++ b/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 Hand; + public List 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; - Deck.AddCardToUsedDeck(card); - Hand.Remove(GetSameCardFromHand(Hand, card)); - CurrentCard = card; + var player = new Player("Koetje " + playerId.Split('-')[0], playerId, socket) + { + Hand = Deck.DrawCards(8) + }; + Players.Add(player); + if (Players.Count == 1) CurrentPlayer = player; } - private Card GetSameCardFromHand(IEnumerable hand, Card card) + public void RemovePlayer(string playerId) { - return hand.FirstOrDefault(handCard => IsSameCardType(handCard, card) && IsSameCardValue(handCard, card)); + var player = GetPlayer(playerId); + Players.Remove(player); } - private bool IsCardPlayable(Card currentCard, Card playedCard) + 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)); + CurrentCard = card; + CurrentPlayer = GetNextPlayer(); + } + + public Player GetNextPlayer() + { + var index = Players.IndexOf(CurrentPlayer); + 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); } - private bool IsCardInHand(IEnumerable hand, Card card) + private static bool IsCardInHand(IEnumerable 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) diff --git a/Mau/GameState.cs b/Mau/GameState.cs index cdb7f1c..2218875 100644 --- a/Mau/GameState.cs +++ b/Mau/GameState.cs @@ -2,15 +2,27 @@ public class GameState { + public string PlayerName { get; set; } public List Hand { get; set; } = new(); public string CurrentCard { get; set; } + public string CurrentPlayer { get; set; } + public List 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; } } \ No newline at end of file diff --git a/Mau/HandDTO.cs b/Mau/HandDTO.cs deleted file mode 100644 index a5b9417..0000000 --- a/Mau/HandDTO.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace MauMau_Server.Mau; - -public class HandDTO -{ - public List Cards { get; set; } = new(); - - public HandDTO(List cards) - { - foreach (var card in cards) - { - Cards.Add(card.ToString()); - } - } - - public HandDTO() - { - - } -} \ No newline at end of file diff --git a/Mau/Player.cs b/Mau/Player.cs new file mode 100644 index 0000000..0a91b20 --- /dev/null +++ b/Mau/Player.cs @@ -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 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; +} \ No newline at end of file diff --git a/Websockets/Room.cs b/Websockets/Room.cs index 6cf4461..b3003fd 100644 --- a/Websockets/Room.cs +++ b/Websockets/Room.cs @@ -8,7 +8,7 @@ namespace MauMau_Server.Websockets; public class Room { private readonly Dictionary _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(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())