yep
This commit is contained in:
@@ -68,7 +68,7 @@ public class SessionsController : ControllerBase
|
|||||||
return this.NoContent();
|
return this.NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.Forbid("Cannot delete sessions created by others.");
|
return this.StatusCode(StatusCodes.Status403Forbidden, "Cannot delete sessions created by others.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("PlayerCount")]
|
[HttpGet("PlayerCount")]
|
||||||
@@ -108,15 +108,15 @@ public class SessionsController : ControllerBase
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPatch("{name}/Move")]
|
[HttpPatch("{sessionName}/Move")]
|
||||||
public async Task<IActionResult> Move([FromRoute] string name, [FromBody] MovePieceCommand command)
|
public async Task<IActionResult> Move([FromRoute] string sessionName, [FromBody] MovePieceCommand command)
|
||||||
{
|
{
|
||||||
var userId = User.GetShogiUserId();
|
var userId = User.GetShogiUserId();
|
||||||
var session = await sessionRepository.ReadSession(name);
|
var session = await sessionRepository.ReadSession(sessionName);
|
||||||
|
|
||||||
if (session == null) return this.NotFound("Shogi session does not exist.");
|
if (session == null) return this.NotFound("Shogi session does not exist.");
|
||||||
|
|
||||||
if (!session.IsSeated(userId)) return this.Forbid("Player is not a member of the Shogi session.");
|
if (!session.IsSeated(userId)) return this.StatusCode(StatusCodes.Status403Forbidden, "Player is not a member of the Shogi session.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -126,14 +126,14 @@ public class SessionsController : ControllerBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
session.Board.Move(command.From!, command.To, command.IsPromotion!.Value);
|
session.Board.Move(command.From!, command.To, command.IsPromotion ?? false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException)
|
catch (InvalidOperationException e)
|
||||||
{
|
{
|
||||||
return this.Conflict("Move is illegal.");
|
return this.Conflict(e.Message);
|
||||||
}
|
}
|
||||||
// TODO: sessionRespository.SaveMove();
|
await sessionRepository.CreateMove(sessionName, command);
|
||||||
await communicationManager.BroadcastToPlayers(
|
await communicationManager.BroadcastToPlayers(
|
||||||
new PlayerHasMovedMessage
|
new PlayerHasMovedMessage
|
||||||
{
|
{
|
||||||
@@ -145,73 +145,4 @@ public class SessionsController : ControllerBase
|
|||||||
|
|
||||||
return this.NoContent();
|
return this.NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
//[HttpPost("{sessionName}/Move")]
|
|
||||||
//public async Task<IActionResult> MovePiece([FromRoute] string sessionName, [FromBody] MovePieceCommand request)
|
|
||||||
//{
|
|
||||||
|
|
||||||
// var user = await gameboardManager.ReadUser(User);
|
|
||||||
// var session = await gameboardRepository.ReadSession(sessionName);
|
|
||||||
// if (session == null)
|
|
||||||
// {
|
|
||||||
// return NotFound();
|
|
||||||
// }
|
|
||||||
// if (user == null || (session.Player1 != user.Id && session.Player2 != user.Id))
|
|
||||||
// {
|
|
||||||
// return Forbid("User is not seated at this game.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// var move = request.Move;
|
|
||||||
// if (move.PieceFromCaptured.HasValue)
|
|
||||||
// session.Move(mapper.Map(move.PieceFromCaptured.Value), move.To);
|
|
||||||
// else if (!string.IsNullOrWhiteSpace(move.From))
|
|
||||||
// session.Move(move.From, move.To, move.IsPromotion);
|
|
||||||
|
|
||||||
// await gameboardRepository.CreateBoardState(session);
|
|
||||||
// await communicationManager.BroadcastToPlayers(
|
|
||||||
// new MoveResponse
|
|
||||||
// {
|
|
||||||
// SessionName = session.Name,
|
|
||||||
// PlayerName = user.Id
|
|
||||||
// },
|
|
||||||
// session.Player1,
|
|
||||||
// session.Player2);
|
|
||||||
|
|
||||||
// return Ok();
|
|
||||||
// }
|
|
||||||
// catch (InvalidOperationException ex)
|
|
||||||
// {
|
|
||||||
// return Conflict(ex.Message);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//[HttpPut("{sessionName}")]
|
|
||||||
//public async Task<IActionResult> PutJoinSession([FromRoute] string sessionName)
|
|
||||||
//{
|
|
||||||
// var user = await ReadUserOrThrow();
|
|
||||||
// var session = await gameboardRepository.ReadSessionMetaData(sessionName);
|
|
||||||
// if (session == null)
|
|
||||||
// {
|
|
||||||
// return NotFound();
|
|
||||||
// }
|
|
||||||
// if (session.Player2 != null)
|
|
||||||
// {
|
|
||||||
// return this.Conflict("This session already has two seated players and is full.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// session.SetPlayer2(user.Id);
|
|
||||||
// await gameboardRepository.UpdateSession(session);
|
|
||||||
|
|
||||||
// var opponentName = user.Id == session.Player1
|
|
||||||
// ? session.Player2!
|
|
||||||
// : session.Player1;
|
|
||||||
// await communicationManager.BroadcastToPlayers(new JoinSessionResponse
|
|
||||||
// {
|
|
||||||
// SessionName = session.Name,
|
|
||||||
// PlayerName = user.Id
|
|
||||||
// }, opponentName);
|
|
||||||
// return Ok();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace Shogi.Api.Models;
|
|||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
public static readonly ReadOnlyCollection<string> Adjectives = new(new[] {
|
public static readonly ReadOnlyCollection<string> Adjectives = new(new[] {
|
||||||
"Fortuitous", "Retractable", "Happy", "Habbitable", "Creative", "Fluffy", "Impervious", "Kingly"
|
"Fortuitous", "Retractable", "Happy", "Habbitable", "Creative", "Fluffy", "Impervious", "Kingly", "Queenly", "Blushing", "Brave",
|
||||||
|
"Brainy", "Eager", "Itchy", "Fierce"
|
||||||
});
|
});
|
||||||
public static readonly ReadOnlyCollection<string> Subjects = new(new[] {
|
public static readonly ReadOnlyCollection<string> Subjects = new(new[] {
|
||||||
"Hippo", "Basil", "Mouse", "Walnut", "Prince", "Lima Bean", "Coala", "Potato", "Penguin"
|
"Hippo", "Basil", "Mouse", "Walnut", "Minstrel", "Lima Bean", "Koala", "Potato", "Penguin", "Cola", "Banana", "Egg", "Fish", "Yak"
|
||||||
});
|
});
|
||||||
public static User CreateMsalUser(string id) => new(id, id, WhichLoginPlatform.Microsoft);
|
public static User CreateMsalUser(string id) => new(id, id, WhichLoginPlatform.Microsoft);
|
||||||
public static User CreateGuestUser(string id)
|
public static User CreateGuestUser(string id)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
using Shogi.Api.Extensions;
|
|
||||||
using Shogi.Api.Repositories.Dto;
|
using Shogi.Api.Repositories.Dto;
|
||||||
|
using Shogi.Contracts.Api;
|
||||||
using Shogi.Domain;
|
using Shogi.Domain;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
@@ -74,9 +74,11 @@ public class SessionRepository : ISessionRepository
|
|||||||
"session.CreateMove",
|
"session.CreateMove",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
To = command.To,
|
command.To,
|
||||||
From = command.From,
|
command.From,
|
||||||
IsPromotion = command.IsPromotion
|
command.IsPromotion,
|
||||||
|
command.PieceFromHand,
|
||||||
|
SessionName = sessionName
|
||||||
},
|
},
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
}
|
}
|
||||||
@@ -84,6 +86,7 @@ public class SessionRepository : ISessionRepository
|
|||||||
|
|
||||||
public interface ISessionRepository
|
public interface ISessionRepository
|
||||||
{
|
{
|
||||||
|
Task CreateMove(string sessionName, MovePieceCommand command);
|
||||||
Task CreateSession(Session session);
|
Task CreateSession(Session session);
|
||||||
Task DeleteSession(string name);
|
Task DeleteSession(string name);
|
||||||
Task<Session?> ReadSession(string name);
|
Task<Session?> ReadSession(string name);
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ Post-Deployment Script Template
|
|||||||
|
|
||||||
:r .\Scripts\PopulateLoginPlatforms.sql
|
:r .\Scripts\PopulateLoginPlatforms.sql
|
||||||
:r .\Scripts\PopulatePieces.sql
|
:r .\Scripts\PopulatePieces.sql
|
||||||
|
:r .\Scripts\EnableSnapshotIsolationLevel.sql
|
||||||
@@ -2,8 +2,31 @@
|
|||||||
@To VARCHAR(2),
|
@To VARCHAR(2),
|
||||||
@From VARCHAR(2),
|
@From VARCHAR(2),
|
||||||
@IsPromotion BIT,
|
@IsPromotion BIT,
|
||||||
@PieceName NVARCHAR(13),
|
@PieceFromHand NVARCHAR(13),
|
||||||
@SessionName [session].[SessionName]
|
@SessionName [session].[SessionName]
|
||||||
AS
|
AS
|
||||||
|
|
||||||
INSERT INTO [session].[Move]
|
BEGIN
|
||||||
|
SET NOCOUNT ON -- Performance boost
|
||||||
|
SET XACT_ABORT ON -- Rollback transaction on error
|
||||||
|
SET TRANSACTION ISOLATION LEVEL SNAPSHOT -- Ignores data changes that happen after the transaction begins.
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
DECLARE @SessionId BIGINT = 0;
|
||||||
|
SELECT @SessionId = Id
|
||||||
|
FROM [session].[Session]
|
||||||
|
WHERE [Name] = @SessionName;
|
||||||
|
|
||||||
|
DECLARE @PieceIdFromhand INT = NULL;
|
||||||
|
SELECT @PieceIdFromhand
|
||||||
|
FROM [session].[Piece]
|
||||||
|
WHERE [Name] = @PieceFromHand;
|
||||||
|
|
||||||
|
INSERT INTO [session].[Move]
|
||||||
|
(SessionId, [To], [From], IsPromotion, PieceIdFromHand)
|
||||||
|
VALUES
|
||||||
|
(@SessionId, @To, @From, @IsPromotion, @PieceIdFromhand);
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
END
|
||||||
@@ -10,6 +10,6 @@ public interface IShogiApi
|
|||||||
Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount();
|
Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount();
|
||||||
Task<CreateTokenResponse?> GetToken();
|
Task<CreateTokenResponse?> GetToken();
|
||||||
Task GuestLogout();
|
Task GuestLogout();
|
||||||
Task PostMove(string sessionName, Move move);
|
Task PostMove(string sessionName, MovePieceCommand move);
|
||||||
Task<HttpStatusCode> PostSession(string name, bool isPrivate);
|
Task<HttpStatusCode> PostSession(string name, bool isPrivate);
|
||||||
}
|
}
|
||||||
@@ -63,9 +63,9 @@ namespace Shogi.UI.Pages.Home.Api
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PostMove(string sessionName, Contracts.Types.Move move)
|
public async Task PostMove(string sessionName, MovePieceCommand command)
|
||||||
{
|
{
|
||||||
await this.HttpClient.PostAsJsonAsync($"Sessions{sessionName}/Move", new MovePieceCommand { Move = move });
|
await this.HttpClient.PostAsJsonAsync($"Sessions{sessionName}/Move", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HttpStatusCode> PostSession(string name, bool isPrivate)
|
public async Task<HttpStatusCode> PostSession(string name, bool isPrivate)
|
||||||
|
|||||||
@@ -2,15 +2,21 @@
|
|||||||
@inject IShogiApi ShogiApi
|
@inject IShogiApi ShogiApi
|
||||||
@inject AccountState Account;
|
@inject AccountState Account;
|
||||||
|
|
||||||
<section class="game-board" data-perspective="@Perspective">
|
<article class="game-board">
|
||||||
@for (var rank = 9; rank > 0; rank--)
|
<!-- Game board -->
|
||||||
|
<section class="board" data-perspective="@Perspective">
|
||||||
|
@for (var rank = 1; rank < 10; rank++)
|
||||||
{
|
{
|
||||||
foreach (var file in Files)
|
foreach (var file in Files)
|
||||||
{
|
{
|
||||||
var position = $"{file}{rank}";
|
var position = $"{file}{rank}";
|
||||||
var piece = session?.BoardState.Board[position];
|
var piece = session?.BoardState.Board[position];
|
||||||
<div class="tile" data-position="@(position)" style="grid-area: @(position)" @onclick="() => OnClickTile(piece, position)">
|
<div class="tile"
|
||||||
<GamePiece Piece="piece" Perspective="@Perspective" />
|
data-position="@(position)"
|
||||||
|
data-selected="@(piece != null && selectedPosition == position)"
|
||||||
|
style="grid-area: @(position)"
|
||||||
|
@onclick="() => OnClickTile(piece, position)">
|
||||||
|
<GamePiece Piece="piece" Perspective="Perspective" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,16 +42,69 @@
|
|||||||
<span>H</span>
|
<span>H</span>
|
||||||
<span>I</span>
|
<span>I</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<!-- Side board -->
|
||||||
|
@if (session != null)
|
||||||
|
{
|
||||||
|
<aside class="side-board">
|
||||||
|
<div class="hand">
|
||||||
|
@foreach (var piece in OpponentHand)
|
||||||
|
{
|
||||||
|
<div class="tile">
|
||||||
|
<GamePiece Piece="piece" Perspective="Perspective" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer" />
|
||||||
|
|
||||||
|
<div class="hand">
|
||||||
|
@foreach (var piece in UserHand)
|
||||||
|
{
|
||||||
|
<div class="title" @onclick="() => OnClickHand(piece)">
|
||||||
|
<GamePiece Piece="piece" Perspective="Perspective" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
}
|
||||||
|
</article>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string? SessionName { get; set; }
|
public string? SessionName { get; set; }
|
||||||
static readonly string[] Files = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };
|
|
||||||
WhichPlayer Perspective => Account.User?.Id == session?.Player1 ? WhichPlayer.Player1 : WhichPlayer.Player2;
|
|
||||||
|
|
||||||
|
static readonly string[] Files = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };
|
||||||
|
WhichPlayer Perspective => Account.User?.Id == session?.Player1
|
||||||
|
? WhichPlayer.Player1
|
||||||
|
: WhichPlayer.Player2;
|
||||||
Session? session;
|
Session? session;
|
||||||
|
IReadOnlyCollection<Piece> OpponentHand
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.session == null) return Array.Empty<Piece>();
|
||||||
|
|
||||||
|
return Perspective == WhichPlayer.Player1
|
||||||
|
? this.session.BoardState.Player1Hand
|
||||||
|
: this.session.BoardState.Player2Hand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IReadOnlyCollection<Piece> UserHand
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.session == null) return Array.Empty<Piece>();
|
||||||
|
|
||||||
|
return Perspective == WhichPlayer.Player1
|
||||||
|
? this.session.BoardState.Player1Hand
|
||||||
|
: this.session.BoardState.Player2Hand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
string? selectedPosition;
|
string? selectedPosition;
|
||||||
|
WhichPiece? selectedPiece;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
@@ -57,6 +116,28 @@
|
|||||||
|
|
||||||
void OnClickTile(Piece? piece, string position)
|
void OnClickTile(Piece? piece, string position)
|
||||||
{
|
{
|
||||||
|
if (selectedPosition == null)
|
||||||
|
{
|
||||||
|
selectedPosition = position;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (selectedPosition == position)
|
||||||
|
{
|
||||||
|
selectedPosition = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (piece != null)
|
||||||
|
{
|
||||||
|
ShogiApi.PostMove(SessionName!, new Contracts.Api.MovePieceCommand
|
||||||
|
{
|
||||||
|
From = selectedPosition,
|
||||||
|
To = position,
|
||||||
|
IsP
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OnClickHand(Piece piece)
|
||||||
|
{
|
||||||
|
selectedPiece = piece.WhichPiece;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
.game-board {
|
.game-board {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "board side-board";
|
||||||
|
grid-template-columns: 3fr minmax(10rem, 1fr);
|
||||||
|
gap: 0.5rem;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board {
|
||||||
|
grid-area: board;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-board {
|
||||||
|
grid-area: side-board;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"rank A9 B9 C9 D9 E9 F9 G9 H9 I9"
|
"rank A9 B9 C9 D9 E9 F9 G9 H9 I9"
|
||||||
@@ -20,7 +35,7 @@
|
|||||||
gap: 3px;
|
gap: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-board[data-perspective="Player2"] {
|
.board[data-perspective="Player2"] {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"file file file file file file file file file ."
|
"file file file file file file file file file ."
|
||||||
"I1 H1 G1 F1 E1 D1 C1 B1 A1 rank"
|
"I1 H1 G1 F1 E1 D1 C1 B1 A1 rank"
|
||||||
@@ -41,6 +56,11 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
|
overflow: hidden; /* Because SVGs are shaped weird */
|
||||||
|
transition: filter linear 0.25s;
|
||||||
|
}
|
||||||
|
.tile[data-selected] {
|
||||||
|
filter: invert(0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ruler {
|
.ruler {
|
||||||
@@ -54,10 +74,20 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-board[data-perspective="Player2"] .ruler {
|
.board[data-perspective="Player2"] .ruler {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-board[data-perspective="Player2"] .ruler.vertical {
|
.board[data-perspective="Player2"] .ruler.vertical {
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side-board {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-board .hand {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@using System.Net
|
@using System.Net
|
||||||
@inject IShogiApi ShogiApi;
|
@inject IShogiApi ShogiApi;
|
||||||
@inject ShogiSocket ShogiSocket;
|
@inject ShogiSocket ShogiSocket;
|
||||||
|
@inject AccountState Account;
|
||||||
|
|
||||||
<section class="game-browser">
|
<section class="game-browser">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
@@ -76,8 +77,15 @@
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
ShogiSocket.OnCreateGameMessage += async (sender, message) => await FetchSessions();
|
ShogiSocket.OnCreateGameMessage += async (sender, message) => await FetchSessions();
|
||||||
|
Account.LoginChangedEvent += async (sender, message) =>
|
||||||
|
{
|
||||||
|
if (message.User != null)
|
||||||
|
{
|
||||||
await FetchSessions();
|
await FetchSessions();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
string ActiveCss(SessionMetadata s) => s == activeSession ? "active" : string.Empty;
|
string ActiveCss(SessionMetadata s) => s == activeSession ? "active" : string.Empty;
|
||||||
|
|
||||||
void OnClickSession(SessionMetadata s)
|
void OnClickSession(SessionMetadata s)
|
||||||
@@ -92,6 +100,7 @@
|
|||||||
if (sessions != null)
|
if (sessions != null)
|
||||||
{
|
{
|
||||||
this.sessions = sessions.PlayerHasJoinedSessions.Concat(sessions.AllOtherSessions).ToArray();
|
this.sessions = sessions.PlayerHasJoinedSessions.Concat(sessions.AllOtherSessions).ToArray();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ html, body, #app {
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
font-family: cursive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using FluentAssertions.Execution;
|
||||||
using Shogi.AcceptanceTests.TestSetup;
|
using Shogi.AcceptanceTests.TestSetup;
|
||||||
using Shogi.Contracts.Api;
|
using Shogi.Contracts.Api;
|
||||||
using Shogi.Contracts.Types;
|
using Shogi.Contracts.Types;
|
||||||
@@ -28,7 +29,7 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
await CreateSession();
|
await SetupTestSession();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var readAllResponse = await Service
|
var readAllResponse = await Service
|
||||||
@@ -45,17 +46,17 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Annul
|
// Annul
|
||||||
await DeleteSession();
|
await DeleteTestSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CreateAndReadSession()
|
public async Task CreateSession()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
await CreateSession();
|
await SetupTestSession();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Service.GetFromJsonAsync<ReadSessionResponse>(
|
var response = await Service.GetFromJsonAsync<ReadSessionResponse>(
|
||||||
@@ -66,6 +67,7 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
response.Should().NotBeNull();
|
response.Should().NotBeNull();
|
||||||
response!.Session.Should().NotBeNull();
|
response!.Session.Should().NotBeNull();
|
||||||
response.Session.BoardState.Board.Should().NotBeEmpty();
|
response.Session.BoardState.Board.Should().NotBeEmpty();
|
||||||
|
ValidateBoard(response.Session.BoardState.Board);
|
||||||
response.Session.BoardState.Player1Hand.Should().BeEmpty();
|
response.Session.BoardState.Player1Hand.Should().BeEmpty();
|
||||||
response.Session.BoardState.Player2Hand.Should().BeEmpty();
|
response.Session.BoardState.Player2Hand.Should().BeEmpty();
|
||||||
response.Session.BoardState.PlayerInCheck.Should().BeNull();
|
response.Session.BoardState.PlayerInCheck.Should().BeNull();
|
||||||
@@ -77,11 +79,218 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Annul
|
// Annul
|
||||||
await DeleteSession();
|
await DeleteTestSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ValidateBoard(Dictionary<string, Piece?> board)
|
||||||
|
{
|
||||||
|
using var scope = new AssertionScope();
|
||||||
|
board["A1"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
|
board["A1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["A1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["B1"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
|
board["B1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["B1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C1"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
|
board["C1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["C1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["D1"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
|
board["D1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["D1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["E1"]!.WhichPiece.Should().Be(WhichPiece.King);
|
||||||
|
board["E1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["E1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["F1"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
|
board["F1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["F1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["G1"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
|
board["G1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["G1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["H1"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
|
board["H1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["H1"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I1"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
|
board["I1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["I1"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
|
board["A2"].Should().BeNull();
|
||||||
|
board["B2"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
|
||||||
|
board["B2"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["B2"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C2"].Should().BeNull();
|
||||||
|
board["D2"].Should().BeNull();
|
||||||
|
board["E2"].Should().BeNull();
|
||||||
|
board["F2"].Should().BeNull();
|
||||||
|
board["G2"].Should().BeNull();
|
||||||
|
board["H2"]!.WhichPiece.Should().Be(WhichPiece.Rook);
|
||||||
|
board["H2"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["H2"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I2"].Should().BeNull();
|
||||||
|
|
||||||
|
board["A3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["A3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["A3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["B3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["B3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["B3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["C3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["C3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["D3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["D3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["D3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["E3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["E3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["E3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["F3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["F3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["F3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["G3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["G3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["G3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["H3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["H3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["H3"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["I3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
board["I3"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
|
board["A4"].Should().BeNull();
|
||||||
|
board["B4"].Should().BeNull();
|
||||||
|
board["C4"].Should().BeNull();
|
||||||
|
board["D4"].Should().BeNull();
|
||||||
|
board["E4"].Should().BeNull();
|
||||||
|
board["F4"].Should().BeNull();
|
||||||
|
board["G4"].Should().BeNull();
|
||||||
|
board["H4"].Should().BeNull();
|
||||||
|
board["I4"].Should().BeNull();
|
||||||
|
|
||||||
|
board["A5"].Should().BeNull();
|
||||||
|
board["B5"].Should().BeNull();
|
||||||
|
board["C5"].Should().BeNull();
|
||||||
|
board["D5"].Should().BeNull();
|
||||||
|
board["E5"].Should().BeNull();
|
||||||
|
board["F5"].Should().BeNull();
|
||||||
|
board["G5"].Should().BeNull();
|
||||||
|
board["H5"].Should().BeNull();
|
||||||
|
board["I5"].Should().BeNull();
|
||||||
|
|
||||||
|
board["A6"].Should().BeNull();
|
||||||
|
board["B6"].Should().BeNull();
|
||||||
|
board["C6"].Should().BeNull();
|
||||||
|
board["D6"].Should().BeNull();
|
||||||
|
board["E6"].Should().BeNull();
|
||||||
|
board["F6"].Should().BeNull();
|
||||||
|
board["G6"].Should().BeNull();
|
||||||
|
board["H6"].Should().BeNull();
|
||||||
|
board["I6"].Should().BeNull();
|
||||||
|
|
||||||
|
board["A7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["A7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["A7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["B7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["B7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["B7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["C7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["C7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["D7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["D7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["D7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["E7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["E7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["E7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["F7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["F7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["F7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["G7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["G7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["G7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["H7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["H7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["H7"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
board["I7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["I7"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
|
board["A8"].Should().BeNull();
|
||||||
|
board["B8"]!.WhichPiece.Should().Be(WhichPiece.Rook);
|
||||||
|
board["B8"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["B8"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C8"].Should().BeNull();
|
||||||
|
board["D8"].Should().BeNull();
|
||||||
|
board["E8"].Should().BeNull();
|
||||||
|
board["F8"].Should().BeNull();
|
||||||
|
board["G8"].Should().BeNull();
|
||||||
|
board["H8"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
|
||||||
|
board["H8"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["H8"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I8"].Should().BeNull();
|
||||||
|
|
||||||
|
board["A9"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
|
board["A9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["A9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["B9"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
|
board["B9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["B9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["C9"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
|
board["C9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["C9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["D9"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
|
board["D9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["D9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["E9"]!.WhichPiece.Should().Be(WhichPiece.King);
|
||||||
|
board["E9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["E9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["F9"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
|
board["F9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["F9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["G9"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
|
board["G9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["G9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["H9"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
|
board["H9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["H9"]!.IsPromoted.Should().Be(false);
|
||||||
|
board["I9"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
|
board["I9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
|
board["I9"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateSession()
|
[Fact]
|
||||||
|
public async Task MovePieceCommand_MovingPieceFromBoard_MovesThePiece()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
await SetupTestSession();
|
||||||
|
var movePawnCommand = new MovePieceCommand
|
||||||
|
{
|
||||||
|
From = "A3",
|
||||||
|
To = "A4",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await Service.PatchAsync(new Uri("Sessions/Acceptance Tests/Move", UriKind.Relative), JsonContent.Create(movePawnCommand));
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.NoContent, because: await response.Content.ReadAsStringAsync());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var session = (await ReadTestSession()).Session;
|
||||||
|
session.BoardState.Board["A2"].Should().BeNull();
|
||||||
|
session.BoardState.Board["A3"].Should().NotBeNull();
|
||||||
|
session.BoardState.Board["A3"]!.IsPromoted.Should().BeFalse();
|
||||||
|
session.BoardState.Board["A3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
|
session.BoardState.Board["A3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Annul
|
||||||
|
await DeleteTestSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetupTestSession()
|
||||||
{
|
{
|
||||||
var createResponse = await Service.PostAsJsonAsync(
|
var createResponse = await Service.PostAsJsonAsync(
|
||||||
new Uri("Sessions", UriKind.Relative),
|
new Uri("Sessions", UriKind.Relative),
|
||||||
@@ -90,10 +299,15 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
|
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteSession()
|
private Task<ReadSessionResponse> ReadTestSession()
|
||||||
|
{
|
||||||
|
return Service.GetFromJsonAsync<ReadSessionResponse>(new Uri("Sessions/Acceptance Tests", UriKind.Relative))!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteTestSession()
|
||||||
{
|
{
|
||||||
var response = await Service.DeleteAsync(new Uri("Sessions/Acceptance Tests", UriKind.Relative));
|
var response = await Service.DeleteAsync(new Uri("Sessions/Acceptance Tests", UriKind.Relative));
|
||||||
response.StatusCode.Should().Be(HttpStatusCode.NoContent, because: "Test cleanup should succeed");
|
response.StatusCode.Should().Be(HttpStatusCode.NoContent, because: await response.Content.ReadAsStringAsync());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,75 +9,75 @@ public class ShogiBoardStateShould
|
|||||||
var board = BoardState.StandardStarting;
|
var board = BoardState.StandardStarting;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
board["A1"]?.WhichPiece.Should().Be(WhichPiece.Lance);
|
board["A1"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
board["A1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["A1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["A1"]?.IsPromoted.Should().Be(false);
|
board["A1"]!.IsPromoted.Should().Be(false);
|
||||||
board["B1"]?.WhichPiece.Should().Be(WhichPiece.Knight);
|
board["B1"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
board["B1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["B1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["B1"]?.IsPromoted.Should().Be(false);
|
board["B1"]!.IsPromoted.Should().Be(false);
|
||||||
board["C1"]?.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
board["C1"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
board["C1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["C1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["C1"]?.IsPromoted.Should().Be(false);
|
board["C1"]!.IsPromoted.Should().Be(false);
|
||||||
board["D1"]?.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
board["D1"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
board["D1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["D1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["D1"]?.IsPromoted.Should().Be(false);
|
board["D1"]!.IsPromoted.Should().Be(false);
|
||||||
board["E1"]?.WhichPiece.Should().Be(WhichPiece.King);
|
board["E1"]!.WhichPiece.Should().Be(WhichPiece.King);
|
||||||
board["E1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["E1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["E1"]?.IsPromoted.Should().Be(false);
|
board["E1"]!.IsPromoted.Should().Be(false);
|
||||||
board["F1"]?.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
board["F1"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
board["F1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["F1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["F1"]?.IsPromoted.Should().Be(false);
|
board["F1"]!.IsPromoted.Should().Be(false);
|
||||||
board["G1"]?.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
board["G1"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
board["G1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["G1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["G1"]?.IsPromoted.Should().Be(false);
|
board["G1"]!.IsPromoted.Should().Be(false);
|
||||||
board["H1"]?.WhichPiece.Should().Be(WhichPiece.Knight);
|
board["H1"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
board["H1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["H1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["H1"]?.IsPromoted.Should().Be(false);
|
board["H1"]!.IsPromoted.Should().Be(false);
|
||||||
board["I1"]?.WhichPiece.Should().Be(WhichPiece.Lance);
|
board["I1"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
board["I1"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["I1"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["I1"]?.IsPromoted.Should().Be(false);
|
board["I1"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
board["A2"].Should().BeNull();
|
board["A2"].Should().BeNull();
|
||||||
board["B2"]?.WhichPiece.Should().Be(WhichPiece.Bishop);
|
board["B2"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
|
||||||
board["B2"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["B2"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["B2"]?.IsPromoted.Should().Be(false);
|
board["B2"]!.IsPromoted.Should().Be(false);
|
||||||
board["C2"].Should().BeNull();
|
board["C2"].Should().BeNull();
|
||||||
board["D2"].Should().BeNull();
|
board["D2"].Should().BeNull();
|
||||||
board["E2"].Should().BeNull();
|
board["E2"].Should().BeNull();
|
||||||
board["F2"].Should().BeNull();
|
board["F2"].Should().BeNull();
|
||||||
board["G2"].Should().BeNull();
|
board["G2"].Should().BeNull();
|
||||||
board["H2"]?.WhichPiece.Should().Be(WhichPiece.Rook);
|
board["H2"]!.WhichPiece.Should().Be(WhichPiece.Rook);
|
||||||
board["H2"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["H2"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["H2"]?.IsPromoted.Should().Be(false);
|
board["H2"]!.IsPromoted.Should().Be(false);
|
||||||
board["I2"].Should().BeNull();
|
board["I2"].Should().BeNull();
|
||||||
|
|
||||||
board["A3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["A3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["A3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["A3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["A3"]?.IsPromoted.Should().Be(false);
|
board["A3"]!.IsPromoted.Should().Be(false);
|
||||||
board["B3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["B3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["B3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["B3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["B3"]?.IsPromoted.Should().Be(false);
|
board["B3"]!.IsPromoted.Should().Be(false);
|
||||||
board["C3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["C3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["C3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["C3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["C3"]?.IsPromoted.Should().Be(false);
|
board["C3"]!.IsPromoted.Should().Be(false);
|
||||||
board["D3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["D3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["D3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["D3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["D3"]?.IsPromoted.Should().Be(false);
|
board["D3"]!.IsPromoted.Should().Be(false);
|
||||||
board["E3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["E3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["E3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["E3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["E3"]?.IsPromoted.Should().Be(false);
|
board["E3"]!.IsPromoted.Should().Be(false);
|
||||||
board["F3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["F3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["F3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["F3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["F3"]?.IsPromoted.Should().Be(false);
|
board["F3"]!.IsPromoted.Should().Be(false);
|
||||||
board["G3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["G3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["G3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["G3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["G3"]?.IsPromoted.Should().Be(false);
|
board["G3"]!.IsPromoted.Should().Be(false);
|
||||||
board["H3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["H3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["H3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["H3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["H3"]?.IsPromoted.Should().Be(false);
|
board["H3"]!.IsPromoted.Should().Be(false);
|
||||||
board["I3"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["I3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["I3"]?.Owner.Should().Be(WhichPlayer.Player1);
|
board["I3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
board["I3"]?.IsPromoted.Should().Be(false);
|
board["I3"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
board["A4"].Should().BeNull();
|
board["A4"].Should().BeNull();
|
||||||
board["B4"].Should().BeNull();
|
board["B4"].Should().BeNull();
|
||||||
@@ -109,74 +109,74 @@ public class ShogiBoardStateShould
|
|||||||
board["H6"].Should().BeNull();
|
board["H6"].Should().BeNull();
|
||||||
board["I6"].Should().BeNull();
|
board["I6"].Should().BeNull();
|
||||||
|
|
||||||
board["A7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["A7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["A7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["A7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["A7"]?.IsPromoted.Should().Be(false);
|
board["A7"]!.IsPromoted.Should().Be(false);
|
||||||
board["B7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["B7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["B7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["B7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["B7"]?.IsPromoted.Should().Be(false);
|
board["B7"]!.IsPromoted.Should().Be(false);
|
||||||
board["C7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["C7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["C7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["C7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["C7"]?.IsPromoted.Should().Be(false);
|
board["C7"]!.IsPromoted.Should().Be(false);
|
||||||
board["D7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["D7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["D7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["D7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["D7"]?.IsPromoted.Should().Be(false);
|
board["D7"]!.IsPromoted.Should().Be(false);
|
||||||
board["E7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["E7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["E7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["E7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["E7"]?.IsPromoted.Should().Be(false);
|
board["E7"]!.IsPromoted.Should().Be(false);
|
||||||
board["F7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["F7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["F7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["F7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["F7"]?.IsPromoted.Should().Be(false);
|
board["F7"]!.IsPromoted.Should().Be(false);
|
||||||
board["G7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["G7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["G7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["G7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["G7"]?.IsPromoted.Should().Be(false);
|
board["G7"]!.IsPromoted.Should().Be(false);
|
||||||
board["H7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["H7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["H7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["H7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["H7"]?.IsPromoted.Should().Be(false);
|
board["H7"]!.IsPromoted.Should().Be(false);
|
||||||
board["I7"]?.WhichPiece.Should().Be(WhichPiece.Pawn);
|
board["I7"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
board["I7"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["I7"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["I7"]?.IsPromoted.Should().Be(false);
|
board["I7"]!.IsPromoted.Should().Be(false);
|
||||||
|
|
||||||
board["A8"].Should().BeNull();
|
board["A8"].Should().BeNull();
|
||||||
board["B8"]?.WhichPiece.Should().Be(WhichPiece.Rook);
|
board["B8"]!.WhichPiece.Should().Be(WhichPiece.Rook);
|
||||||
board["B8"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["B8"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["B8"]?.IsPromoted.Should().Be(false);
|
board["B8"]!.IsPromoted.Should().Be(false);
|
||||||
board["C8"].Should().BeNull();
|
board["C8"].Should().BeNull();
|
||||||
board["D8"].Should().BeNull();
|
board["D8"].Should().BeNull();
|
||||||
board["E8"].Should().BeNull();
|
board["E8"].Should().BeNull();
|
||||||
board["F8"].Should().BeNull();
|
board["F8"].Should().BeNull();
|
||||||
board["G8"].Should().BeNull();
|
board["G8"].Should().BeNull();
|
||||||
board["H8"]?.WhichPiece.Should().Be(WhichPiece.Bishop);
|
board["H8"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
|
||||||
board["H8"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["H8"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["H8"]?.IsPromoted.Should().Be(false);
|
board["H8"]!.IsPromoted.Should().Be(false);
|
||||||
board["I8"].Should().BeNull();
|
board["I8"].Should().BeNull();
|
||||||
|
|
||||||
board["A9"]?.WhichPiece.Should().Be(WhichPiece.Lance);
|
board["A9"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
board["A9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["A9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["A9"]?.IsPromoted.Should().Be(false);
|
board["A9"]!.IsPromoted.Should().Be(false);
|
||||||
board["B9"]?.WhichPiece.Should().Be(WhichPiece.Knight);
|
board["B9"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
board["B9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["B9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["B9"]?.IsPromoted.Should().Be(false);
|
board["B9"]!.IsPromoted.Should().Be(false);
|
||||||
board["C9"]?.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
board["C9"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
board["C9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["C9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["C9"]?.IsPromoted.Should().Be(false);
|
board["C9"]!.IsPromoted.Should().Be(false);
|
||||||
board["D9"]?.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
board["D9"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
board["D9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["D9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["D9"]?.IsPromoted.Should().Be(false);
|
board["D9"]!.IsPromoted.Should().Be(false);
|
||||||
board["E9"]?.WhichPiece.Should().Be(WhichPiece.King);
|
board["E9"]!.WhichPiece.Should().Be(WhichPiece.King);
|
||||||
board["E9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["E9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["E9"]?.IsPromoted.Should().Be(false);
|
board["E9"]!.IsPromoted.Should().Be(false);
|
||||||
board["F9"]?.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
board["F9"]!.WhichPiece.Should().Be(WhichPiece.GoldGeneral);
|
||||||
board["F9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["F9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["F9"]?.IsPromoted.Should().Be(false);
|
board["F9"]!.IsPromoted.Should().Be(false);
|
||||||
board["G9"]?.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
board["G9"]!.WhichPiece.Should().Be(WhichPiece.SilverGeneral);
|
||||||
board["G9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["G9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["G9"]?.IsPromoted.Should().Be(false);
|
board["G9"]!.IsPromoted.Should().Be(false);
|
||||||
board["H9"]?.WhichPiece.Should().Be(WhichPiece.Knight);
|
board["H9"]!.WhichPiece.Should().Be(WhichPiece.Knight);
|
||||||
board["H9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["H9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["H9"]?.IsPromoted.Should().Be(false);
|
board["H9"]!.IsPromoted.Should().Be(false);
|
||||||
board["I9"]?.WhichPiece.Should().Be(WhichPiece.Lance);
|
board["I9"]!.WhichPiece.Should().Be(WhichPiece.Lance);
|
||||||
board["I9"]?.Owner.Should().Be(WhichPlayer.Player2);
|
board["I9"]!.Owner.Should().Be(WhichPlayer.Player2);
|
||||||
board["I9"]?.IsPromoted.Should().Be(false);
|
board["I9"]!.IsPromoted.Should().Be(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user