Checking in before major rewrite
This commit is contained in:
@@ -23,8 +23,11 @@ namespace Squiddler_Server_Lite
|
||||
return TypedResults.BadRequest("No/Invalid game code");
|
||||
if (playerName is null)
|
||||
return TypedResults.BadRequest("No/Invalid player name");
|
||||
var gameState = GameState.FindGame(gameCode);
|
||||
if (gameState is null)
|
||||
return TypedResults.BadRequest("Game code not found");
|
||||
var card = gameState.PlayerDraw();
|
||||
return TypedResults.Ok(new Card("A", 2));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
internal static async Task<IResult> GetTestCard(string text, int value)
|
||||
=> TypedResults.Ok(new Card(text, value));
|
||||
@@ -39,17 +42,30 @@ namespace Squiddler_Server_Lite
|
||||
var gameState = GameState.FindGame(gameCode);
|
||||
if (gameState is null)
|
||||
return TypedResults.BadRequest("Game code not found");
|
||||
switch (gameState.JoinGame(playerName))
|
||||
return gameState.JoinGame(playerName) switch
|
||||
{
|
||||
case GameState.JoinGameResult.Success:
|
||||
return TypedResults.Ok();
|
||||
case GameState.JoinGameResult.AlreadyJoined:
|
||||
return TypedResults.Ok();
|
||||
case GameState.JoinGameResult.Full:
|
||||
return TypedResults.Conflict("Game is full");
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
GameState.JoinGameResult.Success => TypedResults.Ok(),
|
||||
GameState.JoinGameResult.AlreadyJoined => TypedResults.Ok(),
|
||||
GameState.JoinGameResult.Full => TypedResults.Conflict("Game is full"),
|
||||
_ => throw new InvalidOperationException(),
|
||||
};
|
||||
}
|
||||
internal static async Task<IResult> StartGame(HttpContext context)
|
||||
{
|
||||
var gameCode = GetGameCode(context.Request);
|
||||
var playerName = GetPlayerName(context.Request);
|
||||
if (gameCode is null)
|
||||
return TypedResults.BadRequest("No/Invalid game code");
|
||||
if (playerName is null)
|
||||
return TypedResults.BadRequest("No/Invalid player name");
|
||||
var gameState = GameState.FindGame(gameCode);
|
||||
if (gameState is null)
|
||||
return TypedResults.BadRequest("Game code not found");
|
||||
if (gameState.players.Any(p => p.userName is null))
|
||||
return TypedResults.Conflict("Not all players have joined yet");
|
||||
if (!gameState.Start())
|
||||
return TypedResults.Conflict("Game already started");
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
internal static async Task<IResult> PlayCards(HttpContext context,
|
||||
[FromBody] [Required] PlayedCards played)
|
||||
@@ -66,17 +82,106 @@ namespace Squiddler_Server_Lite
|
||||
var player = gameState.ActivePlayer();
|
||||
if (player.userName != playerName)
|
||||
return TypedResults.BadRequest("Not the active player");
|
||||
Card? mustDiscardOnFail = null;
|
||||
if (!gameState.playerDrew)
|
||||
{
|
||||
var drawnCard = gameState.PlayerTakesFromDiscard();
|
||||
mustDiscardOnFail = gameState.PlayerTakesFromDiscard();
|
||||
if (!gameState.ValidatePlayedCards(played))
|
||||
{
|
||||
gameState.PlayerDiscard(drawnCard);
|
||||
gameState.PlayerDiscard(mustDiscardOnFail);
|
||||
return TypedResults.BadRequest("Cards don't match player hand");
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
|
||||
//player not required to use all cards
|
||||
if (gameState.playerWentOut >= 0)
|
||||
{
|
||||
gameState.ActivePlayer().roundScores.Add(played.BaseScore());
|
||||
bool discardSuccess = gameState.PlayerDiscard(played.discarded);
|
||||
Debug.Assert(discardSuccess);
|
||||
gameState.ActivePlayer().playArea = new(played);
|
||||
gameState.NextTurn();
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
else
|
||||
{
|
||||
if (played.unplayed.Any())
|
||||
{
|
||||
gameState.PlayerDiscard(mustDiscardOnFail);
|
||||
return TypedResults.BadRequest("Cannot play cards without going out");
|
||||
}
|
||||
gameState.ActivePlayer().roundScores.Add(played.BaseScore());
|
||||
gameState.playerWentOut = gameState.activePlayer;
|
||||
bool discardSuccess = gameState.PlayerDiscard(played.discarded);
|
||||
Debug.Assert(discardSuccess);
|
||||
gameState.ActivePlayer().playArea = new(played);
|
||||
gameState.NextTurn();
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
}
|
||||
internal static async Task<IResult> DiscardEndTurn(HttpContext context,
|
||||
[FromBody] [Required] Card discard)
|
||||
{
|
||||
var gameCode = GetGameCode(context.Request);
|
||||
var playerName = GetPlayerName(context.Request);
|
||||
if (gameCode is null)
|
||||
return TypedResults.BadRequest("No/Invalid game code");
|
||||
if (playerName is null)
|
||||
return TypedResults.BadRequest("No/Invalid player name");
|
||||
var gameState = GameState.FindGame(gameCode);
|
||||
if (gameState is null)
|
||||
return TypedResults.BadRequest("Game code not found");
|
||||
var player = gameState.ActivePlayer();
|
||||
if (player.userName != playerName)
|
||||
return TypedResults.BadRequest("Not the active player");
|
||||
if (!gameState.playerDrew)
|
||||
{
|
||||
if (discard == gameState.discard.Last())
|
||||
{
|
||||
gameState.NextTurn();
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
var card = gameState.PlayerTakesFromDiscard();
|
||||
if (!gameState.PlayerDiscard(discard))
|
||||
{
|
||||
gameState.PlayerDiscard(card);
|
||||
return TypedResults.BadRequest("Card not in hand or top of discard");
|
||||
}
|
||||
gameState.NextTurn();
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gameState.PlayerDiscard(discard))
|
||||
return TypedResults.BadRequest("Card not in hand");
|
||||
gameState.NextTurn();
|
||||
return TypedResults.Ok();
|
||||
}
|
||||
}
|
||||
internal static async Task<IResult> GetState(HttpContext context)
|
||||
{
|
||||
var gameCode = GetGameCode(context.Request);
|
||||
var playerName = GetPlayerName(context.Request);
|
||||
if (gameCode is null)
|
||||
return TypedResults.BadRequest("No/Invalid game code");
|
||||
if (playerName is null)
|
||||
return TypedResults.BadRequest("No/Invalid player name");
|
||||
var gameState = GameState.FindGame(gameCode);
|
||||
if (gameState is null)
|
||||
return TypedResults.BadRequest("Game code not found");
|
||||
var player = gameState.GetPlayerFromName(playerName);
|
||||
if (player is int playerIndex)
|
||||
return TypedResults.Ok(new VisibleState()
|
||||
{
|
||||
gameName = gameState.gameName,
|
||||
playerName = gameState.players[playerIndex].userName,
|
||||
players = gameState.players.Select(p => p.userName).ToList(),
|
||||
roundNumber = gameState.round,
|
||||
activePlayer = gameState.activePlayer,
|
||||
hand = gameState.players[playerIndex].hand.ToList(),
|
||||
discard = gameState.discard.ToList(),
|
||||
otherPlayersCards = gameState.players.Select(p => p.playArea).ToList(),
|
||||
});
|
||||
else
|
||||
return TypedResults.BadRequest("Player not found");
|
||||
}
|
||||
private static GameCode? GetGameCode(HttpRequest request)
|
||||
{
|
||||
|
||||
31
Squiddler-Server-Lite/Assets/Decks/DefaultDeck.txt
Normal file
31
Squiddler-Server-Lite/Assets/Decks/DefaultDeck.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
A 2 10
|
||||
B 8 2
|
||||
C 8 2
|
||||
D 5 4
|
||||
E 2 12
|
||||
F 6 2
|
||||
G 6 4
|
||||
H 7 2
|
||||
I 2 8
|
||||
J 13 2
|
||||
K 8 2
|
||||
L 3 4
|
||||
M 5 2
|
||||
N 5 6
|
||||
O 2 8
|
||||
P 6 2
|
||||
Q 15 2
|
||||
R 5 6
|
||||
S 3 4
|
||||
T 3 6
|
||||
U 4 6
|
||||
V 11 2
|
||||
W 10 2
|
||||
X 12 2
|
||||
Y 4 4
|
||||
Z 14 2
|
||||
Qu 9 2
|
||||
In 7 2
|
||||
Er 7 2
|
||||
Cl 10 2
|
||||
Th 9 2
|
||||
128960
Squiddler-Server-Lite/Assets/WordLists/EOWL.txt
Normal file
128960
Squiddler-Server-Lite/Assets/WordLists/EOWL.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,7 @@ var playPrefix = apiPrefix.MapGroup("/play")
|
||||
{
|
||||
Type = "string",
|
||||
MaxLength = 4,
|
||||
MinLength = 4
|
||||
MinLength = 4,
|
||||
},
|
||||
});
|
||||
newOp.Parameters.Add(new OpenApiParameter
|
||||
@@ -88,12 +88,30 @@ playPrefix.MapPut("/join_game", (Delegate)Api.JoinGame)
|
||||
.WithName("JoinGame")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapPut("/start_game", (Delegate)Api.StartGame)
|
||||
.Produces(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.Produces<string>(409, "text/plain")
|
||||
.WithName("StartGame")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapPut("/play_cards", (Delegate)Api.PlayCards)
|
||||
.Produces(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("PlayCards")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapPost("/discard_end_turn", (Delegate)Api.DiscardEndTurn)
|
||||
.Produces(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("DiscardEndTurn")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapGet("/get_state", (Delegate)Api.GetState)
|
||||
.Produces<VisibleState>(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("GetState")
|
||||
.WithOpenApi();
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
@@ -6,12 +8,15 @@ namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public GameCode gameCode { get; set; }
|
||||
public string gameName { get; set; }
|
||||
public List<Card> deck { get; set; }
|
||||
public List<Card> resetDeck { get; set; }
|
||||
public readonly int FIRST_ROUND;
|
||||
public readonly int LAST_ROUND;
|
||||
public int round { get; set; }
|
||||
public List<UserState> users { get; set; }
|
||||
public List<UserState> players { get; set; }
|
||||
public int activePlayer { get; set; }
|
||||
public List<Card> discard { get; set; } = new();
|
||||
protected object Lock { get; } = new();
|
||||
//index of player who first went out, otherwise -1
|
||||
public int playerWentOut { get; set; } = -1;
|
||||
#region TURNSTATE
|
||||
@@ -19,35 +24,101 @@ namespace Squiddler_Server_Lite.StateObjects
|
||||
#endregion
|
||||
public void AddToDiscard(Card card)
|
||||
{
|
||||
lock (Lock)
|
||||
discard.Add(new Card(card));
|
||||
}
|
||||
public void DeckToDiscard()
|
||||
{
|
||||
lock(Lock)
|
||||
{
|
||||
var index = Random.Shared.Next(deck.Count);
|
||||
var card = deck[index];
|
||||
deck.RemoveAt(index);
|
||||
discard.Add(new Card(card));
|
||||
}
|
||||
}
|
||||
public Card PlayerTakesFromDiscard()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
Card card = discard[discard.Count - 1];
|
||||
discard.RemoveAt(discard.Count - 1);
|
||||
ActivePlayer().hand.Add(card);
|
||||
return new Card(card);
|
||||
}
|
||||
}
|
||||
//matches the PlayedCards against the active player's hand
|
||||
public bool ValidatePlayedCards(PlayedCards playedCards)
|
||||
=> playedCards.AllCards().Order().SequenceEqual(ActivePlayer().hand.Order());
|
||||
{
|
||||
lock (Lock)
|
||||
return playedCards.AllCards().Order().SequenceEqual(ActivePlayer().hand.Order());
|
||||
}
|
||||
public bool PlayerDiscard(Card? card)
|
||||
{
|
||||
|
||||
if (card is null)
|
||||
return true;
|
||||
lock (Lock)
|
||||
{
|
||||
if (!ActivePlayer().hand.Remove(card))
|
||||
return false;
|
||||
discard.Add(new Card(card));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public JoinGameResult JoinGame(string playerName)
|
||||
{
|
||||
if (users.Any(u => u.userName == playerName))
|
||||
lock (Lock)
|
||||
{
|
||||
if (players.Any(u => CompareNames(u.userName, playerName)))
|
||||
return JoinGameResult.AlreadyJoined;
|
||||
//kind of an abuse of Any() to have side effects
|
||||
return users.Any(u => u.TryJoin(playerName))
|
||||
return players.Any(u => u.TryJoin(playerName))
|
||||
? JoinGameResult.Success : JoinGameResult.Full;
|
||||
}
|
||||
}
|
||||
public Card PlayerDraw(int player)
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
int index = Random.Shared.Next(deck.Count);
|
||||
var card = deck[index];
|
||||
deck.RemoveAt(index);
|
||||
players[player].hand.Add(card);
|
||||
return card;
|
||||
}
|
||||
}
|
||||
//the active player draws a card
|
||||
public Card PlayerDraw()
|
||||
{
|
||||
lock (Lock)
|
||||
return PlayerDraw(activePlayer);
|
||||
}
|
||||
public UserState ActivePlayer()
|
||||
{
|
||||
return users[activePlayer];
|
||||
lock (Lock)
|
||||
return players[activePlayer];
|
||||
}
|
||||
public bool Start()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
if (Started())
|
||||
return false;
|
||||
round = FIRST_ROUND;
|
||||
DrawHands();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public bool Started()
|
||||
{
|
||||
return round > 0;
|
||||
}
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
//the Create method guarantees this value will be written to
|
||||
private GameState(int firstRound, int lastRound)
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
{
|
||||
FIRST_ROUND = firstRound;
|
||||
LAST_ROUND = lastRound;
|
||||
@@ -58,8 +129,9 @@ namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
gameCode = GameCode.CreateRandom(),
|
||||
gameName = config.gameName,
|
||||
users = Enumerable.Range(0, config.playerCount)
|
||||
players = Enumerable.Range(0, config.playerCount)
|
||||
.Select(i => new UserState()).ToList(),
|
||||
resetDeck = LoadDeck(Path.Join("Assets", "Decks", "DefaultDeck.txt")),
|
||||
};
|
||||
ActiveStates.Add(gameState);
|
||||
return gameState;
|
||||
@@ -67,18 +139,116 @@ namespace Squiddler_Server_Lite.StateObjects
|
||||
private static readonly List<GameState> ActiveStates = new();
|
||||
public static GameState? FindGame(GameCode gameCode)
|
||||
{
|
||||
return ActiveStates.FirstOrDefault(g => g.gameCode == gameCode, null);
|
||||
return ActiveStates.FirstOrDefault(g => g!.gameCode == gameCode, null);
|
||||
}
|
||||
public static bool DeleteGame(GameCode gameCode)
|
||||
{
|
||||
return ActiveStates.RemoveAll(g => g.gameCode == gameCode) > 0;
|
||||
}
|
||||
|
||||
internal void PlayerDiscard(Card drawnCard)
|
||||
internal void NextTurn()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
activePlayer = (activePlayer + 1) % players.Count;
|
||||
playerDrew = false;
|
||||
if (activePlayer == playerWentOut)
|
||||
NextRound();
|
||||
else
|
||||
return;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
private void ResetCards()
|
||||
{
|
||||
deck = resetDeck.ToList();
|
||||
foreach (var player in players)
|
||||
player.hand.Clear();
|
||||
discard.Clear();
|
||||
DeckToDiscard();
|
||||
}
|
||||
private void DrawHands()
|
||||
{
|
||||
ResetCards();
|
||||
for (int player = 0; player < players.Count; player++)
|
||||
for (int i = 0; i < round; i++)
|
||||
PlayerDraw(player);
|
||||
}
|
||||
private void NextRound()
|
||||
{
|
||||
int PlayerWordCount(PlayedCards played)
|
||||
=> played.Words().Sum(w => w.Any() ? 1 : 0);
|
||||
int PlayerLongestWord(PlayedCards played)
|
||||
{
|
||||
return played.Words().Max(w => w.Select(w => w.text).Aggregate((w1, w2) => w1 + w1).Length);
|
||||
}
|
||||
int GreatestWithoutTie(IList<int> values)
|
||||
{
|
||||
int max = values.Max();
|
||||
if (values.Where(v => v == max).Count() == 1)
|
||||
return values.IndexOf(max);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
lock (Lock)
|
||||
{
|
||||
foreach (var player in players)
|
||||
Debug.Assert(player.playArea is not null);
|
||||
var wordCounts = players.Select(u => PlayerWordCount(u.playArea!)).ToList();
|
||||
var mostWordsPlayer = GreatestWithoutTie(wordCounts);
|
||||
var wordLengths = players.Select(u => PlayerLongestWord(u.playArea!)).ToList();
|
||||
var longestWordPlayer = GreatestWithoutTie(wordLengths);
|
||||
if (mostWordsPlayer >= 0)
|
||||
players[mostWordsPlayer].roundScores[players[mostWordsPlayer].roundScores.Count] += 10;
|
||||
if (longestWordPlayer >= 0)
|
||||
players[longestWordPlayer].roundScores[players[longestWordPlayer].roundScores.Count] += 10;
|
||||
playerWentOut = -1;
|
||||
round++;
|
||||
if (round > LAST_ROUND)
|
||||
EndGame();
|
||||
else
|
||||
{
|
||||
DrawHands();
|
||||
}
|
||||
}
|
||||
}
|
||||
public int? GetPlayerFromName(string name)
|
||||
{
|
||||
for (int i = 0; i < players.Count; i++)
|
||||
if (CompareNames(name, players[i].userName))
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
private static List<Card> LoadDeck(string filepath)
|
||||
{
|
||||
List<Card> deck = new();
|
||||
foreach (var line in File.ReadAllLines(filepath))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
var spl = line.Split(' ');
|
||||
if (spl.Length != 3)
|
||||
throw new FormatException();
|
||||
var text = spl[0];
|
||||
var value = int.Parse(spl[1]);
|
||||
var count = int.Parse(spl[2]);
|
||||
for (int i = 0; i < count; i++)
|
||||
deck.Add(new Card(text, value));
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
private static bool CompareNames(string name1, string name2)
|
||||
{
|
||||
if (name1 is null || name2 is null)
|
||||
return false;
|
||||
return name1.ToUpper() == name2.ToUpper();
|
||||
}
|
||||
private void EndGame()
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
public enum JoinGameResult
|
||||
{
|
||||
Success,
|
||||
|
||||
@@ -6,6 +6,10 @@ namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public string? userName { get; set; }
|
||||
public List<Card> hand { get; } = new();
|
||||
public List<int> roundScores { get; } = new();
|
||||
public PlayedCards? playArea { get; set; }
|
||||
public int TotalScore()
|
||||
=> roundScores.Sum();
|
||||
public bool TryJoin(string userName)
|
||||
{
|
||||
if (this.userName is null)
|
||||
|
||||
29
Squiddler-Server-Lite/StateObjects/WordList.cs
Normal file
29
Squiddler-Server-Lite/StateObjects/WordList.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
//using System.Path
|
||||
|
||||
namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public class WordList
|
||||
{
|
||||
public HashSet<string> words { get; } = new();
|
||||
public void AddWord(string word)
|
||||
{
|
||||
words.Add(word.Trim().ToUpper());
|
||||
}
|
||||
public void AddRange(IEnumerable<string> newWords)
|
||||
{
|
||||
foreach (var w in newWords)
|
||||
AddWord(w);
|
||||
}
|
||||
public void LoadFile(string filepath)
|
||||
{
|
||||
AddRange(File.ReadLines(filepath));
|
||||
}
|
||||
//temporary, this should be replaced with something more flexible later
|
||||
public void LoadEOWL()
|
||||
=> LoadFile(Path.Join("Assets", "WordLists", "EOWL.txt"));
|
||||
public WordList()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class Card : IComparable<Card>
|
||||
public class Card : IComparable<Card>, IEquatable<Card>
|
||||
{
|
||||
public string text { get; set; }
|
||||
public int value { get; set; }
|
||||
public override string ToString()
|
||||
=> $"[\"{text}\": {value}";
|
||||
[JsonConstructor]
|
||||
public Card(string text, int value)
|
||||
{
|
||||
this.text = FixCaps(text) ?? throw new ArgumentNullException(nameof(text));
|
||||
@@ -24,7 +27,6 @@
|
||||
return text;
|
||||
return text[..1].ToUpper() + text[1..].ToLower();
|
||||
}
|
||||
|
||||
public int CompareTo(Card? other)
|
||||
{
|
||||
if (other is null)
|
||||
@@ -34,5 +36,7 @@
|
||||
return value.CompareTo(other.value);
|
||||
return sCmp;
|
||||
}
|
||||
public bool Equals(Card? other)
|
||||
=> CompareTo(other) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class PlayedCards
|
||||
{
|
||||
@@ -10,8 +12,27 @@
|
||||
public List<Card> unplayed { get; set; }
|
||||
public Card discarded { get; set; }
|
||||
public IEnumerable<Card> AllCards()
|
||||
=> word1.Concat(word2).Concat(word3)
|
||||
.Concat(word4).Concat(word5).Append(discarded);
|
||||
=> Words().Aggregate<IEnumerable<Card>>(Enumerable.Concat)
|
||||
.Concat(unplayed).Append(discarded);
|
||||
public IEnumerable<List<Card>> Words()
|
||||
{
|
||||
yield return word1;
|
||||
yield return word2;
|
||||
yield return word3;
|
||||
yield return word4;
|
||||
yield return word5;
|
||||
}
|
||||
public int BaseScore()
|
||||
=> word1.Sum(c => c.value)
|
||||
+ word2.Sum(c => c.value)
|
||||
+ word3.Sum(c => c.value)
|
||||
+ word4.Sum(c => c.value)
|
||||
+ word5.Sum(c => c.value)
|
||||
- unplayed.Sum(c => c.value);
|
||||
public PlayedCards()
|
||||
{
|
||||
|
||||
}
|
||||
public PlayedCards(IEnumerable<Card> word1,
|
||||
IEnumerable<Card> word2,
|
||||
IEnumerable<Card> word3,
|
||||
@@ -26,7 +47,14 @@
|
||||
this.word4 = word4.ToList();
|
||||
this.word5 = word5.ToList();
|
||||
this.unplayed = unplayed.ToList();
|
||||
this.discarded = discarded;
|
||||
this.discarded = new(discarded);
|
||||
}
|
||||
public PlayedCards(PlayedCards playedCards)
|
||||
: this(playedCards.word1, playedCards.word2, playedCards.word3,
|
||||
playedCards.word4, playedCards.word5, playedCards.unplayed,
|
||||
playedCards.discarded)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Squiddler-Server-Lite/TransferObjects/VisibleState.cs
Normal file
14
Squiddler-Server-Lite/TransferObjects/VisibleState.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class VisibleState
|
||||
{
|
||||
public string gameName { get; set; }
|
||||
public string playerName { get; set; }
|
||||
public int roundNumber { get; set; }
|
||||
public List<string> players { get; set; }
|
||||
public int activePlayer { get; set; }
|
||||
public List<Card> hand { get; set; }
|
||||
public List<Card> discard { get; set; }
|
||||
public List<PlayedCards?> otherPlayersCards { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user