// Used more specifically to enforce board logic public bool DoesMoveLeaveUsInCheck(IBoardState <ChessPieceEntity> boardState, BoardMove move) { var attackingPlayer = boardState.GetItem(move.From).Item.Player; var clone = (IBoardState <ChessPieceEntity>)boardState.Clone(); _moveService.Move(clone, move); var king = clone.GetItems((int)attackingPlayer, (int)ChessPieceName.King).Single(); return(_playerStateService.IsLocationUnderCheck(clone, king.Location, king.Item.Player).result); }
private PlayerState CheckForCheckMate(IBoardState <ChessPieceEntity> boardState, LocatedItem <ChessPieceEntity> king, LocatedItem <ChessPieceEntity> attacker) { var state = PlayerState.Check; var clone = (IBoardState <ChessPieceEntity>)boardState.Clone(); // Find the attacking piece // Not sure why we need to refresh its piece paths here but I get problems with out it RefreshPiecePaths(clone, attacker); // find the path it's attacking on var attackPath = attacker.Paths.FirstOrDefault(p => p.ContainsTo(king.Location)); // Remove the king from the board so as to not have it's location block // attack paths from the new location clone.Remove(king.Location); var kingCannotMove = !king.Paths.Any() || king.Paths.FlattenMoves() .ToList() .All(m => IsLocationUnderCheck(clone, m.To, king.Item.Player).result); // // get all friendly pieces except king // refresh there paths var friendlyPieces = clone.GetItems(king.Item.Owner) .Where(p => p.Item.Piece != ChessPieceName.King) .OrderBy(p => p.Item.EntityType); // check if any friendly paths intersect the attackPath or attack the attacker var canBlock = friendlyPieces.Where(fp => fp.Paths.FlattenMoves() .Any(fm => attackPath .Any(am => am.To.Equals(fm.To) || am.From.Equals(fm.To) ) ) ); if (kingCannotMove && !canBlock.Any()) { return(PlayerState.Checkmate); } return(PlayerState.Check); }
// Typically only used to produce correct san notation on output public bool DoesMoveCauseCheck(IBoardState <ChessPieceEntity> boardState, BoardMove move) { // TODO: Would it be quicker to var attackingPlayer = boardState.GetItem(move.From).Item.Player; var defender = boardState.GetItem(move.To); if (defender != null && defender.Item.Is(attackingPlayer.Enemy(), ChessPieceName.King)) { return(true); } var clone = (IBoardState <ChessPieceEntity>)boardState.Clone(); _moveService.Move(clone, move); var king = clone.GetItems((int)attackingPlayer.Enemy(), (int)ChessPieceName.King).Single(); return(_playerStateService.IsLocationUnderCheck(clone, king.Location, king.Item.Player).result); }