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)
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
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)
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)
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
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
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
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)