chess / app.py
akhaliq's picture
akhaliq HF staff
Update app.py
65f55ff verified
raw
history blame contribute delete
No virus
4.8 kB
import gradio as gr
import chess
import chess.svg
import os
import google.generativeai as genai
# Configure the Google Generative AI client
genai.configure(api_key=os.environ["API_KEY"])
board = chess.Board()
def describe_board_position(board):
"""
Returns a human-readable description of the chessboard for the AI.
Args:
board (chess.Board): The current board position.
Returns:
str: A human-readable description of the chessboard.
"""
description = []
pieces = ['P', 'N', 'B', 'R', 'Q', 'K', 'p', 'n', 'b', 'r', 'q', 'k']
for square in chess.SQUARES:
piece = board.piece_at(square)
if piece:
piece_description = f"{'White' if piece.color == chess.WHITE else 'Black'} {piece.symbol().upper()} on {chess.square_name(square)}"
description.append(piece_description)
return ", ".join(description)
def get_ai_move(fen):
"""
Gets the AI's next move using Google Gemini via google.generativeai.
Args:
fen (str): The current board position in FEN notation.
Returns:
str or None: The AI's move in UCI format, or None if an error occurs.
"""
# Get human-readable board position
board_description = describe_board_position(board)
# Prepare the prompt for the AI
prompt = f"""
You are playing a game of chess. The current board position is described below:
{board_description}
In addition, here is the board's FEN notation for precise positioning:
{fen}
It is your turn to make a move. You should provide the best legal move following the rules of chess.
The move should be in UCI format, which represents the starting and ending squares (for example, 'e2e4').
Please ensure that the move is valid for the current position."""
try:
# Generate the response from the AI model
response = genai.generate_text(
model="gemini-1.5-flash", # Use the Gemini model
prompt=prompt,
temperature=0, # To make the output more deterministic
max_output_tokens=10
)
ai_move = response.result.strip()
print(f"AI move: {ai_move}")
# Validate the move
legal_moves = [move.uci() for move in board.legal_moves]
if ai_move in legal_moves:
return ai_move
else:
print(f"Invalid move received from the AI: {ai_move}")
return None
except Exception as e:
print(f"Error occurred in get_ai_move: {e}")
return None
def board_to_svg(board):
return chess.svg.board(board=board)
def make_move(user_move):
global board
print(f"User move input: {user_move}")
try:
# Try UCI move first
board.push_uci(user_move)
except ValueError as e_uci:
try:
# Try SAN move
board.push_san(user_move)
except ValueError as e_san:
print(f"UCI ValueError: {e_uci}, SAN ValueError: {e_san}")
return gr.update(value=board_to_svg(board)), "Invalid move. Try again."
except Exception as e:
print(f"Unexpected error: {e}")
return gr.update(value=board_to_svg(board)), "Invalid move. Try again."
# Check for game over
if board.is_game_over():
result = board.result()
board_svg = board_to_svg(board)
return gr.update(value=board_svg), f"Game over: {result}"
# AI's move
ai_move = get_ai_move(board.fen())
if ai_move:
try:
board.push_uci(ai_move)
except ValueError as e:
print(f"AI made an invalid move: {ai_move}, Error: {e}")
return gr.update(value=board_to_svg(board)), "AI made an invalid move. Game over."
else:
return gr.update(value=board_to_svg(board)), "AI failed to make a move. Game over."
# Check for game over again
if board.is_game_over():
result = board.result()
board_svg = board_to_svg(board)
return gr.update(value=board_svg), f"Game over: {result}"
# Continue game
return gr.update(value=board_to_svg(board)), "Your move"
def reset_game():
global board
board.reset()
return gr.update(value=board_to_svg(board)), "Game reset. Your move"
with gr.Blocks() as demo:
gr.Markdown("# Chess Game with Google Gemini AI")
with gr.Row():
board_output = gr.HTML(board_to_svg(board))
move_input = gr.Textbox(label="Your Move (e.g., e2e4, e4, Nf3)")
message_output = gr.Textbox(value="Your move", interactive=False)
with gr.Row():
move_button = gr.Button("Make Move")
reset_button = gr.Button("Reset Game")
move_button.click(make_move, inputs=move_input, outputs=[board_output, message_output])
reset_button.click(reset_game, outputs=[board_output, message_output])
demo.launch()