Example #1
0
 def generate_pseudo_legal_drops(self, to_mask=chess.BB_ALL):
     to_mask = to_mask & ~self.occupied
     to_square = chess.bit_scan(to_mask)
     while to_square != -1 and to_square is not None:
         for pt, count in self.pockets[self.turn].pieces.items():
             if count and (pt != chess.PAWN or not chess.BB_BACKRANKS & chess.BB_SQUARES[to_square]):
                 yield chess.Move(to_square, to_square, drop=pt)
         to_square = chess.bit_scan(to_mask, to_square + 1)
Example #2
0
 def generate_pseudo_legal_drops(self, to_mask=chess.BB_ALL):
     to_mask = to_mask & ~self.occupied
     to_square = chess.bit_scan(to_mask)
     while to_square != -1 and to_square is not None:
         for pt, count in self.pockets[self.turn].pieces.items():
             if count and (pt != chess.PAWN or not chess.BB_BACKRANKS & chess.BB_SQUARES[to_square]):
                 yield chess.Move(to_square, to_square, drop=pt)
         to_square = chess.bit_scan(to_mask, to_square + 1)
Example #3
0
    def _kings_connected(self):
        kings = self.kings & self.occupied_co[chess.WHITE]
        king_square = chess.bit_scan(kings)
        while king_square != -1 and king_square is not None:
            if chess.BB_KING_ATTACKS[king_square] & self.kings & self.occupied_co[chess.BLACK]:
                return True

            king_square = chess.bit_scan(kings, king_square + 1)

        return False
Example #4
0
    def _attacked_for_king(self, path):
        # Can castle onto attacked squares if they are connected to the
        # enemy king.
        enemy_kings = self.kings & self.occupied_co[not self.turn]
        enemy_king = chess.bit_scan(enemy_kings)
        while enemy_king != -1 and enemy_king is not None:
            path &= ~chess.BB_KING_ATTACKS[enemy_king]
            enemy_king = chess.bit_scan(enemy_kings, enemy_king + 1)

        return super(AtomicBoard, self)._attacked_for_king(path)
Example #5
0
    def _push_capture(self, move, capture_square, piece_type, was_promoted):
        # Explode the capturing piece.
        self._remove_piece_at(move.to_square)

        # Explode all non pawns around.
        explosion_radius = chess.BB_KING_ATTACKS[capture_square] & ~self.pawns
        explosion = chess.bit_scan(explosion_radius)
        while explosion != -1 and explosion is not None:
            self._remove_piece_at(explosion)
            explosion = chess.bit_scan(explosion_radius, explosion + 1)
Example #6
0
    def _attacked_for_king(self, path):
        # Can castle onto attacked squares if they are connected to the
        # enemy king.
        enemy_kings = self.kings & self.occupied_co[not self.turn]
        enemy_king = chess.bit_scan(enemy_kings)
        while enemy_king != -1 and enemy_king is not None:
            path &= ~chess.BB_KING_ATTACKS[enemy_king]
            enemy_king = chess.bit_scan(enemy_kings, enemy_king + 1)

        return super(AtomicBoard, self)._attacked_for_king(path)
Example #7
0
    def _kings_connected(self):
        kings = self.kings & self.occupied_co[chess.WHITE]
        king_square = chess.bit_scan(kings)
        while king_square != -1 and king_square is not None:
            if chess.BB_KING_ATTACKS[king_square] & self.kings & self.occupied_co[chess.BLACK]:
                return True

            king_square = chess.bit_scan(kings, king_square + 1)

        return False
Example #8
0
    def _push_capture(self, move, capture_square, piece_type, was_promoted):
        # Explode the capturing piece.
        self._remove_piece_at(move.to_square)

        # Explode all non pawns around.
        explosion_radius = chess.BB_KING_ATTACKS[move.to_square] & ~self.pawns
        explosion = chess.bit_scan(explosion_radius)
        while explosion != -1 and explosion is not None:
            self._remove_piece_at(explosion)
            explosion = chess.bit_scan(explosion_radius, explosion + 1)

        # Destroy castling rights.
        self.castling_rights &= ~explosion_radius
