private void AddDirectionalThreats( Board board, Player player, BoardLocation playerKingLocation, BoardLocation opposingPieceBoardLocation, Direction direction, ThreatMatrix threatMatrix) { //get the next square in the given direction BoardLocation?currentLocation = opposingPieceBoardLocation.Neighbor(direction); //for directional threats the king might be pinned... var kingCouldBePinned = playerKingLocation.IsInGivenDirectionFrom(opposingPieceBoardLocation, direction); var threatDirection = direction.ToThreatDirection(); while (currentLocation != null) { //get the piece var piece = board[currentLocation.Value]; //as long as we are empty we can keep moving! if (piece == ChessPiece.None) { //empty square, no pin possible AddThreat(threatMatrix, playerKingLocation, opposingPieceBoardLocation, currentLocation.Value, threatDirection); } else { ThreatDirection?pinDirection = null; //our piece which MIGHT have a pin if our king is on the same directional vector..check for it if ((piece.BelongsTo(player)) && (kingCouldBePinned) && PieceIsPinned(board, currentLocation.Value, playerKingLocation, direction)) { pinDirection = direction.ToThreatDirection(); } AddThreat( threatMatrix, playerKingLocation, opposingPieceBoardLocation, currentLocation.Value, threatDirection, pinDirection); //NOTE: This is a hack, but its a domain hack. From a threat perspective, we can pretend //that the enemy king is 'invisible'. This will allow long range threats to penetrate the king //and proceed to any columns, rows, or diagonals he is on. This in turn will help us //when determining the kings moves by making 'backing up' an invalid strategy for him. //without this check, a king himself would demarcate the end of a long range threat (since a piece is like a stop) //but THAT would create the problem of making it seem like the square behind him was 'safe'. For Example: // | | | | | | | | | | // | |WR|BK| | To=> | |WR| |BK| would be allowed // | | | | | | | | | | //Where it is kind of a hack is by treating the king as invisible it means the white rook is threatening //'beyond' a piece. Theoretically, this would then also allow it to move into those spaces, in essence just //'hoping over' the king. This would be a HUGE problem if not for the golden rule of chess that it is impossible //to make a move that actually captures a king. The game literally ends as soon as a board state emerges where //a king is able to captured on the next turn. Not sure why this is, I am sure it harkens back to some //haughty rule about how 'ignoble' it would be to ever allow the capture of a royal. if (piece.IsKing(player) == false) { //short circuit search since we are done break; } } currentLocation = currentLocation.Neighbor(direction); } }