basic logic + multiplayer
This commit is contained in:
@@ -51,7 +51,7 @@ public class RoomController : ControllerBase
|
|||||||
var id = _roomManager.CreateRoom();
|
var id = _roomManager.CreateRoom();
|
||||||
return Ok(id);
|
return Ok(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
public IActionResult Delete()
|
public IActionResult Delete()
|
||||||
{
|
{
|
||||||
|
|||||||
68
Mau/Game.cs
68
Mau/Game.cs
@@ -1,39 +1,81 @@
|
|||||||
namespace MauMau_Server.Mau;
|
using System.Net.WebSockets;
|
||||||
|
|
||||||
|
namespace MauMau_Server.Mau;
|
||||||
|
|
||||||
public class Game
|
public class Game
|
||||||
{
|
{
|
||||||
public readonly Deck Deck = new();
|
public readonly Deck Deck = new();
|
||||||
public Card CurrentCard;
|
public Card CurrentCard;
|
||||||
public List<Card> Hand;
|
public List<Player> Players = new();
|
||||||
|
public Player CurrentPlayer;
|
||||||
|
public int TurnDirection = 1;
|
||||||
|
|
||||||
public Game()
|
public Game()
|
||||||
{
|
{
|
||||||
CurrentCard = Deck.DrawCard();
|
CurrentCard = Deck.DrawCard();
|
||||||
Deck.AddCardToUsedDeck(CurrentCard);
|
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)
|
||||||
Deck.AddCardToUsedDeck(card);
|
{
|
||||||
Hand.Remove(GetSameCardFromHand(Hand, card));
|
Hand = Deck.DrawCards(8)
|
||||||
CurrentCard = card;
|
};
|
||||||
|
Players.Add(player);
|
||||||
|
if (Players.Count == 1) CurrentPlayer = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Card GetSameCardFromHand(IEnumerable<Card> 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<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);
|
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)
|
private static bool IsSameCardType(Card card1, Card card2)
|
||||||
|
|||||||
@@ -2,15 +2,27 @@
|
|||||||
|
|
||||||
public class GameState
|
public class GameState
|
||||||
{
|
{
|
||||||
|
public string PlayerName { get; set; }
|
||||||
public List<string> Hand { get; set; } = new();
|
public List<string> Hand { get; set; } = new();
|
||||||
public string CurrentCard { get; set; }
|
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());
|
Hand.Add(card.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var player in game.Players)
|
||||||
|
{
|
||||||
|
Players.Add(player.Name);
|
||||||
|
}
|
||||||
|
|
||||||
CurrentCard = game.CurrentCard.ToString();
|
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
|
public class Room
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, WebSocket> _connections = new();
|
private readonly Dictionary<string, WebSocket> _connections = new();
|
||||||
private Game _game = new();
|
private readonly Game _game = new();
|
||||||
|
|
||||||
public async Task InstantiateConnection(WebSocket socket)
|
public async Task InstantiateConnection(WebSocket socket)
|
||||||
{
|
{
|
||||||
@@ -18,26 +18,28 @@ public class Room
|
|||||||
|
|
||||||
private async Task HandleConnection(WebSocket socket, string socketId)
|
private async Task HandleConnection(WebSocket socket, string socketId)
|
||||||
{
|
{
|
||||||
BroadcastAsync(JsonSerializer.Serialize(new GameState(_game)));
|
BroadcastGameState();
|
||||||
var buffer = EmptyBuffer();
|
var buffer = EmptyBuffer();
|
||||||
var result = await ReceiveAsync(socket, buffer);
|
var result = await ReceiveAsync(socket, buffer);
|
||||||
while (!result.CloseStatus.HasValue)
|
while (!result.CloseStatus.HasValue)
|
||||||
{
|
{
|
||||||
var slicedBuffer = buffer[0..result.Count];
|
var slicedBuffer = buffer[0..result.Count];
|
||||||
var playedCard = JsonSerializer.Deserialize<CardDTO>(slicedBuffer).ToCard();
|
var playedCard = JsonSerializer.Deserialize<CardDTO>(slicedBuffer).ToCard();
|
||||||
_game.PlayCard(playedCard);
|
_game.PlayCard(socketId, playedCard);
|
||||||
BroadcastAsync(JsonSerializer.Serialize(new GameState(_game)));
|
BroadcastGameState();
|
||||||
buffer = EmptyBuffer();
|
buffer = EmptyBuffer();
|
||||||
result = await ReceiveAsync(socket, buffer);
|
result = await ReceiveAsync(socket, buffer);
|
||||||
}
|
}
|
||||||
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
|
||||||
RemoveConnection(socketId);
|
RemoveConnection(socketId);
|
||||||
|
_game.RemovePlayer(socketId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string AddConnection(WebSocket socket)
|
private string AddConnection(WebSocket socket)
|
||||||
{
|
{
|
||||||
var socketId = Guid.NewGuid().ToString();
|
var socketId = Guid.NewGuid().ToString();
|
||||||
_connections.Add(socketId, socket);
|
_connections.Add(socketId, socket);
|
||||||
|
_game.AddPlayerToGame(socketId, socket);
|
||||||
return socketId;
|
return socketId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,6 +65,16 @@ public class Room
|
|||||||
return result;
|
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)
|
private void BroadcastAsync(string message)
|
||||||
{
|
{
|
||||||
foreach (var (id, socket) in GetAllConnections())
|
foreach (var (id, socket) in GetAllConnections())
|
||||||
|
|||||||
Reference in New Issue
Block a user