diff --git a/Shogi.UI/Pages/Home/GameBoard.razor b/Shogi.UI/Pages/Home/GameBoard.razor
index 82208c1..3fc8200 100644
--- a/Shogi.UI/Pages/Home/GameBoard.razor
+++ b/Shogi.UI/Pages/Home/GameBoard.razor
@@ -1,6 +1,9 @@
-@using Shogi.Contracts.Types;
+@using Shogi.Contracts.Api
+@using Shogi.Contracts.Types;
+@using System.Text.RegularExpressions;
@inject IShogiApi ShogiApi
@inject AccountState Account;
+@inject PromotePrompt PromotePrompt;
@@ -42,6 +45,15 @@
H
I
+
+
@if (session != null)
@@ -67,15 +79,15 @@
}
-
}
@code {
+ static readonly string[] Files = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };
+
[Parameter]
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;
@@ -114,8 +126,22 @@
}
}
- void OnClickTile(Piece? piece, string position)
+ bool ShouldPromptForPromotion(string position)
{
+ if (Perspective == WhichPlayer.Player1 && Regex.IsMatch(position, ".[7-9]"))
+ {
+ return true;
+ }
+ if (Perspective == WhichPlayer.Player2 && Regex.IsMatch(position, ".[1-3]"))
+ {
+ return true;
+ }
+ return false;
+ }
+ async void OnClickTile(Piece? piece, string position)
+ {
+ if (SessionName == null) return;
+
if (selectedPosition == null)
{
selectedPosition = position;
@@ -128,12 +154,23 @@
}
else if (piece != null)
{
- ShogiApi.PostMove(SessionName!, new Contracts.Api.MovePieceCommand
+ if (ShouldPromptForPromotion(position) || ShouldPromptForPromotion(selectedPosition))
{
- From = selectedPosition,
- To = position,
- IsP
- });
+ PromotePrompt.Show(SessionName, new MovePieceCommand
+ {
+ From = selectedPosition,
+ To = position
+ });
+ }
+ else
+ {
+ await ShogiApi.PostMove(SessionName, new MovePieceCommand
+ {
+ From = selectedPosition,
+ IsPromotion = false,
+ To = position
+ });
+ }
}
}
void OnClickHand(Piece piece)
diff --git a/Shogi.UI/Pages/Home/PromotePrompt.cs b/Shogi.UI/Pages/Home/PromotePrompt.cs
new file mode 100644
index 0000000..dbd1cf8
--- /dev/null
+++ b/Shogi.UI/Pages/Home/PromotePrompt.cs
@@ -0,0 +1,58 @@
+using Shogi.Contracts.Api;
+using Shogi.UI.Pages.Home.Api;
+
+namespace Shogi.UI.Pages.Home;
+
+public class PromotePrompt
+{
+ private readonly IShogiApi shogiApi;
+ private string? sessionName;
+ private MovePieceCommand? command;
+
+ public PromotePrompt(IShogiApi shogiApi)
+ {
+ this.shogiApi = shogiApi;
+ IsVisible = false;
+ OnClickCancel = Hide;
+ }
+
+ public bool IsVisible { get; private set; }
+ public Action OnClickCancel;
+ public Func? OnClickNo;
+ public Func? OnClickYes;
+
+ public void Show(string sessionName, MovePieceCommand command)
+ {
+ this.sessionName = sessionName;
+ this.command = command;
+ IsVisible = true;
+ OnClickNo = Move;
+ OnClickYes = MoveAndPromote;
+ }
+
+ public void Hide()
+ {
+ IsVisible = false;
+ OnClickNo = null;
+ OnClickYes = null;
+ }
+
+ private Task Move()
+ {
+ if (command != null && sessionName != null)
+ {
+ command.IsPromotion = false;
+ return shogiApi.PostMove(sessionName, command);
+ }
+ return Task.CompletedTask;
+ }
+ private Task MoveAndPromote()
+ {
+ if (command != null && sessionName != null)
+ {
+ command.IsPromotion = true;
+ return shogiApi.PostMove(sessionName, command);
+ }
+ return Task.CompletedTask;
+ }
+}
diff --git a/Shogi.UI/Program.cs b/Shogi.UI/Program.cs
index ac0d6df..a832802 100644
--- a/Shogi.UI/Program.cs
+++ b/Shogi.UI/Program.cs
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Shogi.UI;
+using Shogi.UI.Pages.Home;
using Shogi.UI.Pages.Home.Account;
using Shogi.UI.Pages.Home.Api;
using Shogi.UI.Shared;
@@ -54,6 +55,7 @@ static void ConfigureDependencies(IServiceCollection services, IConfiguration co
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
var serializerOptions = new JsonSerializerOptions
{