I am trying to understand the algorithms behind determining valid moves for each chess piece. The specific issue I am having is determining when a piece cannot move past a certain point because it is being blocked by a piece of its own colour or is able to take a piece of the opposite colour but cannot move past that point.
The simple algorithms I have for each piece are:
Valid King move, if the piece moves from (X1, Y1) to (X2, Y2), the move is valid if and only if |X2-X1|<=1 and |Y2-Y1|<=1.
Valid Bishop move, if the piece moves from (X1, Y1) to (X2, Y2), the move is valid if and only if |X2-X1|=|Y2-Y1|.
Valid Rook move, if the piece moves from (X1, Y1) to (X2, Y2), the move is valid if and only if X2=X1 or Y2=Y1.
Valid Queen move, a queen's move is valid if it is either a valid bishop or rook move.
Valid Knight move, if the piece moves from (X1, Y1) to (X2, Y2), the move is valid if and only if (|X2-X1|=1 and |Y2-Y1|=2) or (|X2-X1|=2 and |Y2-Y1|=1).
Valid Pawn move, if the piece moves from (X1, Y1) to (X2, Y2), the move is valid if and only if X2=X1 and Y2-Y1=1 (only for a white pawn).
Any advice would be appreciated.
You need to take the board state into account for that. I think the common way to do it would be checking if each cell on the path is empty or not.
public enum PieceColor { Black, White }
public interface IBoard
{
bool IsEmpty(int x, int y);
PieceColor GetPieceColor(int x, int y);
}
IBoard board;
bool BishopCanMove(PieceColor bishopColor, int fromX, int fromY, int toX, int toY)
{
int pathLength = Mathf.Abs(toX - fromX);
if (pathLength != Mathf.Abs(toY - fromY)) return false; // Not diagonal
// Also validate if the coordinates are in the 0-7 range
// Check all cells before the target
for (int i = 1; i < pathLength; i++)
{
int x = fromX + i;
int y = fromY + i;
if(board.IsEmpty(x, y)) continue; // No obstacles here: keep going
else return false; // Obstacle found before reaching target: the move is invalid
}
// Check target cell
if (board.IsEmpty(toX, toY)) return true; // No piece: move is valid
// There's a piece here: the move is valid only if we can capture
return board.GetPieceColor(toX, toY) == bishopColor;
}
The IBoard
interface is there just to show the point. You should have a board state exposing those informations in some way.