create, read, playercount

This commit is contained in:
2022-11-09 16:08:04 -06:00
parent a1f996e508
commit da76917490
37 changed files with 999 additions and 814 deletions

View File

@@ -1,5 +1,6 @@
using Shogi.AcceptanceTests.TestSetup;
using Shogi.Contracts.Api;
using Shogi.Contracts.Types;
using System.Net;
using System.Net.Http.Json;
using Xunit.Abstractions;
@@ -21,16 +22,78 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
private HttpClient Service => fixture.Service;
[Fact]
public async Task ReadSessionsPlayerCount()
{
try
{
// Arrange
await CreateSession();
// Act
var readAllResponse = await Service
.GetFromJsonAsync<ReadSessionsPlayerCountResponse>(new Uri("Sessions/PlayerCount", UriKind.Relative),
Contracts.ShogiApiJsonSerializerSettings.SystemTextJsonSerializerOptions);
// Assert
readAllResponse.Should().NotBeNull();
readAllResponse!
.AllOtherSessions
.Should()
.ContainSingle(session => session.Name == "Acceptance Tests" && session.PlayerCount == 1);
}
finally
{
// Annul
await DeleteSession();
}
}
[Fact]
public async Task CreateAndReadSession()
{
var createResponse = await Service.PostAsJsonAsync(new Uri("Session", UriKind.Relative), new CreateSessionCommand { Name = "Acceptance Tests" });
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var yep = await createResponse.Content.ReadAsStringAsync();
console.WriteLine(yep);
try
{
// Arrange
await CreateSession();
// Act
var response = await Service.GetFromJsonAsync<ReadSessionResponse>(
new Uri("Sessions/Acceptance Tests", UriKind.Relative),
Contracts.ShogiApiJsonSerializerSettings.SystemTextJsonSerializerOptions);
// Assert
response.Should().NotBeNull();
response!.Session.Should().NotBeNull();
response.Session.BoardState.Board.Should().NotBeEmpty();
response.Session.BoardState.Player1Hand.Should().BeEmpty();
response.Session.BoardState.Player2Hand.Should().BeEmpty();
response.Session.BoardState.PlayerInCheck.Should().BeNull();
response.Session.BoardState.WhoseTurn.Should().Be(WhichPlayer.Player1);
response.Session.Player1.Should().NotBeNullOrEmpty();
response.Session.Player2.Should().BeNull();
response.Session.SessionName.Should().Be("Acceptance Tests");
}
finally
{
// Annul
await DeleteSession();
}
}
private async Task CreateSession()
{
var createResponse = await Service.PostAsJsonAsync(
new Uri("Sessions", UriKind.Relative),
new CreateSessionCommand { Name = "Acceptance Tests" },
Contracts.ShogiApiJsonSerializerSettings.SystemTextJsonSerializerOptions);
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
}
private async Task DeleteSession()
{
var response = await Service.DeleteAsync(new Uri("Sessions/Acceptance Tests", UriKind.Relative));
response.StatusCode.Should().Be(HttpStatusCode.NoContent, because: "Test cleanup should succeed");
var readAllResponse = await Service.GetFromJsonAsync<ReadAllSessionsResponse>(new Uri("Session", UriKind.Relative));
readAllResponse.Should().NotBeNull();
readAllResponse!.AllOtherSessions.Should().ContainSingle(session => session.Name == "Acceptance Tests" && session.PlayerCount == 1);
}
}

View File

@@ -21,21 +21,21 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.46.1" />
<PackageReference Include="FluentAssertions" Version="6.8.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.48.0" />
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View File

