Saving snapshots

This commit is contained in:
2024-11-09 13:35:39 -06:00
parent 0a62eb7582
commit 13e79eb490
14 changed files with 176 additions and 16 deletions

View File

@@ -0,0 +1,34 @@
namespace Shogi.Api.Repositories.Dto.SessionState;
public class Piece
{
public bool IsPromoted { get; set; }
public WhichPiece WhichPiece { get; set; }
public WhichPlayer Owner { get; set; }
public Piece() { }
public Piece(Domain.ValueObjects.Piece piece)
{
IsPromoted = piece.IsPromoted;
WhichPiece = piece.WhichPiece switch
{
Domain.ValueObjects.WhichPiece.Bishop => WhichPiece.Bishop,
Domain.ValueObjects.WhichPiece.GoldGeneral => WhichPiece.GoldGeneral,
Domain.ValueObjects.WhichPiece.King => WhichPiece.King,
Domain.ValueObjects.WhichPiece.SilverGeneral => WhichPiece.SilverGeneral,
Domain.ValueObjects.WhichPiece.Rook => WhichPiece.Rook,
Domain.ValueObjects.WhichPiece.Knight => WhichPiece.Knight,
Domain.ValueObjects.WhichPiece.Lance => WhichPiece.Lance,
Domain.ValueObjects.WhichPiece.Pawn => WhichPiece.Pawn,
_ => throw new NotImplementedException()
};
Owner = piece.Owner switch
{
Domain.ValueObjects.WhichPlayer.Player1 => WhichPlayer.Player1,
Domain.ValueObjects.WhichPlayer.Player2 => WhichPlayer.Player2,
_ => throw new NotImplementedException()
};
}
}

View File

@@ -0,0 +1,69 @@
namespace Shogi.Api.Repositories.Dto.SessionState;
public class SessionStateDocument
{
public long Id { get; set; }
public Dictionary<string, Piece?> Board { get; set; }
public WhichPiece[] Player1Hand { get; set; }
public WhichPiece[] Player2Hand { get; set; }
public WhichPlayer? PlayerInCheck { get; set; }
public WhichPlayer WhoseTurn { get; set; }
public bool IsGameOver { get; set; }
public string DocumentVersion { get; set; } = "1";
public SessionStateDocument() { }
public SessionStateDocument(Domain.ValueObjects.BoardState boardState)
{
this.Board = boardState.State.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value == null ? null : new Piece(kvp.Value));
this.Player1Hand = boardState.Player1Hand
.Select(piece => Map(piece.WhichPiece))
.ToArray();
this.Player2Hand = boardState.Player2Hand
.Select(piece => Map(piece.WhichPiece))
.ToArray();
this.PlayerInCheck = boardState.InCheck.HasValue
? Map(boardState.InCheck.Value)
: null;
this.IsGameOver = boardState.IsCheckmate;
}
static WhichPiece Map(Domain.ValueObjects.WhichPiece whichPiece)
{
return whichPiece switch
{
Domain.ValueObjects.WhichPiece.Bishop => WhichPiece.Bishop,
Domain.ValueObjects.WhichPiece.GoldGeneral => WhichPiece.GoldGeneral,
Domain.ValueObjects.WhichPiece.King => WhichPiece.King,
Domain.ValueObjects.WhichPiece.SilverGeneral => WhichPiece.SilverGeneral,
Domain.ValueObjects.WhichPiece.Rook => WhichPiece.Rook,
Domain.ValueObjects.WhichPiece.Knight => WhichPiece.Knight,
Domain.ValueObjects.WhichPiece.Lance => WhichPiece.Lance,
Domain.ValueObjects.WhichPiece.Pawn => WhichPiece.Pawn,
_ => throw new NotImplementedException()
};
}
static WhichPlayer Map(Domain.ValueObjects.WhichPlayer whichPlayer)
{
return whichPlayer switch
{
Domain.ValueObjects.WhichPlayer.Player1 => WhichPlayer.Player1,
Domain.ValueObjects.WhichPlayer.Player2 => WhichPlayer.Player2,
_ => throw new NotImplementedException()
};
}
}

View File

@@ -0,0 +1,13 @@
namespace Shogi.Api.Repositories.Dto.SessionState;
public enum WhichPiece
{
King,
GoldGeneral,
SilverGeneral,
Bishop,
Rook,
Knight,
Lance,
Pawn
}

View File

@@ -0,0 +1,7 @@
namespace Shogi.Api.Repositories.Dto.SessionState;
public enum WhichPlayer
{
Player1,
Player2
}

View File

@@ -1,9 +1,11 @@
using Dapper;
using Shogi.Api.Repositories.Dto;
using Shogi.Api.Repositories.Dto.SessionState;
using Shogi.Contracts.Api.Commands;
using Shogi.Domain.Aggregates;
using System.Data;
using System.Data.SqlClient;
using System.Text.Json;
namespace Shogi.Api.Repositories;
@@ -81,4 +83,19 @@ public class SessionRepository(IConfiguration configuration)
},
commandType: CommandType.StoredProcedure);
}
public async Task CreateState(Session session)
{
var document = new SessionStateDocument(session.Board.BoardState);
using var connection = new SqlConnection(this.connectionString);
await connection.ExecuteAsync(
"session.CreateState",
new
{
SessionId = session.Id.ToString(),
Document = JsonSerializer.Serialize(document)
},
commandType: CommandType.StoredProcedure);
}
}