Example #1
0
 def get_all(cls):
     '''Yield all moves combinations that do not have promotion.'''
     #FIXME add in promotion
     
     for source in Square.get_all():
         for target in Square.get_all():
             if source != target:
                 move = cls(Square.from_x88(source.x88), Square.from_x88(target.x88))
                 yield(move)
Example #2
0
    def get_king(self, color):
        """Gets the square of the king.

        :param color:
            `"w"` for the white players king. `"b"` for the black
            players king.

        :return:
            The first square with a matching king or `None` if that
            player has no king.
        """
        #if not color in ["w", "b"]:
        #   raise KeyError("Invalid color: %s." % repr(color))

        for square, piece in [(s, self._pieces[s._x88]) for s in Square.get_all() if self._pieces[s._x88]]:
            if Piece.is_klass_and_color(piece, KING, color):
                return square
Example #3
0
    def is_insufficient_material(self):
        """Checks if there is sufficient material to mate.

        Mating is impossible in:

        * A king versus king endgame.
        * A king with bishop versus king endgame.
        * A king with knight versus king endgame.
        * A king with bishop versus king with bishop endgame, where both
          bishops are on the same color. Same goes for additional
          bishops on the same color.

        Assumes that the position is valid and each player has exactly
        one king.

        :return:
            Whether there is insufficient material to mate.
        """
        piece_counts = self.get_piece_counts()

        # King versus king.
        if sum(piece_counts.values()) == 2:
            return True

        # King and knight or bishop versus king.
        elif sum(piece_counts.values()) == 3:
            if piece_counts["b"] == 1 or piece_counts["n"] == 1:
                return True

        # Each player with only king and any number of bishops,
        # where all bishops are on the same color.
        elif sum(piece_counts.values()) == 2 + piece_counts[BISHOP]:
            white_has_bishop = self.get_piece_counts([WHITE])[BISHOP] != 0
            black_has_bishop = self.get_piece_counts([BLACK])[BISHOP] != 0
            if white_has_bishop and black_has_bishop:
                color = None
                for square in Square.get_all():
                    p = self._pieces[square._x88]
                    if p and Piece.klass(p) == BISHOP:
                        if color and color != square.is_light():
                            return False
                        color = square.is_light()
                return True
        return False
Example #4
0
    def is_insufficient_material(self):
        """Checks if there is sufficient material to mate.

        Mating is impossible in:

        * A king versus king endgame.
        * A king with bishop versus king endgame.
        * A king with knight versus king endgame.
        * A king with bishop versus king with bishop endgame, where both
          bishops are on the same color. Same goes for additional
          bishops on the same color.

        Assumes that the position is valid and each player has exactly
        one king.

        :return:
            Whether there is insufficient material to mate.
        """
        piece_counts = self.get_piece_counts()

        # King versus king.
        if sum(piece_counts.values()) == 2:
            return True

        # King and knight or bishop versus king.
        elif sum(piece_counts.values()) == 3:
            if piece_counts["b"] == 1 or piece_counts["n"] == 1:
                return True

        # Each player with only king and any number of bishops, 
        # where all bishops are on the same color.
        elif sum(piece_counts.values()) == 2 + piece_counts[BISHOP]:
            white_has_bishop = self.get_piece_counts([WHITE])[BISHOP] != 0
            black_has_bishop = self.get_piece_counts([BLACK])[BISHOP] != 0
            if white_has_bishop and black_has_bishop:
                color = None
                for square in Square.get_all():
                    p = self._pieces[square._x88]
                    if p and Piece.klass(p) == BISHOP:
                        if color and color != square.is_light():
                            return False
                        color = square.is_light()
                return True
        return False
Example #5
0
    def get_king(self, color):
        """Gets the square of the king.

        :param color:
            `"w"` for the white players king. `"b"` for the black
            players king.

        :return:
            The first square with a matching king or `None` if that
            player has no king.
        """
        #if not color in ["w", "b"]:
        #   raise KeyError("Invalid color: %s." % repr(color))

        for square, piece in [(s, self._pieces[s._x88])
                              for s in Square.get_all()
                              if self._pieces[s._x88]]:
            if Piece.is_klass_and_color(piece, KING, color):
                return square
Example #6
0
    def hash_position(self, position):
        """Computes the Zobrist hash of a position.

        :param position:
            The position to hash.

        :return:
            The hash as an integer.
        """
        key = 0

        # Hash in the board setup.
        for square in Square.get_all():
            piece = position[square]
            if piece:
                i = "pPnNbBrRqQkK".index(piece.symbol)
                key ^= self.__random_array[64 * i + 8 * square.y + square.x]

        # Hash in the castling flags.
        if position.get_castling_right("K"):
            key ^= self.__random_array[768]
        if position.get_castling_right("Q"):
            key ^= self.__random_array[768 + 1]
        if position.get_castling_right("k"):
            key ^= self.__random_array[768 + 2]
        if position.get_castling_right("q"):
            key ^= self.__random_array[768 + 3]

        # Hash in the en-passant file.
        if (position.ep_file
                and position.get_theoretical_ep_right(position.ep_file)):
            i = ord(position.ep_file) - ord("a")
            key ^= self.__random_array[772 + i]

        # Hash in the turn.
        if position.turn == "w":
            key ^= self.__random_array[780]

        return key
Example #7
0
    def hash_position(self, position):
        """Computes the Zobrist hash of a position.

        :param position:
            The position to hash.

        :return:
            The hash as an integer.
        """
        key = 0

        # Hash in the board setup.
        for square in Square.get_all():
            piece = position[square]
            if piece:
                i = "pPnNbBrRqQkK".index(piece.symbol)
                key ^= self.__random_array[64 * i + 8 * square.y + square.x]

        # Hash in the castling flags.
        if position.get_castling_right("K"):
            key ^= self.__random_array[768]
        if position.get_castling_right("Q"):
            key ^= self.__random_array[768 + 1]
        if position.get_castling_right("k"):
            key ^= self.__random_array[768 + 2]
        if position.get_castling_right("q"):
            key ^= self.__random_array[768 + 3]

        # Hash in the en-passant file.
        if (position.ep_file and
               position.get_theoretical_ep_right(position.ep_file)):
            i = ord(position.ep_file) - ord("a")
            key ^= self.__random_array[772 + i]

        # Hash in the turn.
        if position.turn == "w":
            key ^= self.__random_array[780]

        return key
Example #8
0
def gen_moves():
    for source in Square.get_all():
        for target in Square.get_all():
            if target != source:
                yield (Move(source, target))
Example #9
0
	def test_get_all(self):
		for idx, square in enumerate(Square.get_all()):
			pass
		total = len(Square.ranks) * len(Square.files)
		self.assertEqual(total - 1, idx)
Example #10
0
	def test___hash__(self):
		d = {}
		for square in Square.get_all():
			d[hash(square)] = None
		total = len(Square.ranks) * len(Square.files)
		self.assertEqual(total, len(d))
Example #11
0
def gen_moves():
    for source in Square.get_all():
        for target in Square.get_all():
            if target != source:
                yield(Move(source, target))