Spaces:
Sleeping
Sleeping
File size: 6,759 Bytes
5c1db90 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
import gradio as gr
import chess
import chess.engine
import tempfile
import os
from PIL import Image, ImageDraw
import requests
import io
# Configuración
BOARD_SIZE = 400
SQUARE_SIZE = BOARD_SIZE // 8
class ChessGame:
def __init__(self):
self.board = chess.Board()
self.selected_square = None
self.valid_moves = []
self.game_over = False
self.player_turn = True
def create_board_image(self):
"""Crear imagen del tablero con las piezas"""
# Colores
light_square = (238, 238, 210)
dark_square = (118, 150, 86)
highlight = (186, 202, 68)
# Crear imagen
img = Image.new('RGB', (BOARD_SIZE, BOARD_SIZE), color='white')
draw = ImageDraw.Draw(img)
# Dibujar tablero
for row in range(8):
for col in range(8):
color = light_square if (row + col) % 2 == 0 else dark_square
x1 = col * SQUARE_SIZE
y1 = row * SQUARE_SIZE
x2 = x1 + SQUARE_SIZE
y2 = y1 + SQUARE_SIZE
draw.rectangle([x1, y1, x2, y2], fill=color)
# Dibujar piezas (usaremos emojis como texto)
piece_chars = {
'r': '♜', 'n': '♞', 'b': '♝', 'q': '♛', 'k': '♚', 'p': '♟',
'R': '♖', 'N': '♘', 'B': '♗', 'Q': '♕', 'K': '♔', 'P': '♙'
}
for square in chess.SQUARES:
piece = self.board.piece_at(square)
if piece:
col = chess.square_file(square)
row = 7 - chess.square_rank(square)
x = col * SQUARE_SIZE + SQUARE_SIZE // 2
y = row * SQUARE_SIZE + SQUARE_SIZE // 2
# Usar emoji para la pieza
piece_char = piece_chars[piece.symbol()]
draw.text((x-10, y-15), piece_char, fill='black', font_size=30)
return img
def get_move_suggestion(self):
"""Obtener sugerencia de Stockfish usando API"""
try:
# Usar API de stockfish.js como fallback
fen = self.board.fen()
url = f"https://stockfish.online/api/s/v2.php?fen={fen}&depth=10"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if 'bestmove' in data:
return data['bestmove']
except:
pass
# Fallback: elegir el primer movimiento legal
legal_moves = list(self.board.legal_moves)
return str(legal_moves[0]) if legal_moves else None
def make_move(self, move_uci):
"""Realizar movimiento"""
try:
move = chess.Move.from_uci(move_uci)
if move in self.board.legal_moves:
self.board.push(move)
self.player_turn = False
return True
except:
pass
return False
def ai_move(self):
"""Movimiento de la IA"""
if not self.player_turn and not self.board.is_game_over():
best_move = self.get_move_suggestion()
if best_move:
self.board.push(chess.Move.from_uci(best_move))
self.player_turn = True
def get_game_status(self):
"""Obtener estado del juego"""
if self.board.is_checkmate():
return "¡Jaque mate! " + ("Ganaste" if self.player_turn else "Stockfish gana")
elif self.board.is_stalemate():
return "Tablas por ahogado"
elif self.board.is_insufficient_material():
return "Tablas por material insuficiente"
elif self.board.is_check():
return "¡Jaque!"
else:
return "Tu turno" if self.player_turn else "Pensando..."
# Instancia global del juego
game = ChessGame()
def update_interface():
"""Actualizar la interfaz completa"""
board_img = game.create_board_image()
status = game.get_game_status()
# Generar lista de movimientos legales
legal_moves = [str(move) for move in game.board.legal_moves]
return board_img, status, "\n".join(legal_moves[:10]) # Mostrar primeros 10 movimientos
def handle_move(move_input):
"""Manejar movimiento del jugador"""
if game.player_turn and not game.board.is_game_over():
if game.make_move(move_input):
# Movimiento de la IA después de un breve delay
game.ai_move()
return update_interface()
def handle_suggestion():
"""Obtener sugerencia de movimiento"""
if game.player_turn:
suggestion = game.get_move_suggestion()
return suggestion if suggestion else "No hay sugerencias disponibles"
return "Es el turno de Stockfish"
def reset_game():
"""Reiniciar juego"""
global game
game = ChessGame()
return update_interface()
# Crear interfaz Gradio
with gr.Blocks(theme=gr.themes.Soft(), title="Ajedrez con Stockfish") as demo:
gr.Markdown("""
# ♟️ Ajedrez con Stockfish
Juega contra Stockfish, uno de los motores de ajedrez más fuertes del mundo.
""")
with gr.Row():
with gr.Column():
board_image = gr.Image(label="Tablero", interactive=False)
status_text = gr.Textbox(label="Estado del Juego", interactive=False)
with gr.Column():
move_input = gr.Textbox(
label="Ingresa tu movimiento (ej: e2e4)",
placeholder="Formato: casilla_origen casilla_destino"
)
with gr.Row():
submit_btn = gr.Button("Realizar Movimiento", variant="primary")
suggest_btn = gr.Button("Sugerencia")
reset_btn = gr.Button("Nuevo Juego")
suggestion_text = gr.Textbox(label="Sugerencia de Stockfish", interactive=False)
legal_moves_text = gr.Textbox(
label="Movimientos Legales (primeros 10)",
lines=10,
interactive=False
)
# Conexiones de eventos
submit_btn.click(
fn=handle_move,
inputs=move_input,
outputs=[board_image, status_text, legal_moves_text]
)
suggest_btn.click(
fn=handle_suggestion,
outputs=suggestion_text
)
reset_btn.click(
fn=reset_game,
outputs=[board_image, status_text, legal_moves_text]
)
# Inicializar interfaz
demo.load(
fn=update_interface,
outputs=[board_image, status_text, legal_moves_text]
)
# Para Hugging Face Spaces
if __name__ == "__main__":
demo.launch(share=True) |