From 24b155e9a9d854836dedc5fffe6bc99364088d0a Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 17 Mar 2024 22:43:37 +0100 Subject: [PATCH 1/4] Engine: Improve CardList initialization code --- BinaryMatrixEngine/CardList.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/BinaryMatrixEngine/CardList.cs b/BinaryMatrixEngine/CardList.cs index 07cbd37..6395be3 100644 --- a/BinaryMatrixEngine/CardList.cs +++ b/BinaryMatrixEngine/CardList.cs @@ -34,6 +34,12 @@ public CardList(int initialCapacity) { this.cards = listPool.Rent(initialCapacity); } + private static (Card[] storage, int count) CreateListFromCollection(ICollection cardList) { + Card[] storage = listPool.Rent(cardList.Count); + cardList.CopyTo(storage, 0); + return (storage, cardList.Count); + } + public CardList(IEnumerable cards) { if(cards is CardList list) { this.cards = listPool.Rent(list.Count); @@ -41,10 +47,7 @@ public CardList(IEnumerable cards) { return; } - Card[] theCards = cards.ToArray(); - this.cards = listPool.Rent(theCards.Length); - Array.Copy(theCards, this.cards, theCards.Length); - this.Count = theCards.Length; + (this.cards, this.Count) = CreateListFromCollection(cards as ICollection ?? cards.ToArray()); if(FAIL_FAST_INVALID) { foreach(ref Card card in this) { if(card.IsInvalid) @@ -54,9 +57,7 @@ public CardList(IEnumerable cards) { } public CardList(IList cards) { - this.cards = listPool.Rent(cards.Count); - cards.CopyTo(this.cards, 0); - this.Count = this.cards.Length; + (this.cards, this.Count) = CreateListFromCollection(cards); if(FAIL_FAST_INVALID) { foreach(ref Card card in this) { if(card.IsInvalid) From 22cc75c4ca721727c787efafd393990445ca3f9b Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 17 Mar 2024 22:46:39 +0100 Subject: [PATCH 2/4] Engine: Use ImmutableList in GameBoard --- BinaryMatrixEngine/GameBoard.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BinaryMatrixEngine/GameBoard.cs b/BinaryMatrixEngine/GameBoard.cs index dbf9710..ebee0b7 100644 --- a/BinaryMatrixEngine/GameBoard.cs +++ b/BinaryMatrixEngine/GameBoard.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using Fayti1703.CommonLib.Enumeration; using JetBrains.Annotations; @@ -84,7 +85,7 @@ public sealed class GameBoard : IDisposable { private readonly IReadOnlyList cells; public GameBoard() { - this.cells = Enum.GetValues().Select(x => new Cell(x)).ToList(); + this.cells = Enum.GetValues().Select(x => new Cell(x)).ToImmutableList(); } public Cell GetCell(CellName name) { From 67796627b4d99e38e007f22e27d41b002f169326 Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 17 Mar 2024 22:50:42 +0100 Subject: [PATCH 3/4] Engine: Add GameBoard serialization/deserialization into stack list --- BinaryMatrixEngine/GameBoard.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/BinaryMatrixEngine/GameBoard.cs b/BinaryMatrixEngine/GameBoard.cs index ebee0b7..5d84679 100644 --- a/BinaryMatrixEngine/GameBoard.cs +++ b/BinaryMatrixEngine/GameBoard.cs @@ -27,6 +27,11 @@ internal Cell(CellName name) { }); } + internal Cell(CellName name, IEnumerable cards) { + this.name = name; + this.cards = new CardList(cards); + } + public bool Revealed { get => this.name switch { >= X0 and <= X5 => true, @@ -88,6 +93,11 @@ public GameBoard() { this.cells = Enum.GetValues().Select(x => new Cell(x)).ToImmutableList(); } + public GameBoard(IReadOnlyCollection> stacks) { + if(stacks.Count != Enum.GetValues().Length) throw new ArgumentException("Invalid number of stacks", nameof(stacks)); + this.cells = stacks.Select((x, i) => new Cell((CellName) i, x)).ToImmutableList(); + } + public Cell GetCell(CellName name) { return this.cells[(int) name]; } @@ -116,6 +126,8 @@ public GameBoard Copy() { return newBoard; } + public IReadOnlyList> GetStacks() => this.cells.Select(x => x.cards).ToImmutableList(); + public void Dispose() { foreach(Cell cell in this.cells) { cell.Dispose(); From 7c93a454b9374cacb0e62f4e1fbc4e56e94ff90a Mon Sep 17 00:00:00 2001 From: Fayti1703 Date: Sun, 17 Mar 2024 22:53:12 +0100 Subject: [PATCH 4/4] Engine: Move GameState away from GameBoard GameState is meant to be an immutable structure and GameBoard is very, very mutable --- BinaryMatrixEngine/GameContext.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BinaryMatrixEngine/GameContext.cs b/BinaryMatrixEngine/GameContext.cs index 94c2a83..c2d2b59 100644 --- a/BinaryMatrixEngine/GameContext.cs +++ b/BinaryMatrixEngine/GameContext.cs @@ -5,7 +5,7 @@ namespace BinaryMatrix.Engine; public readonly struct GameState { public readonly int turnCounter; - public readonly GameBoard board; + public readonly IReadOnlyList> board; public readonly IReadOnlyList players; public readonly PlayerRole? victor; public readonly IReadOnlyList binlog; @@ -13,7 +13,7 @@ public readonly struct GameState { public GameState( int turnCounter, IReadOnlyList players, - GameBoard board, + IReadOnlyList> board, PlayerRole? victor, IReadOnlyList binlog ) { @@ -75,7 +75,7 @@ public GameContext(IEnumerable players, RNG rng, GameHooks hooks) : this(players, rng, hooks, new GameBoard(), new List()) { } public GameContext(GameState state, IReadOnlyDictionary actors, RNG rng, GameHooks hooks) - : this(state.CreatePlayers(actors), rng, hooks, state.board.Copy(), new List(state.binlog)) { + : this(state.CreatePlayers(actors), rng, hooks, new GameBoard(state.board), new List(state.binlog)) { this.TurnCounter = state.turnCounter; this.Victor = state.victor; } @@ -98,7 +98,7 @@ public GameState SaveState() { return new GameState( this.TurnCounter, this.Players.Select(x => x.data.Copy()).ToImmutableList(), - this.board.Copy(), + this.board.GetStacks(), this.Victor, this.binlog.ToImmutableList() );