@using Shogi.Contracts.Api;
@using Shogi.Contracts.Types;
@using System.Text.RegularExpressions;
@using System.Net;
@inject ShogiApi ShogiApi;
@if (showPromotePrompt)
{
}
@code {
[Parameter, EditorRequired]
public WhichPlayer Perspective { get; set; }
[Parameter, EditorRequired]
public Session Session { get; set; } = default!;
private bool IsMyTurn => Session?.BoardState.WhoseTurn == Perspective;
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 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 Task OnClickTile(Piece? pieceAtPosition, string position)
{
if (!IsMyTurn) return;
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)
{
Console.WriteLine("pieceAtPosition is null? {0}", pieceAtPosition == null);
if (pieceAtPosition == null || pieceAtPosition?.Owner != Perspective)
{
// Moving to an empty space or capturing an opponent's piece.
if (ShouldPromptForPromotion(position) || ShouldPromptForPromotion(selectedBoardPosition))
{
Console.WriteLine("Prompt!");
moveTo = position;
showPromotePrompt = true;
}
else
{
Console.WriteLine("OnClick to move to {0}", position);
var success = await ShogiApi.Move(Session.SessionId, new MovePieceCommand(selectedBoardPosition, position, false));
Console.WriteLine("Success? {0}", success);
if (!success)
{
selectedBoardPosition = null;
}
}
StateHasChanged();
return;
}
}
}
async Task OnClickHand(Piece piece)
{
if (!IsMyTurn) 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 Task OnClickPromotionChoice(bool shouldPromote)
{
if (selectedBoardPosition == null && selectedPieceFromHand.HasValue && moveTo != null)
{
return ShogiApi.Move(Session.SessionId, new MovePieceCommand(selectedPieceFromHand.Value, moveTo));
}
throw new InvalidOperationException("Unexpected scenario during OnClickPromotionChoice.");
}
}