def set_board(self): for board_file in BOARD_FILES: file_ = board_file[0] white_pawn = Piece() white_pawn.color = Piece.WHITE white_pawn.name = Piece.PAWN self.square(file_, 2).piece = white_pawn for board_file in BOARD_FILES: file_ = board_file[0] black_pawn = Piece() black_pawn.color = Piece.BLACK black_pawn.name = Piece.PAWN self.square(file_, 7).piece = black_pawn for board_file in BOARD_FILES: file_ = board_file[0] white_piece = Piece() white_piece.color = Piece.WHITE white_piece.name = board_file[1] self.square(file_, 1).piece = white_piece black_piece = Piece() black_piece.color = Piece.BLACK black_piece.name = board_file[1] self.square(file_, 8).piece = black_piece for board_file in BOARD_FILES: file_ = board_file[0] self.square(file_, 3).piece = None self.square(file_, 4).piece = None self.square(file_, 5).piece = None self.square(file_, 6).piece = None
def get_attackers(self, color, square): """Gets the attackers of a specific square. :param color: Filter attackers by this piece color. :param square: The square to check for. :yield: Source squares of the attack. """ if not color in [BLACK, WHITE]: raise KeyError("Invalid color: %s." % repr(color)) for x88, source in Square._x88_squares.iteritems(): piece = self._pieces[x88] if not piece or Piece.color(piece) != color: continue difference = x88 - square._x88 index = difference + X88.ATTACKER_DIFF klass = Piece.klass(piece) if X88.ATTACKS[index] & (1 << X88.SHIFTS[klass]): # Handle pawns. if klass == PAWN: if difference > 0: if Piece.color(piece) == WHITE: yield source else: if Piece.color(piece) == BLACK: yield source continue # Handle knights and king. if klass in [KNIGHT, KING]: yield source # Handle the others. offset = X88.RAYS[index] j = source._x88 + offset blocked = False while j != square._x88: if self._pieces[j]: blocked = True break j += offset if not blocked: yield source
def get_piece_counts(self, colors=[WHITE, BLACK]): """Counts the pieces on the board. :param color: list of colors to check. Defualts to black and white :return: A dictionary of piece counts, keyed by lowercase piece type letters. """ #if not color in ["w", "b", "wb", "bw"]: # raise KeyError( # "Expected color filter to be one of 'w', 'b', 'wb', 'bw', " # "got: %s." % repr(color)) counts = { PAWN: 0, BISHOP: 0, KNIGHT: 0, ROOK: 0, KING: 0, QUEEN: 0, } for piece in self._pieces: if piece and Piece.color(piece) in colors: counts[Piece.klass(piece)] += 1 return counts
def get_pseudo_legal_moves(self, source=None): """:yield: Pseudo legal moves in the current position. :param source: The source square to limit moves or None for all possible moves. """ tomove = self.fen._to_move for x88 in [ x88 for x88 in Square._x88_squares.keys() if self._pieces[x88] and Piece.color(self._pieces[x88]) == tomove and (source is None or x88 == source._x88) ]: piece = self._pieces[x88] klass = Piece.klass(piece) # pawn moves if klass == PAWN: single, double, capleft, capright = X88.PAWN_OFFSETS[tomove] # Single square ahead. Do not capture. offset = x88 + single if not self._pieces[offset]: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # Two squares ahead. Do not capture. if X88.is_secondrank(x88, tomove): offset = x88 + double if not self._pieces[offset]: yield Move.from_x88(x88, offset) # Pawn captures. for cap in [capleft, capright]: offset = x88 + cap if offset & X88.X88: continue target = self._pieces[offset] if target and Piece.color(target) != tomove: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # En-passant. elif not target and offset == self.fen._ep: yield Move.from_x88(target, self.fen._ep) #piece moves else: # for each a direction a piece moves in for offset in X88.PIECE_OFFSETS[Piece.klass(piece)]: t_x88 = x88 + offset # while we do not fall off the board while not t_x88 & 0x88: # if there was not piece to attack then yield a quiet move if not self._pieces[t_x88]: yield Move.from_x88(x88, t_x88) # do not break out # else there is a piece there else: # if we can attack generate a move if Piece.color(self._pieces[t_x88]) != tomove: yield Move.from_x88(x88, t_x88) # we hit something so break out break # Knight and king do not go multiple times in their direction. if klass in [KNIGHT, KING]: break # travel down the board in the direction t_x88 += offset # castling moves opponent = Piece.opposite_color(tomove) ok = True # get possible castling for the side to move for castle in [ c for c in self.fen._castle_rights if Piece.color(c) == tomove ]: (square, enum), _ = Piece.castle_squares[castle] king = Square(square) if Piece.klass(castle) == KING: direc = 1 else: direc = -1 # for offset in the squares the king will travel for offset in range(0, 3): s = Square.from_x88(king._x88 + (offset * direc)) # if we are not the king square and we are occuppied if offset and self._pieces[s._x88]: ok = False break # if we are trying to travel through check if self.is_attacked(opponent, s): ok = False break # kludge: we have to check occupancy for one more square on the queen side if direc == -1 and self._pieces[s._x88 - 1]: ok = False if ok: yield Move(king, s)
def get_pseudo_legal_moves(self, source=None): """:yield: Pseudo legal moves in the current position. :param source: The source square to limit moves or None for all possible moves. """ tomove = self.fen._to_move for x88 in [ x88 for x88 in Square._x88_squares.keys() if self._pieces[x88] and Piece.color(self._pieces[x88]) == tomove and (source is None or x88 == source._x88)]: piece = self._pieces[x88] klass = Piece.klass(piece) # pawn moves if klass == PAWN: single, double, capleft, capright = X88.PAWN_OFFSETS[tomove] # Single square ahead. Do not capture. offset = x88 + single if not self._pieces[offset]: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # Two squares ahead. Do not capture. if X88.is_secondrank(x88, tomove): offset = x88 + double if not self._pieces[offset]: yield Move.from_x88(x88, offset) # Pawn captures. for cap in [capleft, capright]: offset = x88 + cap if offset & X88.X88: continue target = self._pieces[offset] if target and Piece.color(target) != tomove: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # En-passant. elif not target and offset == self.fen._ep: yield Move.from_x88(target, self.fen._ep) #piece moves else: # for each a direction a piece moves in for offset in X88.PIECE_OFFSETS[Piece.klass(piece)]: t_x88 = x88 + offset # while we do not fall off the board while not t_x88 & 0x88: # if there was not piece to attack then yield a quiet move if not self._pieces[t_x88]: yield Move.from_x88(x88, t_x88) # do not break out # else there is a piece there else: # if we can attack generate a move if Piece.color(self._pieces[t_x88]) != tomove: yield Move.from_x88(x88, t_x88) # we hit something so break out break # Knight and king do not go multiple times in their direction. if klass in [KNIGHT, KING]: break # travel down the board in the direction t_x88 += offset # castling moves opponent = Piece.opposite_color(tomove) ok = True # get possible castling for the side to move for castle in [c for c in self.fen._castle_rights if Piece.color(c) == tomove]: (square, enum), _ = Piece.castle_squares[castle] king = Square(square) if Piece.klass(castle) == KING: direc = 1 else: direc = -1 # for offset in the squares the king will travel for offset in range(0, 3): s = Square.from_x88(king._x88 + (offset * direc)) # if we are not the king square and we are occuppied if offset and self._pieces[s._x88]: ok = False break # if we are trying to travel through check if self.is_attacked(opponent, s): ok = False break # kludge: we have to check occupancy for one more square on the queen side if direc == -1 and self._pieces[s._x88 - 1]: ok = False if ok: yield Move(king, s)
def test_color(self): self.assertEqual(piece.WHITE, Piece.color('P')) self.assertEqual(piece.BLACK, Piece.color('p'))