yep
This commit is contained in:
@@ -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;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user