This commit is contained in:
2021-12-22 17:43:32 -06:00
parent aa4d5120e4
commit a2f3abb94e
14 changed files with 1096 additions and 212 deletions

View File

@@ -1,6 +1,4 @@
using System.Numerics;
namespace Shogi.Domain
namespace Shogi.Domain
{
/// <summary>
/// Facilitates Shogi board state transitions, cognisant of Shogi rules.
@@ -17,74 +15,89 @@ namespace Shogi.Domain
{
this.board = board;
rules = new StandardRules(this.board);
Error = string.Empty;
}
public Shogi(IList<Move> moves) : this()
//public Shogi(IList<Move> moves) : this(new ShogiBoardState())
//{
// for (var i = 0; i < moves.Count; i++)
// {
// if (!Move(moves[i]))
// {
// throw new InvalidOperationException($"Unable to construct ShogiBoard with the given move at index {i}.");
// }
// }
//}
public MoveResult CanMove(string from, string to, bool isPromotion)
{
for (var i = 0; i < moves.Count; i++)
{
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}. {Error}");
}
}
// TODO: ShogiBoardState.FromBoardNotation should not throw an execption in this query method.
var fromVector = ShogiBoardState.FromBoardNotation(from);
var toVector = ShogiBoardState.FromBoardNotation(to);
var simulator = new StandardRules(new ShogiBoardState(board));
return simulator.Move(fromVector, toVector, isPromotion);
}
public bool Move(Move move)
public MoveResult CanMove(WhichPiece pieceInHand, string to)
{
var moveSuccess = TryMove(move);
var toVector = ShogiBoardState.FromBoardNotation(to);
var simulator = new StandardRules(new ShogiBoardState(board));
return simulator.Move(pieceInHand, toVector);
}
if (!moveSuccess)
public void Move(string from, string to, bool isPromotion)
{
var fromVector = ShogiBoardState.FromBoardNotation(from);
var toVector = ShogiBoardState.FromBoardNotation(to);
var moveResult = rules.Move(fromVector, toVector, isPromotion);
if (!moveResult.Success)
{
return false;
throw new InvalidOperationException(moveResult.Reason);
}
var otherPlayer = WhoseTurn == WhichPlayer.Player1 ? WhichPlayer.Player2 : WhichPlayer.Player1;
if (EvaluateCheckAfterMove(move, otherPlayer))
var otherPlayer = board.WhoseTurn == WhichPlayer.Player1 ? WhichPlayer.Player2 : WhichPlayer.Player1;
if (rules.EvaluateCheckAfterMove(fromVector, toVector, otherPlayer))
{
InCheck = otherPlayer;
IsCheckmate = EvaluateCheckmate();
board.InCheck = otherPlayer;
board.IsCheckmate = rules.EvaluateCheckmate();
}
else
{
InCheck = null;
board.InCheck = null;
}
return true;
}
/// <summary>
/// Attempts a given move. Returns false if the move is illegal.
/// </summary>
private bool TryMove(Move move)
{
// Try making the move in a "throw away" board.
var simulator = new StandardRules(new ShogiBoardState(this.board));
///// <summary>
///// Attempts a given move. Returns false if the move is illegal.
///// </summary>
//private bool TryMove(Move move)
//{
// // Try making the move in a "throw away" board.
// var simulator = new StandardRules(new ShogiBoardState(this.board));
var simulatedMoveResults = move.PieceFromHand.HasValue
? simulator.PlaceFromHand(move)
: simulator.PlaceFromBoard(move);
if (!simulatedMoveResults)
{
// Surface the error description.
Error = simulationBoard.Error;
return false;
}
// If already in check, assert the move that resulted in check no longer results in check.
if (InCheck == WhoseTurn)
{
if (simulationBoard.EvaluateCheckAfterMove(MoveHistory[^1], WhoseTurn))
{
// Sneakily using this.WhoseTurn instead of validationBoard.WhoseTurn;
return false;
}
}
// var simulatedMoveResults = move.PieceFromHand.HasValue
// ? simulator.PlaceFromHand(move)
// : simulator.PlaceFromBoard(move);
// if (!simulatedMoveResults)
// {
// // Surface the error description.
// Error = simulationBoard.Error;
// return false;
// }
// // If already in check, assert the move that resulted in check no longer results in check.
// if (InCheck == WhoseTurn)
// {
// // Sneakily using this.WhoseTurn instead of validationBoard.WhoseTurn;
// if (simulationBoard.EvaluateCheckAfterMove(MoveHistory[^1], WhoseTurn))
// {
// return false;
// }
// }
// The move is valid and legal; update board state.
if (move.PieceFromHand.HasValue) PlaceFromHand(move);
else PlaceFromBoard(move);
return true;
}
// // The move is valid and legal; update board state.
// if (move.PieceFromHand.HasValue) PlaceFromHand(move);
// else PlaceFromBoard(move);
// return true;
//}
}
}