Spaces:
Sleeping
Sleeping
| import chess | |
| from PIL import Image | |
| from io import BytesIO | |
| import cairosvg | |
| def _create_board_from_moves(moves: list[str]) -> chess.Board: | |
| """ | |
| Create a chess board and apply a sequence of moves. | |
| Args: | |
| moves: List of moves in UCI format (e.g., ['e2e4', 'd7d5']) | |
| Returns: | |
| Chess board with moves applied | |
| """ | |
| board = chess.Board() | |
| for move_str in moves: | |
| try: | |
| move = chess.Move.from_uci(move_str) | |
| board.push(move) | |
| except ValueError: | |
| pass # Skip invalid moves | |
| return board | |
| def generate_board_image(moves: list[str], size: int = 400) -> Image.Image: | |
| """ | |
| Generate a PIL image of a chess board after applying a sequence of moves. | |
| Args: | |
| moves: List of moves in UCI format (e.g., ['e2e4', 'd7d5']) | |
| size: Size of the output image in pixels (default: 400) | |
| Returns: | |
| PIL Image of the chess board | |
| """ | |
| import chess.svg | |
| board = _create_board_from_moves(moves) | |
| # Generate SVG using chess library | |
| svg_data = chess.svg.board(board, size=size) | |
| # Convert SVG to PNG using cairosvg | |
| png_data = cairosvg.svg2png(bytestring=svg_data.encode("utf-8")) | |
| # Load PNG into PIL Image | |
| img = Image.open(BytesIO(png_data)) | |
| return img | |
| def generate_board_ascii(moves: list[str]) -> str: | |
| """ | |
| Generate an ASCII representation of a chess board after applying a sequence of moves. | |
| Args: | |
| moves: List of moves in UCI format (e.g., ['e2e4', 'd7d5']) | |
| Returns: | |
| String representation of the chess board | |
| """ | |
| board = _create_board_from_moves(moves) | |
| return str(board) | |
| def generate_game_gif(moves: list[str], size: int = 400, duration: int = 500) -> bytes: | |
| """ | |
| Generate an animated GIF of a chess game from a sequence of moves. | |
| Args: | |
| moves: List of moves in UCI format (e.g., ['e2e4', 'd7d5']) | |
| size: Size of each frame in pixels (default: 400) | |
| duration: Duration of each frame in milliseconds (default: 500) | |
| Returns: | |
| Bytes of the animated GIF | |
| """ | |
| frames = [] | |
| # Initial position | |
| img = generate_board_image([], size) | |
| frames.append(img) | |
| # Apply moves and capture frames | |
| moves_so_far = [] | |
| for move_str in moves: | |
| try: | |
| move = chess.Move.from_uci(move_str) | |
| moves_so_far.append(move_str) | |
| img = generate_board_image(moves_so_far, size) | |
| frames.append(img) | |
| except ValueError: | |
| pass # Skip invalid moves | |
| # Save frames as GIF in memory | |
| gif_bytes = BytesIO() | |
| frames[0].save( | |
| gif_bytes, | |
| format="GIF", | |
| save_all=True, | |
| append_images=frames[1:], | |
| duration=duration, | |
| loop=0, | |
| ) | |
| gif_bytes.seek(0) | |
| return gif_bytes.getvalue() | |
| if __name__ == "__main__": | |
| moves = ["e2e4"] | |
| img = generate_board_image(moves) | |
| img.show() | |
| ascii_board = generate_board_ascii(moves) | |
| print(ascii_board) | |
| coup_du_berget = ["e2e4", "e7e5", "f1c4", "b8c6", "d1h5", "g8f6", "h5f7"] | |
| gif = generate_game_gif(coup_du_berget) | |
| with open("coup_du_berget.gif", "wb") as f: | |
| f.write(gif) | |