Example #9
0
    def legal_drop_squares_mask(self):
        king_bb = self.kings & self.occupied_co[self.turn]
        king_square = chess.bit_scan(king_bb)
        if king_square is None or king_square == -1:
            return ~self.occupied

        king_attackers = self.attackers_mask(not self.turn, king_square)
        num_attackers = chess.pop_count(king_attackers)

        if num_attackers == 0:
            return ~self.occupied
        elif num_attackers == 1:
            king_rank_mask = chess.RANK_MASK[king_bb]
            king_file_mask = chess.FILE_MASK[king_bb]
            king_diag_ne = chess.DIAG_MASK_NE[king_bb]
            king_diag_nw = chess.DIAG_MASK_NW[king_bb]

            if king_rank_mask == chess.RANK_MASK[king_attackers]:
                rank_pieces = king_rank_mask & self.occupied
                return chess.RANK_ATTACKS[king_bb][rank_pieces] & ~self.occupied & chess.RANK_ATTACKS[king_attackers][rank_pieces]
            elif king_file_mask == chess.FILE_MASK[king_attackers]:
                file_pieces = king_file_mask & self.occupied
                return chess.FILE_ATTACKS[king_bb][file_pieces] & ~self.occupied & chess.FILE_ATTACKS[king_attackers][file_pieces]
            elif king_diag_ne == chess.DIAG_MASK_NE[king_attackers]:
                ne_pieces = king_diag_ne & self.occupied
                return chess.DIAG_ATTACKS_NE[king_bb][ne_pieces] & ~self.occupied & chess.DIAG_ATTACKS_NE[king_attackers][ne_pieces]
            elif king_diag_nw == chess.DIAG_MASK_NW[king_attackers]:
                nw_pieces = king_diag_nw & self.occupied
                return chess.DIAG_ATTACKS_NW[king_bb][nw_pieces] & ~self.occupied & chess.DIAG_ATTACKS_NW[king_attackers][nw_pieces]

        return chess.BB_VOID
Example #10
0
    def legal_drop_squares_mask(self):
        king_bb = self.kings & self.occupied_co[self.turn]
        king_square = chess.bit_scan(king_bb)
        if king_square is None or king_square == -1:
            return ~self.occupied

        king_attackers = self.attackers_mask(not self.turn, king_square)
        num_attackers = chess.pop_count(king_attackers)

        if num_attackers == 0:
            return ~self.occupied
        elif num_attackers == 1:
            king_rank_mask = chess.RANK_MASK[king_bb]
            king_file_mask = chess.FILE_MASK[king_bb]
            king_diag_ne = chess.DIAG_MASK_NE[king_bb]
            king_diag_nw = chess.DIAG_MASK_NW[king_bb]

            if king_rank_mask == chess.RANK_MASK[king_attackers]:
                rank_pieces = king_rank_mask & self.occupied
                return chess.RANK_ATTACKS[king_bb][rank_pieces] & ~self.occupied & chess.RANK_ATTACKS[king_attackers][rank_pieces]
            elif king_file_mask == chess.FILE_MASK[king_attackers]:
                file_pieces = king_file_mask & self.occupied
                return chess.FILE_ATTACKS[king_bb][file_pieces] & ~self.occupied & chess.FILE_ATTACKS[king_attackers][file_pieces]
            elif king_diag_ne == chess.DIAG_MASK_NE[king_attackers]:
                ne_pieces = king_diag_ne & self.occupied
                return chess.DIAG_ATTACKS_NE[king_bb][ne_pieces] & ~self.occupied & chess.DIAG_ATTACKS_NE[king_attackers][ne_pieces]
            elif king_diag_nw == chess.DIAG_MASK_NW[king_attackers]:
                nw_pieces = king_diag_nw & self.occupied
                return chess.DIAG_ATTACKS_NW[king_bb][nw_pieces] & ~self.occupied & chess.DIAG_ATTACKS_NW[king_attackers][nw_pieces]

        return chess.BB_VOID
