@using Shogi.Contracts.Api.Commands @using Shogi.Contracts.Types; @using System.Text.RegularExpressions; @using System.Net; @inject ShogiApi ShogiApi;
@if (showPromotePrompt) {

Do you wish to promote?

}
@code { [Parameter, EditorRequired] public WhichPlayer Perspective { get; set; } [Parameter, EditorRequired] public Session Session { get; set; } = default!; private string? selectedBoardPosition; private WhichPiece? selectedPieceFromHand; private bool showPromotePrompt; private string? moveTo; protected override void OnParametersSet() { base.OnParametersSet(); selectedBoardPosition = null; selectedPieceFromHand = null; if (Session == null) { throw new ArgumentException($"{nameof(Session)} cannot be null.", nameof(Session)); } } bool IsWithinPromoteArea(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 Task OnClickTile(string position) { if (showPromotePrompt) return; var pieceAtPosition = Session.BoardState.Board[position]; if (selectedBoardPosition == position) { // Deselect the selected position. selectedBoardPosition = null; StateHasChanged(); return; } if (selectedBoardPosition == null && pieceAtPosition?.Owner == Perspective) { // Select an owned piece. selectedBoardPosition = position; // Prevent selecting pieces from the hand and board at the same time. selectedPieceFromHand = null; StateHasChanged(); return; } if (selectedPieceFromHand is not null) { if (pieceAtPosition is null) { // Placing a piece from the hand to an empty space. var success = await ShogiApi.Move( Session.SessionId, new MovePieceCommand(selectedPieceFromHand.Value, position)); if (!success) { selectedPieceFromHand = null; } } StateHasChanged(); return; } if (selectedBoardPosition != null) { if (pieceAtPosition == null || pieceAtPosition?.Owner != Perspective) { var pieceBeingMoved = Session.BoardState.Board[selectedBoardPosition]; var isPromotedAlready = pieceBeingMoved != null && pieceBeingMoved.IsPromoted; Console.WriteLine("Is promoted? {0}", isPromotedAlready); // Moving to an empty space or capturing an opponent's piece. if (!isPromotedAlready && (IsWithinPromoteArea(position) || IsWithinPromoteArea(selectedBoardPosition))) { Console.WriteLine("Prompt!"); moveTo = position; showPromotePrompt = true; } else { var success = await ShogiApi.Move(Session.SessionId, new MovePieceCommand(selectedBoardPosition, position, false)); if (!success) { selectedBoardPosition = null; } } StateHasChanged(); return; } } } void OnClickHand(Piece piece) { if (showPromotePrompt) return; // Prevent selecting from both the hand and the board. selectedBoardPosition = null; selectedPieceFromHand = piece.WhichPiece == selectedPieceFromHand // Deselecting the already-selected piece ? selectedPieceFromHand = null : selectedPieceFromHand = piece.WhichPiece; StateHasChanged(); } private async Task OnClickPromotionChoice(bool shouldPromote) { if (selectedBoardPosition != null && moveTo != null) { await ShogiApi.Move(Session.SessionId, new MovePieceCommand(selectedBoardPosition, moveTo, shouldPromote)); showPromotePrompt = false; return; } throw new InvalidOperationException("Unexpected scenario during OnClickPromotionChoice."); } }