Rules for the king, queen, rooks, and bishops

Let's first take a look at simple cases of orthogonally and diagonally moving chess pieces, which are the king, queen, rooks, and bishops. We need somehow to figure out a way to change the position of these chess pieces by using a mathematical rule.

The following diagram shows what it takes to move a chess piece from its current position (say x, y) both orthogonally and diagonally:

If you look at the preceding diagram, x represents the column number and y represents the row number. It is clear that we can represent the orthogonal movements by adding to the current position the items from the tuples (-1, 0), (0, 1), (1, 0), (0, -1).

Similarly, diagonal movements can be represented by adding to the tuples (-1, 1), (1, 1), (1, -1), (-1, -1).

Let's add these two tuples to configurations.py (see 4.04), as follows:

ORTHOGONAL_POSITIONS = ((-1,0),(0,1),(1,0),(0, -1))
DIAGONAL_POSITIONS = ((-1,-1),(-1,1),(1,-1),(1,1))

If a chess piece can move both orthogonally and diagonally, such as the queen, the representative tuple is simply an addition of the preceding two tuples.

If a chess piece can be moved by more than one square, it's simply a matter of multiplying the representative tuple by an integer to get all the other allowed positions on the chessboard.

With this information in mind, let's code a moves_available method that, given the current position of the chess piece, the directions tuple relevant to the chess piece, and the maximum distance that the chess piece can move, returns a list of all the allowed_moves, as follows (see 4.04piece.py):

def moves_available(self, current_position, directions,distance):
model = self.model
allowed_moves = []
piece = self
start_row, start_column = get_numeric_notation(current_position)
for x, y in directions:
collision = False
for step in range(1, distance + 1):
if collision: break
destination = start_row + step * x, start_column + step * y
if self.possible_position(destination) not in
model.all_occupied_positions():
allowed_moves.append(destination)
elif self.possible_position(destination) in
model.all_positions_occupied_by_color
(piece.color):
collision = True
else:
allowed_moves.append(destination)
collision = True
allowed_moves = filter(model.is_on_board, allowed_moves)
return map(model.get_alphanumeric_position, allowed_moves)

The following is a description of the preceding code:

  • Depending on the arguments, the method collects all the allowed moves for a given chess piece in a list named allowed_moves.
  • The code iterates through all the locations to detect a possible collision. If a collision is detected, it breaks out of the loop. Otherwise, it appends the coordinate to the allowed_moves list.
  • The second to last line filters out the moves that fall outside the chessboard, and the last line returns the equivalent position in alphanumeric notations for all the allowed moves.

We can also define a few helper methods to support the preceding method, as follows:

def possible_position(self, destination): #4.04 piece.py
return self.model.get_alphanumeric_position(destination)

def all_positions_occupied_by_color(self, color): #4.04 model.py
result = []
for position in self.keys():
piece = self.get_piece_at(position)
if piece.color == color:
result.append(position)
return result

def all_occupied_positions(self): #4.04 model.py
return self.all_positions_occupied_by_color('white') +
self.all_positions_occupied_by_color('black')

Next, let's modify the Piece child classes of king, queen, rooks, and bishops as follows (see 4.04piece.py):

class King(Piece):
directions = ORTHOGONAL_POSITIONS + DIAGONAL_POSITIONS
max_distance = 1

def moves_available(self,current_position):
return super().moves_available(current_position, self.directions, self.max_distance)

class Queen(Piece):
directions = ORTHOGONAL_POSITIONS + DIAGONAL_POSITIONS
max_distance = 8

def moves_available(self,current_position):
return super(Queen, self).moves_available
(current_position, self.directions, self.max_distance)

class Rook(Piece):
directions = ORTHOGONAL_POSITIONS
max_distance = 8

def moves_available(self,current_position):
return super(Rook, self).moves_available(current_position,
self.directions, self.max_distance)

class Bishop(Piece):
directions = DIAGONAL_POSITIONS
max_distance = 8

def moves_available(self,current_position):
return super(Bishop, self).moves_available
(current_position, self.directions, self.max_distance)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.119.170