Fixed accidentally building the board from player2 perspective.

This commit is contained in:
2021-04-06 19:52:02 -05:00
parent 2d5c6b20b9
commit 05a9c71499
45 changed files with 441 additions and 276 deletions

View File

@@ -1,10 +1,10 @@
using Gameboard.ShogiUI.BoardState.Pieces;
using Gameboard.ShogiUI.Rules.Pieces;
using PathFinding;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Gameboard.ShogiUI.BoardState
namespace Gameboard.ShogiUI.Rules
{
/// <summary>
/// Facilitates Shogi board state transitions, cognisant of Shogi rules.
@@ -14,16 +14,20 @@ namespace Gameboard.ShogiUI.BoardState
public class ShogiBoard
{
private delegate void MoveSetCallback(Piece piece, Vector2 position);
private readonly bool isValidationBoard;
private readonly PathFinder2D<Piece> pathFinder;
private ShogiBoard validationBoard;
private Vector2 player1King;
private Vector2 player2King;
public IReadOnlyDictionary<WhichPlayer, List<Piece>> Hands { get; }
public PlanarCollection<Piece> Board { get; }
public PlanarCollection<Piece> Board { get; } //TODO: Hide this being a getter method
public List<Move> MoveHistory { get; }
public WhichPlayer WhoseTurn => MoveHistory.Count % 2 == 0 ? WhichPlayer.Player1 : WhichPlayer.Player2;
public WhichPlayer? InCheck { get; private set; }
public bool IsCheckmate { get; private set; }
public string Error { get; private set; }
public ShogiBoard()
{
@@ -35,8 +39,8 @@ namespace Gameboard.ShogiUI.BoardState
};
pathFinder = new PathFinder2D<Piece>(Board);
InitializeBoardState();
player1King = new Vector2(4, 0);
player2King = new Vector2(4, 8);
player1King = new Vector2(4, 8);
player2King = new Vector2(4, 0);
}
public ShogiBoard(IList<Move> moves) : this()
@@ -46,13 +50,14 @@ namespace Gameboard.ShogiUI.BoardState
if (!Move(moves[i]))
{
// Todo: Add some smarts to know why a move was invalid. In check? Piece not found? etc.
throw new InvalidOperationException($"Unable to construct ShogiBoard with the given move at index {i}.");
throw new InvalidOperationException($"Unable to construct ShogiBoard with the given move at index {i}. {Error}");
}
}
}
private ShogiBoard(ShogiBoard toCopy)
{
isValidationBoard = true;
Board = new PlanarCollection<Piece>(9, 9);
for (var x = 0; x < 9; x++)
for (var y = 0; y < 9; y++)
@@ -143,8 +148,8 @@ namespace Gameboard.ShogiUI.BoardState
minimumY = WhoseTurn == WhichPlayer.Player1 ? 7 : 1;
break;
}
if (WhoseTurn == WhichPlayer.Player1 && move.To.Y > minimumY) return false;
if (WhoseTurn == WhichPlayer.Player2 && move.To.Y < minimumY) return false;
if (WhoseTurn == WhichPlayer.Player1 && move.To.Y < minimumY) return false;
if (WhoseTurn == WhichPlayer.Player2 && move.To.Y > minimumY) return false;
// Mutate the board.
Board[move.To.X, move.To.Y] = Hands[WhoseTurn][index];
@@ -156,9 +161,21 @@ namespace Gameboard.ShogiUI.BoardState
private bool PlaceFromBoard(Move move)
{
var fromPiece = Board[move.From.X, move.From.Y];
if (fromPiece == null) return false; // Invalid move
if (fromPiece.Owner != WhoseTurn) return false; // Invalid move; cannot move other players pieces.
if (IsPathable(move.From, move.To) == false) return false; // Invalid move; move not part of move-set.
if (fromPiece == null)
{
Error = $"No piece exists at {nameof(move)}.{nameof(move.From)}.";
return false; // Invalid move
}
if (fromPiece.Owner != WhoseTurn)
{
Error = "Not allowed to move the opponents piece";
return false; // Invalid move; cannot move other players pieces.
}
if (IsPathable(move.From, move.To) == false)
{
Error = $"Illegal move for {fromPiece.WhichPiece}. {nameof(move)}.{nameof(move.To)} is not part of the move-set.";
return false; // Invalid move; move not part of move-set.
}
var captured = Board[move.To.X, move.To.Y];
if (captured != null)
@@ -171,11 +188,11 @@ namespace Gameboard.ShogiUI.BoardState
//Mutate the board.
if (move.IsPromotion)
{
if (WhoseTurn == WhichPlayer.Player1 && (move.To.Y > 5 || move.From.Y > 5))
if (WhoseTurn == WhichPlayer.Player1 && (move.To.Y < 3 || move.From.Y < 3))
{
fromPiece.Promote();
}
else if (WhoseTurn == WhichPlayer.Player2 && (move.To.Y < 3 || move.From.Y < 3))
else if (WhoseTurn == WhichPlayer.Player2 && (move.To.Y > 5 || move.From.Y > 5))
{
fromPiece.Promote();
}
@@ -313,12 +330,12 @@ namespace Gameboard.ShogiUI.BoardState
}
private void ResetFrontRow(WhichPlayer player)
{
int y = player == WhichPlayer.Player1 ? 2 : 6;
int y = player == WhichPlayer.Player1 ? 6 : 2;
for (int x = 0; x < 9; x++) Board[x, y] = new Pawn(player);
}
private void ResetMiddleRow(WhichPlayer player)
{
int y = player == WhichPlayer.Player1 ? 1 : 7;
int y = player == WhichPlayer.Player1 ? 7 : 1;
Board[0, y] = null;
for (int x = 2; x < 7; x++) Board[x, y] = null;
@@ -336,7 +353,7 @@ namespace Gameboard.ShogiUI.BoardState
}
private void ResetRearRow(WhichPlayer player)
{
int y = player == WhichPlayer.Player1 ? 0 : 8;
int y = player == WhichPlayer.Player1 ? 8 : 0;
Board[0, y] = new Lance(player);
Board[1, y] = new Knight(player);
@@ -350,13 +367,13 @@ namespace Gameboard.ShogiUI.BoardState
}
private void InitializeBoardState()
{
ResetRearRow(WhichPlayer.Player1);
ResetMiddleRow(WhichPlayer.Player1);
ResetFrontRow(WhichPlayer.Player1);
ResetEmptyRows();
ResetFrontRow(WhichPlayer.Player2);
ResetMiddleRow(WhichPlayer.Player2);
ResetRearRow(WhichPlayer.Player2);
ResetMiddleRow(WhichPlayer.Player2);
ResetFrontRow(WhichPlayer.Player2);
ResetEmptyRows();
ResetFrontRow(WhichPlayer.Player1);
ResetMiddleRow(WhichPlayer.Player1);
ResetRearRow(WhichPlayer.Player1);
}
#endregion
}