@@ -1,62 +1,60 @@
using Microsoft.Extensions.Configuration;
namespace Shogi.AcceptanceTests.TestSetup
namespace Shogi.AcceptanceTests.TestSetup;
/// <summary>
/// Acceptance Test fixture for tests which assert features for Microsoft accounts.
/// </summary>
public class GuestTestFixture : IAsyncLifetime, IDisposable
{
/// <summary>
/// Acceptance Test fixture for tests which assert features for Microsoft accounts.
/// </summary>
public class GuestTestFixture : IAsyncLifetime, IDisposable
private bool disposedValue;
public GuestTestFixture()
{
private bool disposedValue;
Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
public GuestTestFixture()
Service = new HttpClient
{
Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
//.AddEnvironmentVariables()
.Build();
BaseAddress = new Uri(Configuration["ServiceUrl"], UriKind.Absolute)
};
}
Service = new HttpClient
public IConfiguration Configuration { get; private set; }
public HttpClient Service { get; }
public async Task InitializeAsync()
{
// Log in as a guest account and retain the session cookie for future requests.
var loginResponse = await Service.GetAsync(new Uri("User/LoginAsGuest", UriKind.Relative));
loginResponse.IsSuccessStatusCode.Should().BeTrue(because: "Guest accounts should work");
var guestSessionCookie = loginResponse.Headers.GetValues("Set-Cookie").SingleOrDefault();
Service.DefaultRequestHeaders.Add("Set-Cookie", guestSessionCookie);
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
BaseAddress = new Uri(Configuration["ServiceUrl"], UriKind.Absolute)
};
}
public IConfiguration Configuration { get; private set; }
public HttpClient Service { get; }
public async Task InitializeAsync()
{
// Log in as a guest account.
var loginResponse = await Service.GetAsync(new Uri("User/LoginAsGuest", UriKind.Relative));
loginResponse.EnsureSuccessStatusCode();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
Service.Dispose();
}
disposedValue = true;
Service.Dispose();
}
}
public Task DisposeAsync()
{
Dispose(true);
return Task.CompletedTask;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
disposedValue = true;
}
}
public Task DisposeAsync()
{
Dispose(true);
return Task.CompletedTask;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}

View File

