namespace Shogi.Domain { /// /// Facilitates Shogi board state transitions, cognisant of Shogi rules. /// The board is always from Player1's perspective. /// [0,0] is the lower-left position, [8,8] is the higher-right position /// public sealed class Shogi { private readonly ShogiBoardState board; private readonly StandardRules rules; public string Error { get; private set; } public Shogi(ShogiBoardState board) { this.board = board; rules = new StandardRules(this.board); } //public Shogi(IList 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) { var simulator = new StandardRules(new ShogiBoardState(board)); return simulator.Move(from, to, isPromotion); } public MoveResult CanMove(WhichPiece pieceInHand, string to) { var simulator = new StandardRules(new ShogiBoardState(board)); return simulator.Move(pieceInHand, to); } public void Move(string from, string to, bool isPromotion) { var fromVector = ShogiBoardState.FromBoardNotation(from); var toVector = ShogiBoardState.FromBoardNotation(to); var moveResult = rules.Move(from, to, isPromotion); if (!moveResult.Success) { throw new InvalidOperationException(moveResult.Reason); } var otherPlayer = board.WhoseTurn == WhichPlayer.Player1 ? WhichPlayer.Player2 : WhichPlayer.Player1; if (rules.EvaluateCheckAfterMove(fromVector, toVector, otherPlayer)) { board.InCheck = otherPlayer; board.IsCheckmate = rules.EvaluateCheckmate(); } else { board.InCheck = null; } board.WhoseTurn = otherPlayer; } ///// ///// Attempts a given move. Returns false if the move is illegal. ///// //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) // { // // 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; //} } }