Example #11
0
    def is_variant_end(self):
        if not self.kings & chess.BB_RANK_8:
            return False

        if self.turn == chess.WHITE or self.kings & self.occupied_co[
                chess.BLACK] & chess.BB_RANK_8:
            return True

        black_king = chess.bit_scan(self.kings & self.occupied_co[chess.BLACK])
        if black_king is None or black_king == -1:
            return True

        # White has reached the backrank. The game is over if black can not
        # also reach the backrank on the next move. Check if there are any
        # safe squares for the king.
        targets = chess.BB_KING_ATTACKS[black_king] & chess.BB_RANK_8
        target = chess.bit_scan(targets)
        while target != -1 and target is not None:
            if not self.attackers_mask(chess.WHITE, target):
                return False
            target = chess.bit_scan(targets, target + 1)

        return True
Example #12
0
    async def update_match_embed(self,
                                 *,
                                 flipped=None,
                                 footer_text=discord.Embed.Empty):
        if flipped is None: flipped = not self.turn
        # svg = self._repr_svg_()
        svg = chess.svg.board(
            self,
            lastmove=self.peek() if self.move_stack else None,
            check=chess.bit_scan(self.kings & self.occupied_co[self.turn])
            if self.is_check() else None,
            flipped=flipped)
        svg = svg.replace("y=\"390\"", "y=\"395\"")
        svg = svg.replace("class=\"square light",
                          "fill=\"#ffce9e\" class=\"square light")
        svg = svg.replace("class=\"square dark",
                          "fill=\"#d18b47\" class=\"square dark")
        svg = svg.replace("class=\"check",
                          "fill=\"url(#check_gradient)\" class=\"check")
        svg = svg.replace(
            "<stop offset=\"100%\" stop-color=\"rgba(158, 0, 0, 0)\" />",
            "<stop offset=\"100%\" stop-color=\"rgba(158, 0, 0, 0)\" stop-opacity=\"0\" />"
        )
        svg = re.subn(
            r"fill=\"#ffce9e\" class=\"square light [a-h][1-8] lastmove\"",
            lambda m: m.group(0).replace("ffce9e", "cdd16a"), svg)[0]
        svg = re.subn(
            r"fill=\"#d18b47\" class=\"square dark [a-h][1-8] lastmove\"",
            lambda m: m.group(0).replace("d18b47", "aaa23b"), svg)[0]
        with open("data/temp/chess_board.svg", 'w') as image:
            print(svg, file=image)
        with Image(filename="data/temp/chess_board.svg") as img:
            img.format = "png"
            img.save(filename="data/temp/chess_board.png")
        # asyncio.sleep(0.2) # necessary?, wasn't even awaited
        if not self.match_embed:
            self.match_embed = discord.Embed(color=clients.bot_color)
        '''
		with open("data/temp/chess_board.png", "rb") as image:
			request = requests.post("http://uploads.im/api", files = {"upload": image})
			# import aiohttp
			# data = aiohttp.helpers.FormData()
			# data.add_field("upload", image, filename = "chess_board.png")
			# async with clients.aiohttp_session.post("http://uploads.im/api", data = data) as resp:
				# data = await resp.text()
		try:
			data = request.json()
		except:
			print(request.text)
			return
		if data["status_code"] == 403:
			await self.bot.send_embed(self.text_channel, ":no_entry: Error: {}".format(data["status_txt"]))
			return
		# self.match_embed.set_image(url = clients.imgur_client.upload_from_path("data/temp/chess_board.png")["link"])
		self.match_embed.set_image(url = data["data"]["img_url"])
		'''
        cache_channel = self.bot.get_channel(clients.cache_channel_id)
        with open("data/temp/chess_board.png", "rb") as image:
            image_message = await self.bot.send_file(cache_channel, image)
        self.match_embed.set_image(url=image_message.attachments[0]["url"])
        self.match_embed.set_footer(text=footer_text)
        chess_pgn = chess.pgn.Game.from_board(self)
        chess_pgn.headers["Site"] = "Discord"
        chess_pgn.headers["Date"] = datetime.datetime.utcnow().strftime(
            "%Y.%m.%d")
        chess_pgn.headers["White"] = self.white_player.mention
        chess_pgn.headers["Black"] = self.black_player.mention
        self.match_embed.description = str(chess_pgn)
        if not self.match_message:
            self.match_message = await self.bot.send_message(
                self.text_channel, embed=self.match_embed)
        else:
            await self.bot.edit_message(self.match_message,
                                        embed=self.match_embed)