a lot of stuff
This commit is contained in:
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
[*.cs]
|
||||
|
||||
# IDE1006: Naming Styles
|
||||
dotnet_diagnostic.IDE1006.severity = none
|
||||
@@ -5,6 +5,11 @@ VisualStudioVersion = 17.6.33723.286
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squiddler-Server-Lite", "Squiddler-Server-Lite\Squiddler-Server-Lite.csproj", "{89A88EA7-771B-4E74-B662-C13363C4C140}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B32566A0-4B05-4EB6-8BB8-B98E7DA76B25}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
||||
101
Squiddler-Server-Lite/Api.cs
Normal file
101
Squiddler-Server-Lite/Api.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Squiddler_Server_Lite.StateObjects;
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Squiddler_Server_Lite
|
||||
{
|
||||
internal static class Api
|
||||
{
|
||||
internal static async Task<IResult> CreateGame([FromBody] [Required] NewGameConfiguration config)
|
||||
{
|
||||
if (!config.Validate())
|
||||
return TypedResults.BadRequest("Invalid configuration");
|
||||
var gameState = GameState.Create(config);
|
||||
return TypedResults.Ok(gameState.gameCode);
|
||||
}
|
||||
internal static async Task<IResult> DrawCard(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");
|
||||
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));
|
||||
internal static async Task<IResult> JoinGame(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");
|
||||
switch (gameState.JoinGame(playerName))
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
internal static async Task<IResult> PlayCards(HttpContext context,
|
||||
[FromBody] [Required] PlayedCards played)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var drawnCard = gameState.PlayerTakesFromDiscard();
|
||||
if (!gameState.ValidatePlayedCards(played))
|
||||
{
|
||||
gameState.PlayerDiscard(drawnCard);
|
||||
return TypedResults.BadRequest("Cards don't match player hand");
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private static GameCode? GetGameCode(HttpRequest request)
|
||||
{
|
||||
if (request.Headers.ContainsKey(Headers.GAMECODE))
|
||||
if (GameCode.TryParse(request.Headers[Headers.GAMECODE].ToString(),
|
||||
out GameCode gameCode))
|
||||
return gameCode;
|
||||
return null;
|
||||
}
|
||||
private static string? GetPlayerName(HttpRequest request)
|
||||
{
|
||||
if (request.Headers.ContainsKey(Headers.PLAYERNAME))
|
||||
return request.Headers[Headers.PLAYERNAME].ToString();
|
||||
return null;
|
||||
}
|
||||
public static class Headers
|
||||
{
|
||||
public const string GAMECODE = "GAME-CODE";
|
||||
public const string PLAYERNAME = "PLAYER-NAME";
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Squiddler-Server-Lite/Middleware/RequireGameCode.cs
Normal file
16
Squiddler-Server-Lite/Middleware/RequireGameCode.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Squiddler_Server_Lite.Middleware
|
||||
{
|
||||
public class RequireGameCode
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
public RequireGameCode(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (context.Request.Headers.ContainsKey(Api.Headers.GAMECODE))
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,24 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Squiddler_Server_Lite;
|
||||
using Squiddler_Server_Lite.Middleware;
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SupportNonNullableReferenceTypes();
|
||||
options.MapType<GameCode>(() => new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
MinLength = 4,
|
||||
MaxLength = 4,
|
||||
});
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -15,7 +30,74 @@ if (app.Environment.IsDevelopment())
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseWebSockets();
|
||||
|
||||
var apiPrefix = app.MapGroup("/api");
|
||||
|
||||
apiPrefix.MapGet("/test/card/{text}/{value}", Api.GetTestCard)
|
||||
.Produces<Card>(200, "application/json")
|
||||
.WithName("Test_GetCard")
|
||||
.WithOpenApi();
|
||||
|
||||
apiPrefix.MapPost("/create_game", Api.CreateGame)
|
||||
.Produces<GameCode>(200, "text/plain")
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("CreateNewGame")
|
||||
.WithOpenApi();
|
||||
|
||||
var playPrefix = apiPrefix.MapGroup("/play")
|
||||
.WithOpenApi(op =>
|
||||
{
|
||||
OpenApiOperation newOp = new(op);
|
||||
newOp.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Required = true,
|
||||
In = ParameterLocation.Header,
|
||||
Style = ParameterStyle.Simple,
|
||||
AllowEmptyValue = false,
|
||||
Name = Api.Headers.GAMECODE,
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
MaxLength = 4,
|
||||
MinLength = 4
|
||||
},
|
||||
});
|
||||
newOp.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Required = true,
|
||||
In = ParameterLocation.Header,
|
||||
Style = ParameterStyle.Simple,
|
||||
AllowEmptyValue = false,
|
||||
Name = Api.Headers.PLAYERNAME,
|
||||
Schema = new OpenApiSchema { Type = "string" },
|
||||
});
|
||||
return newOp;
|
||||
});
|
||||
|
||||
playPrefix.MapPut("/draw_card", (Delegate)Api.DrawCard)
|
||||
.Produces<Card>(200, "application/json")
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("DrawCard")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapPut("/join_game", (Delegate)Api.JoinGame)
|
||||
.Produces(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.Produces<string>(409, "text/plain")
|
||||
.WithName("JoinGame")
|
||||
.WithOpenApi();
|
||||
|
||||
playPrefix.MapPut("/play_cards", (Delegate)Api.PlayCards)
|
||||
.Produces(200)
|
||||
.Produces<string>(400, "text/plain")
|
||||
.WithName("PlayCards")
|
||||
.WithOpenApi();
|
||||
|
||||
|
||||
app.Run();
|
||||
|
||||
/*
|
||||
var summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
@@ -36,9 +118,8 @@ app.MapGet("/weatherforecast", () =>
|
||||
.WithName("GetWeatherForecast")
|
||||
.WithOpenApi();
|
||||
|
||||
app.Run();
|
||||
|
||||
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
|
||||
{
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
<RootNamespace>Squiddler_Server_Lite</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\.editorconfig" Link=".editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
|
||||
89
Squiddler-Server-Lite/StateObjects/GameState.cs
Normal file
89
Squiddler-Server-Lite/StateObjects/GameState.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
|
||||
namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public class GameState
|
||||
{
|
||||
public GameCode gameCode { get; set; }
|
||||
public string gameName { get; set; }
|
||||
public readonly int FIRST_ROUND;
|
||||
public readonly int LAST_ROUND;
|
||||
public int round { get; set; }
|
||||
public List<UserState> users { get; set; }
|
||||
public int activePlayer { get; set; }
|
||||
public List<Card> discard { get; set; } = new();
|
||||
//index of player who first went out, otherwise -1
|
||||
public int playerWentOut { get; set; } = -1;
|
||||
#region TURNSTATE
|
||||
public bool playerDrew { get; set; }
|
||||
#endregion
|
||||
public void AddToDiscard(Card card)
|
||||
{
|
||||
discard.Add(new Card(card));
|
||||
}
|
||||
public Card PlayerTakesFromDiscard()
|
||||
{
|
||||
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());
|
||||
public JoinGameResult JoinGame(string playerName)
|
||||
{
|
||||
if (users.Any(u => u.userName == playerName))
|
||||
return JoinGameResult.AlreadyJoined;
|
||||
//kind of an abuse of Any() to have side effects
|
||||
return users.Any(u => u.TryJoin(playerName))
|
||||
? JoinGameResult.Success : JoinGameResult.Full;
|
||||
}
|
||||
public UserState ActivePlayer()
|
||||
{
|
||||
return users[activePlayer];
|
||||
}
|
||||
public bool Started()
|
||||
{
|
||||
return round > 0;
|
||||
}
|
||||
private GameState(int firstRound, int lastRound)
|
||||
{
|
||||
FIRST_ROUND = firstRound;
|
||||
LAST_ROUND = lastRound;
|
||||
}
|
||||
public static GameState Create(NewGameConfiguration config)
|
||||
{
|
||||
GameState gameState = new(config.firstRound, config.lastRound)
|
||||
{
|
||||
gameCode = GameCode.CreateRandom(),
|
||||
gameName = config.gameName,
|
||||
users = Enumerable.Range(0, config.playerCount)
|
||||
.Select(i => new UserState()).ToList(),
|
||||
};
|
||||
ActiveStates.Add(gameState);
|
||||
return gameState;
|
||||
}
|
||||
private static readonly List<GameState> ActiveStates = new();
|
||||
public static GameState? FindGame(GameCode gameCode)
|
||||
{
|
||||
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)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public enum JoinGameResult
|
||||
{
|
||||
Success,
|
||||
Full,
|
||||
AlreadyJoined,
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Squiddler-Server-Lite/StateObjects/PlayAreaState.cs
Normal file
17
Squiddler-Server-Lite/StateObjects/PlayAreaState.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
|
||||
namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public class PlayAreaState
|
||||
{
|
||||
public readonly List<Card>[] rows =
|
||||
{
|
||||
new(), new(), new(), new(), new(),
|
||||
};
|
||||
//calculates sum of values of played cards
|
||||
public int baseScore()
|
||||
{
|
||||
return rows.Sum(r => r.Sum(c => c.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Squiddler-Server-Lite/StateObjects/UserState.cs
Normal file
19
Squiddler-Server-Lite/StateObjects/UserState.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Squiddler_Server_Lite.TransferObjects;
|
||||
|
||||
namespace Squiddler_Server_Lite.StateObjects
|
||||
{
|
||||
public class UserState
|
||||
{
|
||||
public string? userName { get; set; }
|
||||
public List<Card> hand { get; } = new();
|
||||
public bool TryJoin(string userName)
|
||||
{
|
||||
if (this.userName is null)
|
||||
{
|
||||
this.userName = userName;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Squiddler-Server-Lite/TransferObjects/Card.cs
Normal file
38
Squiddler-Server-Lite/TransferObjects/Card.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class Card : IComparable<Card>
|
||||
{
|
||||
public string text { get; set; }
|
||||
public int value { get; set; }
|
||||
public override string ToString()
|
||||
=> $"[\"{text}\": {value}";
|
||||
public Card(string text, int value)
|
||||
{
|
||||
this.text = FixCaps(text) ?? throw new ArgumentNullException(nameof(text));
|
||||
this.value = value;
|
||||
}
|
||||
public Card(Card card)
|
||||
{
|
||||
text = card.text;
|
||||
value = card.value;
|
||||
}
|
||||
//fixes text so first letter is capitalized and the rest are lower
|
||||
//behavior undefined is text contains characters other than ASCII letters
|
||||
public static string FixCaps(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return text;
|
||||
return text[..1].ToUpper() + text[1..].ToLower();
|
||||
}
|
||||
|
||||
public int CompareTo(Card? other)
|
||||
{
|
||||
if (other is null)
|
||||
return 1;
|
||||
var sCmp = text.CompareTo(other.text);
|
||||
if (sCmp == 0)
|
||||
return value.CompareTo(other.value);
|
||||
return sCmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Squiddler-Server-Lite/TransferObjects/GameCode.cs
Normal file
71
Squiddler-Server-Lite/TransferObjects/GameCode.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
//[KnownType(typeof(GameCode))]
|
||||
public class GameCode
|
||||
{
|
||||
const string ALLOWED_CHARS = "ABCDEFGHIJKLMNPQRSTVWXYZ";
|
||||
public const int LENGTH = 4;
|
||||
[StringLength(LENGTH, MinimumLength = LENGTH)]
|
||||
public string code { get; set; }
|
||||
private GameCode(string code)
|
||||
{
|
||||
this.code = code ?? throw new ArgumentNullException(nameof(code));
|
||||
}
|
||||
public static GameCode CreateRandom()
|
||||
{
|
||||
var stringChars = new char[LENGTH];
|
||||
for (int i = 0; i < stringChars.Length; i++)
|
||||
stringChars[i] = ALLOWED_CHARS[Random.Shared.Next(ALLOWED_CHARS.Length)];
|
||||
return new GameCode(new string(stringChars));
|
||||
}
|
||||
public static bool TryParse(string text, out GameCode gameCode)
|
||||
{
|
||||
gameCode = new GameCode(text);
|
||||
return gameCode.Validate();
|
||||
}
|
||||
public static implicit operator string(GameCode gameCode)
|
||||
=> gameCode.code;
|
||||
public static bool operator ==(GameCode first, GameCode second)
|
||||
=> first.code == second.code;
|
||||
public static bool operator !=(GameCode first, GameCode second)
|
||||
=> !(first == second);
|
||||
public bool Validate()
|
||||
{
|
||||
return code?.All(ALLOWED_CHARS.Contains) ?? false;
|
||||
}
|
||||
public class GameCodeConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof(string))
|
||||
return true;
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
|
||||
{
|
||||
if (value is string v)
|
||||
{
|
||||
var code = new GameCode(v);
|
||||
if (code.Validate())
|
||||
return code;
|
||||
}
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
if (value is GameCode gameCode)
|
||||
return gameCode.code;
|
||||
return base.ConvertTo(context, culture, value, destinationType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class NewGameConfiguration
|
||||
{
|
||||
public const int MIN_PLAYERS = 2;
|
||||
public const int MAX_PLAYERS = 6;
|
||||
public string gameName { get; set; }
|
||||
[Range(MIN_PLAYERS, MAX_PLAYERS)]
|
||||
public int playerCount { get; set; }
|
||||
[DefaultValue(3)]
|
||||
public int firstRound { get; set; }
|
||||
[DefaultValue(10)]
|
||||
public int lastRound { get; set; }
|
||||
public NewGameConfiguration(string gameName, int playerCount,
|
||||
int firstRound = 3, int lastRound = 10)
|
||||
{
|
||||
this.gameName = gameName ?? throw new ArgumentNullException(nameof(gameName));
|
||||
this.playerCount = playerCount;
|
||||
this.firstRound = firstRound;
|
||||
this.lastRound = lastRound;
|
||||
}
|
||||
public bool Validate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(gameName))
|
||||
return false;
|
||||
if (playerCount > MAX_PLAYERS || playerCount < MIN_PLAYERS)
|
||||
return false;
|
||||
if (lastRound < firstRound)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Squiddler-Server-Lite/TransferObjects/PlayedCards.cs
Normal file
32
Squiddler-Server-Lite/TransferObjects/PlayedCards.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Squiddler_Server_Lite.TransferObjects
|
||||
{
|
||||
public class PlayedCards
|
||||
{
|
||||
public List<Card> word1 { get; set; }
|
||||
public List<Card> word2 { get; set; }
|
||||
public List<Card> word3 { get; set; }
|
||||
public List<Card> word4 { get; set; }
|
||||
public List<Card> word5 { get; set; }
|
||||
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);
|
||||
public PlayedCards(IEnumerable<Card> word1,
|
||||
IEnumerable<Card> word2,
|
||||
IEnumerable<Card> word3,
|
||||
IEnumerable<Card> word4,
|
||||
IEnumerable<Card> word5,
|
||||
IEnumerable<Card> unplayed,
|
||||
Card discarded)
|
||||
{
|
||||
this.word1 = word1.ToList();
|
||||
this.word2 = word2.ToList();
|
||||
this.word3 = word3.ToList();
|
||||
this.word4 = word4.ToList();
|
||||
this.word5 = word5.ToList();
|
||||
this.unplayed = unplayed.ToList();
|
||||
this.discarded = discarded;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user