End Game Position: "8/2R2pk1/2P5/2r5/1p6/1P2Pq2/8/2K1B3 w - - 5 44"
Search Depth: 5
Nodes searched: 12370
Probes: 324398
Hits: 271702
Writes: 52696
Overwites: 19316
*Opening Position*
Search depth : 5
Nodes searched: 10974
Probes: 120935
Hits: 98987
Writes: 21948
Overwites: 4012
"QueryandCachePlayerInCheckStatusForPosition" is called from 14 places in the source code. 12 places inside the alpha beta loop.
It would probably be more optimal to calculate and store the check status for each side when a move is generated, then store those values as a couple Booleans on the move class. The move class itself might still intially query the Check Hash Table, in order to sets its intial values. I wager that would dramtically reduce the number of Probes. It would require some restructuring, as the Check status is a property of a player.
Out of interest, I've attached the code that determines if the player is in check.
From the PieceKing class:
- Code: Select all
public bool DetermineCheckStatus()
{
return this.Base.Square.PlayerCanAttackSquare(this.Base.Player.OpposingPlayer);
}
From the Square class:
- Code: Select all
/// <summary>
/// Determines whether the specified player can attack this square.
/// </summary>
/// <param name="player">
/// The player being tested.
/// </param>
/// <returns>
/// True if player can move a piece to this square.
/// </returns>
public bool PlayerCanAttackSquare(Player player)
{
Piece piece;
// Pawn
piece = Board.GetPiece(this.Ordinal - player.PawnAttackLeftOffset);
if (piece != null && piece.Name == Piece.PieceNames.Pawn && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - player.PawnAttackRightOffset);
if (piece != null && piece.Name == Piece.PieceNames.Pawn && piece.Player.Colour == player.Colour)
{
return true;
}
// Knight
piece = Board.GetPiece(this.Ordinal + 33);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 18);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 14);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 31);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 33);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 18);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 14);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 31);
if (piece != null && piece.Name == Piece.PieceNames.Knight && piece.Player.Colour == player.Colour)
{
return true;
}
// Bishop & Queen
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Bishop, this, 15) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Bishop, this, 17) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Bishop, this, -15) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Bishop, this, -17) != null)
{
return true;
}
// Rook & Queen
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Rook, this, 1) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Rook, this, -1) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Rook, this, 16) != null)
{
return true;
}
if (Board.LinesFirstPiece(player.Colour, Piece.PieceNames.Rook, this, -16) != null)
{
return true;
}
// King!
piece = Board.GetPiece(this.Ordinal + 16);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 17);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 1);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 15);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 16);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 17);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal - 1);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
piece = Board.GetPiece(this.Ordinal + 15);
if (piece != null && piece.Name == Piece.PieceNames.King && piece.Player.Colour == player.Colour)
{
return true;
}
return false;
}
From the Board class:
- Code: Select all
/// <summary>
/// Returns the first piece found in a vector from the specified Square.
/// </summary>
/// <param name="colour">
/// The colour.
/// </param>
/// <param name="pieceName">
/// The piece name.
/// </param>
/// <param name="squareStart">
/// The square start.
/// </param>
/// <param name="vectorOffset">
/// The vector offset.
/// </param>
/// <returns>
/// The first piece on the line, or null.
/// </returns>
public static Piece LinesFirstPiece(
Player.PlayerColourNames colour, Piece.PieceNames pieceName, Square squareStart, int vectorOffset)
{
int intOrdinal = squareStart.Ordinal;
Square square;
intOrdinal += vectorOffset;
while ((square = GetSquare(intOrdinal)) != null)
{
if (square.Piece == null)
{
}
else if (square.Piece.Player.Colour != colour)
{
return null;
}
else if (square.Piece.Name == pieceName || square.Piece.Name == Piece.PieceNames.Queen)
{
return square.Piece;
}
else
{
return null;
}
intOrdinal += vectorOffset;
}
return null;
}