@@ -1,186 +1,182 @@
using FluentAssertions;
using Xunit;
namespace Shogi.Domain.UnitTests;
namespace Shogi.Domain.UnitTests
public class ShogiBoardStateShould
{
public class ShogiBoardStateShould
[Fact]
public void InitializeBoardState()
{
[Fact]
public void InitializeBoardState()
{
// Act
var board = new BoardState();
// Act
var board = BoardState.StandardStarting;
// Assert
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);
// Assert
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["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["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["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["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["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["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["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);
}
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);
}
}

View File

@@ -1,462 +1,463 @@
using System;
using Shogi.Domain.ValueObjects;
using System;
namespace Shogi.Domain.UnitTests
{
public class ShogiShould
{
private readonly ITestOutputHelper console;
public ShogiShould(ITestOutputHelper console)
{
this.console = console;
}
public class ShogiShould
{
private readonly ITestOutputHelper console;
public ShogiShould(ITestOutputHelper console)
{
this.console = console;
}
[Fact]
public void MoveAPieceToAnEmptyPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
[Fact]
public void MoveAPieceToAnEmptyPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
board["A4"].Should().BeNull();
var expectedPiece = board["A3"];
expectedPiece.Should().NotBeNull();
board["A4"].Should().BeNull();
var expectedPiece = board["A3"];
expectedPiece.Should().NotBeNull();
// Act
shogi.Move("A3", "A4", false);
// Act
shogi.Move("A3", "A4", false);
// Assert
board["A3"].Should().BeNull();
board["A4"].Should().Be(expectedPiece);
}
// Assert
board["A3"].Should().BeNull();
board["A4"].Should().Be(expectedPiece);
}
[Fact]
public void AllowValidMoves_AfterCheck()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// P1 Bishop puts P2 in check
shogi.Move("B2", "G7", false);
board.InCheck.Should().Be(WhichPlayer.Player2);
[Fact]
public void AllowValidMoves_AfterCheck()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// P1 Bishop puts P2 in check
shogi.Move("B2", "G7", false);
board.InCheck.Should().Be(WhichPlayer.Player2);
// Act - P2 is able to un-check theirself.
/// P2 King moves out of check
shogi.Move("E9", "E8", false);
// Act - P2 is able to un-check theirself.
/// P2 King moves out of check
shogi.Move("E9", "E8", false);
// Assert
using (new AssertionScope())
{
board.InCheck.Should().BeNull();
}
}
// Assert
using (new AssertionScope())
{
board.InCheck.Should().BeNull();
}
}
[Fact]
public void PreventInvalidMoves_MoveFromEmptyPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
board["D5"].Should().BeNull();
[Fact]
public void PreventInvalidMoves_MoveFromEmptyPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
board["D5"].Should().BeNull();
// Act
var act = () => shogi.Move("D5", "D6", false);
// Act
var act = () => shogi.Move("D5", "D6", false);
// Assert
act.Should().Throw<InvalidOperationException>();
board["D5"].Should().BeNull();
board["D6"].Should().BeNull();
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
// Assert
act.Should().Throw<InvalidOperationException>();
board["D5"].Should().BeNull();
board["D6"].Should().BeNull();
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
[Fact]
public void PreventInvalidMoves_MoveToCurrentPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A3"];
[Fact]
public void PreventInvalidMoves_MoveToCurrentPosition()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A3"];
// Act - P1 "moves" pawn to the position it already exists at.
var act = () => shogi.Move("A3", "A3", false);
// Act - P1 "moves" pawn to the position it already exists at.
var act = () => shogi.Move("A3", "A3", false);
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A3"].Should().Be(expectedPiece);
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A3"].Should().Be(expectedPiece);
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
[Fact]
public void PreventInvalidMoves_MoveSet()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A1"];
expectedPiece!.WhichPiece.Should().Be(WhichPiece.Lance);
[Fact]
public void PreventInvalidMoves_MoveSet()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A1"];
expectedPiece!.WhichPiece.Should().Be(WhichPiece.Lance);
// Act - Move Lance illegally
var act = () => shogi.Move("A1", "D5", false);
// Act - Move Lance illegally
var act = () => shogi.Move("A1", "D5", false);
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A1"].Should().Be(expectedPiece);
board["A5"].Should().BeNull();
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A1"].Should().Be(expectedPiece);
board["A5"].Should().BeNull();
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
[Fact]
public void PreventInvalidMoves_Ownership()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A7"];
expectedPiece!.Owner.Should().Be(WhichPlayer.Player2);
board.WhoseTurn.Should().Be(WhichPlayer.Player1);
[Fact]
public void PreventInvalidMoves_Ownership()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var expectedPiece = board["A7"];
expectedPiece!.Owner.Should().Be(WhichPlayer.Player2);
board.WhoseTurn.Should().Be(WhichPlayer.Player1);
// Act - Move Player2 Pawn when it is Player1 turn.
var act = () => shogi.Move("A7", "A6", false);
// Act - Move Player2 Pawn when it is Player1 turn.
var act = () => shogi.Move("A7", "A6", false);
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A7"].Should().Be(expectedPiece);
board["A6"].Should().BeNull();
}
}
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A7"].Should().Be(expectedPiece);
board["A6"].Should().BeNull();
}
}
[Fact]
public void PreventInvalidMoves_MoveThroughAllies()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var lance = board["A1"];
var pawn = board["A3"];
lance!.Owner.Should().Be(pawn!.Owner);
[Fact]
public void PreventInvalidMoves_MoveThroughAllies()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var lance = board["A1"];
var pawn = board["A3"];
lance!.Owner.Should().Be(pawn!.Owner);
// Act - Move P1 Lance through P1 Pawn.
var act = () => shogi.Move("A1", "A5", false);
// Act - Move P1 Lance through P1 Pawn.
var act = () => shogi.Move("A1", "A5", false);
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A1"].Should().Be(lance);
board["A3"].Should().Be(pawn);
board["A5"].Should().BeNull();
}
}
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["A1"].Should().Be(lance);
board["A3"].Should().Be(pawn);
board["A5"].Should().BeNull();
}
}
[Fact]
public void PreventInvalidMoves_CaptureAlly()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var knight = board["B1"];
var pawn = board["C3"];
knight!.Owner.Should().Be(pawn!.Owner);
[Fact]
public void PreventInvalidMoves_CaptureAlly()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var knight = board["B1"];
var pawn = board["C3"];
knight!.Owner.Should().Be(pawn!.Owner);
// Act - P1 Knight tries to capture P1 Pawn.
var act = () => shogi.Move("B1", "C3", false);
// Act - P1 Knight tries to capture P1 Pawn.
var act = () => shogi.Move("B1", "C3", false);
// Arrange
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["B1"].Should().Be(knight);
board["C3"].Should().Be(pawn);
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
// Arrange
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board["B1"].Should().Be(knight);
board["C3"].Should().Be(pawn);
board.Player1Hand.Should().BeEmpty();
board.Player2Hand.Should().BeEmpty();
}
}
[Fact]
public void PreventInvalidMoves_Check()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// P1 Bishop puts P2 in check
shogi.Move("B2", "G7", false);
board.InCheck.Should().Be(WhichPlayer.Player2);
var lance = board["I9"];
[Fact]
public void PreventInvalidMoves_Check()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// P1 Bishop puts P2 in check
shogi.Move("B2", "G7", false);
board.InCheck.Should().Be(WhichPlayer.Player2);
var lance = board["I9"];
// Act - P2 moves Lance while in check.
var act = () => shogi.Move("I9", "I8", false);
// Act - P2 moves Lance while in check.
var act = () => shogi.Move("I9", "I8", false);
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board.InCheck.Should().Be(WhichPlayer.Player2);
board["I9"].Should().Be(lance);
board["I8"].Should().BeNull();
}
}
// Assert
using (new AssertionScope())
{
act.Should().Throw<InvalidOperationException>();
board.InCheck.Should().Be(WhichPlayer.Player2);
board["I9"].Should().Be(lance);
board["I8"].Should().BeNull();
}
}
[Fact]
// TODO: Consider nesting classes to share this setup in a constructor but have act and assert as separate facts.
public void PreventInvalidDrops_MoveSet()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("I7", "I6", false);
// P1 Bishop takes P2 Pawn.
shogi.Move("B2", "G7", false);
// P2 Gold, block check from P1 Bishop.
shogi.Move("F9", "F8", false);
// P1 Bishop takes P2 Bishop, promotes so it can capture P2 Knight and P2 Lance
shogi.Move("G7", "H8", true);
// P2 Pawn again
shogi.Move("I6", "I5", false);
// P1 Bishop takes P2 Knight
shogi.Move("H8", "H9", false);
// P2 Pawn again
shogi.Move("I5", "I4", false);
// P1 Bishop takes P2 Lance
shogi.Move("H9", "I9", false);
// P2 Pawn captures P1 Pawn
shogi.Move("I4", "I3", false);
board.Player1Hand.Count.Should().Be(4);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Lance);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Pawn);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
board.WhoseTurn.Should().Be(WhichPlayer.Player1);
[Fact]
// TODO: Consider nesting classes to share this setup in a constructor but have act and assert as separate facts.
public void PreventInvalidDrops_MoveSet()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("I7", "I6", false);
// P1 Bishop takes P2 Pawn.
shogi.Move("B2", "G7", false);
// P2 Gold, block check from P1 Bishop.
shogi.Move("F9", "F8", false);
// P1 Bishop takes P2 Bishop, promotes so it can capture P2 Knight and P2 Lance
shogi.Move("G7", "H8", true);
// P2 Pawn again
shogi.Move("I6", "I5", false);
// P1 Bishop takes P2 Knight
shogi.Move("H8", "H9", false);
// P2 Pawn again
shogi.Move("I5", "I4", false);
// P1 Bishop takes P2 Lance
shogi.Move("H9", "I9", false);
// P2 Pawn captures P1 Pawn
shogi.Move("I4", "I3", false);
board.Player1Hand.Count.Should().Be(4);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Lance);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Pawn);
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
board.WhoseTurn.Should().Be(WhichPlayer.Player1);
// Act | Assert - Illegally placing Knight from the hand in farthest rank.
board["H9"].Should().BeNull();
var act = () => shogi.Move(WhichPiece.Knight, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
// Act | Assert - Illegally placing Knight from the hand in farthest rank.
board["H9"].Should().BeNull();
var act = () => shogi.Move(WhichPiece.Knight, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
// Act | Assert - Illegally placing Knight from the hand in second farthest row.
board["H8"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Knight, "H8");
act.Should().Throw<InvalidOperationException>();
board["H8"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
// Act | Assert - Illegally placing Knight from the hand in second farthest row.
board["H8"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Knight, "H8");
act.Should().Throw<InvalidOperationException>();
board["H8"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Knight);
// Act | Assert - Illegally place Lance from the hand.
board["H9"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Knight, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Lance);
// Act | Assert - Illegally place Lance from the hand.
board["H9"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Knight, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Lance);
// Act | Assert - Illegally place Pawn from the hand.
board["H9"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Pawn, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Pawn);
// Act | Assert - Illegally place Pawn from the hand.
board["H9"].Should().BeNull();
act = () => shogi.Move(WhichPiece.Pawn, "H9");
act.Should().Throw<InvalidOperationException>();
board["H9"].Should().BeNull();
board.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Pawn);
// // Act | Assert - Illegally place Pawn from the hand in a row which already has an unpromoted Pawn.
// // TODO
}
// // Act | Assert - Illegally place Pawn from the hand in a row which already has an unpromoted Pawn.
// // TODO
}
//[Fact]
//public void PreventInvalidDrop_Check()
//{
// // Arrange
// var moves = new[]
// {
// // P1 Pawn
// new Move("C3", "C4"),
// // P2 Pawn
// new Move("G7", "G6"),
// // P1 Pawn, arbitrary move.
// new Move("A3", "A4"),
// // P2 Bishop takes P1 Bishop
// new Move("H8", "B2"),
// // P1 Silver takes P2 Bishop
// new Move("C1", "B2"),
// // P2 Pawn, arbtrary move
// new Move("A7", "A6"),
// // P1 drop Bishop, place P2 in check
// new Move(WhichPiece.Bishop, "G7")
// };
// var shogi = new Shogi(moves);
// shogi.InCheck.Should().Be(WhichPlayer.Player2);
// shogi.Player2Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["E5"].Should().BeNull();
//[Fact]
//public void PreventInvalidDrop_Check()
//{
// // Arrange
// var moves = new[]
// {
// // P1 Pawn
// new Move("C3", "C4"),
// // P2 Pawn
// new Move("G7", "G6"),
// // P1 Pawn, arbitrary move.
// new Move("A3", "A4"),
// // P2 Bishop takes P1 Bishop
// new Move("H8", "B2"),
// // P1 Silver takes P2 Bishop
// new Move("C1", "B2"),
// // P2 Pawn, arbtrary move
// new Move("A7", "A6"),
// // P1 drop Bishop, place P2 in check
// new Move(WhichPiece.Bishop, "G7")
// };
// var shogi = new Shogi(moves);
// shogi.InCheck.Should().Be(WhichPlayer.Player2);
// shogi.Player2Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["E5"].Should().BeNull();
// // Act - P2 places a Bishop while in check.
// var dropSuccess = shogi.Move(new Move(WhichPiece.Bishop, "E5"));
// // Act - P2 places a Bishop while in check.
// var dropSuccess = shogi.Move(new Move(WhichPiece.Bishop, "E5"));
// // Assert
// dropSuccess.Should().BeFalse();
// board["E5"].Should().BeNull();
// shogi.InCheck.Should().Be(WhichPlayer.Player2);
// shogi.Player2Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
//}
// // Assert
// dropSuccess.Should().BeFalse();
// board["E5"].Should().BeNull();
// shogi.InCheck.Should().Be(WhichPlayer.Player2);
// shogi.Player2Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
//}
//[Fact]
//public void PreventInvalidDrop_Capture()
//{
// // Arrange
// var moves = new[]
// {
// // P1 Pawn
// new Move("C3", "C4"),
// // P2 Pawn
// new Move("G7", "G6"),
// // P1 Bishop capture P2 Bishop
// new Move("B2", "H8"),
// // P2 Pawn
// new Move("G6", "G5")
// };
// var shogi = new Shogi(moves);
// using (new AssertionScope())
// {
// shogi.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["I9"].Should().NotBeNull();
// board["I9"].WhichPiece.Should().Be(WhichPiece.Lance);
// board["I9"].Owner.Should().Be(WhichPlayer.Player2);
// }
//[Fact]
//public void PreventInvalidDrop_Capture()
//{
// // Arrange
// var moves = new[]
// {
// // P1 Pawn
// new Move("C3", "C4"),
// // P2 Pawn
// new Move("G7", "G6"),
// // P1 Bishop capture P2 Bishop
// new Move("B2", "H8"),
// // P2 Pawn
// new Move("G6", "G5")
// };
// var shogi = new Shogi(moves);
// using (new AssertionScope())
// {
// shogi.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["I9"].Should().NotBeNull();
// board["I9"].WhichPiece.Should().Be(WhichPiece.Lance);
// board["I9"].Owner.Should().Be(WhichPlayer.Player2);
// }
// // Act - P1 tries to place a piece where an opponent's piece resides.
// var dropSuccess = shogi.Move(new Move(WhichPiece.Bishop, "I9"));
// // Act - P1 tries to place a piece where an opponent's piece resides.
// var dropSuccess = shogi.Move(new Move(WhichPiece.Bishop, "I9"));
// // Assert
// using (new AssertionScope())
// {
// dropSuccess.Should().BeFalse();
// shogi.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["I9"].Should().NotBeNull();
// board["I9"].WhichPiece.Should().Be(WhichPiece.Lance);
// board["I9"].Owner.Should().Be(WhichPlayer.Player2);
// }
//}
// // Assert
// using (new AssertionScope())
// {
// dropSuccess.Should().BeFalse();
// shogi.Player1Hand.Should().ContainSingle(_ => _.WhichPiece == WhichPiece.Bishop);
// board["I9"].Should().NotBeNull();
// board["I9"].WhichPiece.Should().Be(WhichPiece.Lance);
// board["I9"].Owner.Should().Be(WhichPlayer.Player2);
// }
//}
[Fact]
public void Check()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
[Fact]
public void Check()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// Act - P1 Bishop, check
shogi.Move("B2", "G7", false);
// Act - P1 Bishop, check
shogi.Move("B2", "G7", false);
// Assert
board.InCheck.Should().Be(WhichPlayer.Player2);
}
// Assert
board.InCheck.Should().Be(WhichPlayer.Player2);
}
[Fact]
public void Promote()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
[Fact]
public void Promote()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Pawn
shogi.Move("C3", "C4", false);
// P2 Pawn
shogi.Move("G7", "G6", false);
// Act - P1 moves across promote threshold.
shogi.Move("B2", "G7", true);
// Act - P1 moves across promote threshold.
shogi.Move("B2", "G7", true);
// Assert
using (new AssertionScope())
{
board["B2"].Should().BeNull();
board["G7"].Should().NotBeNull();
board["G7"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
board["G7"]!.Owner.Should().Be(WhichPlayer.Player1);
board["G7"]!.IsPromoted.Should().BeTrue();
}
}
// Assert
using (new AssertionScope())
{
board["B2"].Should().BeNull();
board["G7"].Should().NotBeNull();
board["G7"]!.WhichPiece.Should().Be(WhichPiece.Bishop);
board["G7"]!.Owner.Should().Be(WhichPlayer.Player1);
board["G7"]!.IsPromoted.Should().BeTrue();
}
}
[Fact]
public void Capture()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var p1Bishop = board["B2"];
p1Bishop!.WhichPiece.Should().Be(WhichPiece.Bishop);
shogi.Move("C3", "C4", false);
shogi.Move("G7", "G6", false);
[Fact]
public void Capture()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
var p1Bishop = board["B2"];
p1Bishop!.WhichPiece.Should().Be(WhichPiece.Bishop);
shogi.Move("C3", "C4", false);
shogi.Move("G7", "G6", false);
// Act - P1 Bishop captures P2 Bishop
shogi.Move("B2", "H8", false);
// Act - P1 Bishop captures P2 Bishop
shogi.Move("B2", "H8", false);
// Assert
board["B2"].Should().BeNull();
board["H8"].Should().Be(p1Bishop);
// Assert
board["B2"].Should().BeNull();
board["H8"].Should().Be(p1Bishop);
board
.Player1Hand
.Should()
.ContainSingle(p => p.WhichPiece == WhichPiece.Bishop && p.Owner == WhichPlayer.Player1);
}
board
.Player1Hand
.Should()
.ContainSingle(p => p.WhichPiece == WhichPiece.Bishop && p.Owner == WhichPlayer.Player1);
}
[Fact]
public void CheckMate()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Rook
shogi.Move("H2", "E2", false);
// P2 Gold
shogi.Move("F9", "G8", false);
// P1 Pawn
shogi.Move("E3", "E4", false);
// P2 other Gold
shogi.Move("D9", "C8", false);
// P1 same Pawn
shogi.Move("E4", "E5", false);
// P2 Pawn
shogi.Move("E7", "E6", false);
// P1 Pawn takes P2 Pawn
shogi.Move("E5", "E6", false);
// P2 King
shogi.Move("E9", "E8", false);
// P1 Pawn promotes; threatens P2 King
shogi.Move("E6", "E7", true);
// P2 King retreat
shogi.Move("E8", "E9", false);
[Fact]
public void CheckMate()
{
// Arrange
var shogi = MockShogiBoard();
var board = shogi.BoardState;
// P1 Rook
shogi.Move("H2", "E2", false);
// P2 Gold
shogi.Move("F9", "G8", false);
// P1 Pawn
shogi.Move("E3", "E4", false);
// P2 other Gold
shogi.Move("D9", "C8", false);
// P1 same Pawn
shogi.Move("E4", "E5", false);
// P2 Pawn
shogi.Move("E7", "E6", false);
// P1 Pawn takes P2 Pawn
shogi.Move("E5", "E6", false);
// P2 King
shogi.Move("E9", "E8", false);
// P1 Pawn promotes; threatens P2 King
shogi.Move("E6", "E7", true);
// P2 King retreat
shogi.Move("E8", "E9", false);
// Act - P1 Pawn wins by checkmate.
shogi.Move("E7", "E8", false);
// Act - P1 Pawn wins by checkmate.
shogi.Move("E7", "E8", false);
// Assert - checkmate
console.WriteLine(shogi.ToStringStateAsAscii());
board.IsCheckmate.Should().BeTrue();
board.InCheck.Should().Be(WhichPlayer.Player2);
}
// Assert - checkmate
console.WriteLine(shogi.ToStringStateAsAscii());
board.IsCheckmate.Should().BeTrue();
board.InCheck.Should().Be(WhichPlayer.Player2);
}
private static ShogiBoard MockShogiBoard() => new ShogiBoard("Test Session", BoardState.StandardStarting);
}
private static ShogiBoard MockShogiBoard() => new(BoardState.StandardStarting);
}
}

View File

@@ -8,14 +8,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="FluentAssertions" Version="6.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>