basic logic + multiplayer

This commit is contained in:
2023-03-17 11:42:53 +01:00
parent d05ece2efc
commit 5d1e78094f
6 changed files with 106 additions and 39 deletions

View File

@@ -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)
{
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); Deck.AddCardToUsedDeck(card);
Hand.Remove(GetSameCardFromHand(Hand, card)); hand.Remove(GetSameCardFromHand(hand, card));
CurrentCard = 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); 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)

View File

@@ -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;
} }
} }

View File

@@ -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
View 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;
}

View File

@@ -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())