Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,28 +9,70 @@ import random
|
|
9 |
# Configuration de la page
|
10 |
st.set_page_config(page_title="Échecs contre IA", layout="wide")
|
11 |
|
12 |
-
def
|
13 |
-
"""
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
if st.session_state.selected_square is None:
|
18 |
-
# Premier clic - sélection de la pièce
|
19 |
-
square = chess.parse_square(square_name)
|
20 |
piece = st.session_state.board.piece_at(square)
|
21 |
if piece and piece.color == st.session_state.board.turn:
|
22 |
st.session_state.selected_square = square_name
|
|
|
|
|
23 |
else:
|
24 |
-
# Deuxième clic - déplacement
|
25 |
from_square = chess.parse_square(st.session_state.selected_square)
|
26 |
-
|
27 |
-
move = chess.Move(from_square, to_square)
|
28 |
|
29 |
if move in st.session_state.board.legal_moves:
|
30 |
-
san_move = st.session_state.board.san(move)
|
31 |
st.session_state.board.push(move)
|
32 |
-
st.session_state.moves.append(
|
33 |
-
st.session_state.selected_square = None
|
34 |
|
35 |
# Tour de l'IA
|
36 |
game_str = get_game_string()
|
@@ -39,54 +81,10 @@ def handle_click(square_name):
|
|
39 |
try_move(ai_move)
|
40 |
|
41 |
st.session_state.selected_square = None
|
42 |
-
|
43 |
-
def render_chessboard():
|
44 |
-
"""Render un échiquier interactif en SVG avec des boutons pour chaque case"""
|
45 |
-
board_svg = chess.svg.board(
|
46 |
-
board=st.session_state.board,
|
47 |
-
size=400,
|
48 |
-
lastmove=st.session_state.board.peek() if st.session_state.board.move_stack else None,
|
49 |
-
squares=get_legal_moves_squares() if st.session_state.show_hints else None,
|
50 |
-
)
|
51 |
-
|
52 |
-
st.write(f"""
|
53 |
-
<div style="display: flex; justify-content: center;">
|
54 |
-
<div style="position: relative; width: 400px;">
|
55 |
-
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0;">
|
56 |
-
{board_svg}
|
57 |
-
</div>
|
58 |
-
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
59 |
-
display: grid; grid-template-columns: repeat(8, 1fr);
|
60 |
-
height: 400px;">
|
61 |
-
""", unsafe_allow_html=True)
|
62 |
-
|
63 |
-
# Créer une grille de boutons transparents
|
64 |
-
for rank in range(7, -1, -1):
|
65 |
-
for file in range(8):
|
66 |
-
square = chess.square(file, rank)
|
67 |
-
square_name = chess.square_name(square)
|
68 |
-
if st.button("", key=f"square_{square_name}",
|
69 |
-
help=square_name,
|
70 |
-
use_container_width=True):
|
71 |
-
handle_click(square_name)
|
72 |
-
|
73 |
-
st.write("</div></div></div>", unsafe_allow_html=True)
|
74 |
-
|
75 |
-
def get_legal_moves_squares():
|
76 |
-
"""Obtenir les cases des coups légaux pour la pièce sélectionnée"""
|
77 |
-
squares = []
|
78 |
-
if hasattr(st.session_state, 'selected_square') and st.session_state.selected_square:
|
79 |
-
legal_moves = st.session_state.board.legal_moves
|
80 |
-
from_square = chess.parse_square(st.session_state.selected_square)
|
81 |
-
for move in legal_moves:
|
82 |
-
if move.from_square == from_square:
|
83 |
-
squares.append(chess.square_name(move.to_square))
|
84 |
-
return squares
|
85 |
|
86 |
def calculate_max_length(move_count):
|
87 |
-
"""
|
88 |
-
Calcule le max_length optimal basé sur le nombre de coups joués
|
89 |
-
"""
|
90 |
base_length = 10
|
91 |
increment = 1
|
92 |
max_length = 100
|
@@ -122,8 +120,6 @@ if 'moves' not in st.session_state:
|
|
122 |
st.session_state.moves = []
|
123 |
if 'selected_square' not in st.session_state:
|
124 |
st.session_state.selected_square = None
|
125 |
-
if 'show_hints' not in st.session_state:
|
126 |
-
st.session_state.show_hints = True
|
127 |
|
128 |
def get_ai_move(prompt):
|
129 |
"""Obtient le coup de l'IA"""
|
@@ -137,10 +133,10 @@ def get_ai_move(prompt):
|
|
137 |
else:
|
138 |
moves = prompt.split()
|
139 |
last_moves = " ".join(moves[-4:])
|
140 |
-
if len(moves) % 2 == 0:
|
141 |
next_move_num = f"{(len(moves)//2 + 1)}."
|
142 |
response = generator.generate(f"{last_moves} {next_move_num}")
|
143 |
-
else:
|
144 |
response = generator.generate(f"{last_moves}")
|
145 |
|
146 |
moves = response[0].split() if isinstance(response, list) else response.split()
|
@@ -192,12 +188,12 @@ def get_game_string():
|
|
192 |
# Interface utilisateur
|
193 |
st.title("♟️ Échecs contre IA")
|
194 |
|
195 |
-
#
|
196 |
col1, col2 = st.columns([2, 1])
|
197 |
|
198 |
with col1:
|
199 |
# Échiquier interactif
|
200 |
-
|
201 |
|
202 |
# Input texte comme méthode alternative
|
203 |
move = st.text_input(
|
@@ -227,9 +223,6 @@ with col2:
|
|
227 |
- Roque: O-O ou O-O-O
|
228 |
""")
|
229 |
|
230 |
-
# Option pour afficher les coups possibles
|
231 |
-
st.checkbox("Afficher les coups possibles", key="show_hints")
|
232 |
-
|
233 |
# Nouvelle partie
|
234 |
if st.button("Nouvelle partie"):
|
235 |
st.session_state.board = chess.Board()
|
|
|
9 |
# Configuration de la page
|
10 |
st.set_page_config(page_title="Échecs contre IA", layout="wide")
|
11 |
|
12 |
+
def render_chessboard():
|
13 |
+
"""Render l'échiquier"""
|
14 |
+
squares = None
|
15 |
+
if st.session_state.selected_square is not None:
|
16 |
+
squares = []
|
17 |
+
from_square = chess.parse_square(st.session_state.selected_square)
|
18 |
+
for move in st.session_state.board.legal_moves:
|
19 |
+
if move.from_square == from_square:
|
20 |
+
squares.append(move.to_square)
|
21 |
+
|
22 |
+
board_svg = chess.svg.board(
|
23 |
+
board=st.session_state.board,
|
24 |
+
size=400,
|
25 |
+
lastmove=st.session_state.board.peek() if st.session_state.board.move_stack else None,
|
26 |
+
squares=chess.SquareSet(squares) if squares else None
|
27 |
+
)
|
28 |
+
|
29 |
+
return board_svg
|
30 |
+
|
31 |
+
def display_interactive_board():
|
32 |
+
"""Affiche l'échiquier avec les contrôles interactifs"""
|
33 |
+
board_svg = render_chessboard()
|
34 |
+
|
35 |
+
col1, col2, col3 = st.columns([1, 2, 1])
|
36 |
+
|
37 |
+
with col2:
|
38 |
+
# Afficher l'échiquier
|
39 |
+
st.write(f"""
|
40 |
+
<div style="display: flex; justify-content: center; position: relative;">
|
41 |
+
{board_svg}
|
42 |
+
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
43 |
+
display: grid; grid-template-columns: repeat(8, 1fr);
|
44 |
+
grid-template-rows: repeat(8, 1fr);">
|
45 |
+
""", unsafe_allow_html=True)
|
46 |
+
|
47 |
+
# Créer les boutons transparents pour chaque case
|
48 |
+
for rank in range(7, -1, -1):
|
49 |
+
for file in range(8):
|
50 |
+
square_name = chess.square_name(chess.square(file, rank))
|
51 |
+
if st.button("", key=f"square_{square_name}",
|
52 |
+
use_container_width=True,
|
53 |
+
help=square_name):
|
54 |
+
handle_square_click(square_name)
|
55 |
|
56 |
+
st.write("</div></div>", unsafe_allow_html=True)
|
57 |
+
|
58 |
+
def handle_square_click(square_name):
|
59 |
+
"""Gère le clic sur une case"""
|
60 |
+
square = chess.parse_square(square_name)
|
61 |
+
|
62 |
+
# Si aucune pièce n'est sélectionnée
|
63 |
if st.session_state.selected_square is None:
|
|
|
|
|
64 |
piece = st.session_state.board.piece_at(square)
|
65 |
if piece and piece.color == st.session_state.board.turn:
|
66 |
st.session_state.selected_square = square_name
|
67 |
+
st.rerun()
|
68 |
+
# Si une pièce est déjà sélectionnée
|
69 |
else:
|
|
|
70 |
from_square = chess.parse_square(st.session_state.selected_square)
|
71 |
+
move = chess.Move(from_square, square)
|
|
|
72 |
|
73 |
if move in st.session_state.board.legal_moves:
|
|
|
74 |
st.session_state.board.push(move)
|
75 |
+
st.session_state.moves.append(st.session_state.board.san(move))
|
|
|
76 |
|
77 |
# Tour de l'IA
|
78 |
game_str = get_game_string()
|
|
|
81 |
try_move(ai_move)
|
82 |
|
83 |
st.session_state.selected_square = None
|
84 |
+
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
def calculate_max_length(move_count):
|
87 |
+
"""Calcule le max_length optimal"""
|
|
|
|
|
88 |
base_length = 10
|
89 |
increment = 1
|
90 |
max_length = 100
|
|
|
120 |
st.session_state.moves = []
|
121 |
if 'selected_square' not in st.session_state:
|
122 |
st.session_state.selected_square = None
|
|
|
|
|
123 |
|
124 |
def get_ai_move(prompt):
|
125 |
"""Obtient le coup de l'IA"""
|
|
|
133 |
else:
|
134 |
moves = prompt.split()
|
135 |
last_moves = " ".join(moves[-4:])
|
136 |
+
if len(moves) % 2 == 0:
|
137 |
next_move_num = f"{(len(moves)//2 + 1)}."
|
138 |
response = generator.generate(f"{last_moves} {next_move_num}")
|
139 |
+
else:
|
140 |
response = generator.generate(f"{last_moves}")
|
141 |
|
142 |
moves = response[0].split() if isinstance(response, list) else response.split()
|
|
|
188 |
# Interface utilisateur
|
189 |
st.title("♟️ Échecs contre IA")
|
190 |
|
191 |
+
# Layout principal
|
192 |
col1, col2 = st.columns([2, 1])
|
193 |
|
194 |
with col1:
|
195 |
# Échiquier interactif
|
196 |
+
display_interactive_board()
|
197 |
|
198 |
# Input texte comme méthode alternative
|
199 |
move = st.text_input(
|
|
|
223 |
- Roque: O-O ou O-O-O
|
224 |
""")
|
225 |
|
|
|
|
|
|
|
226 |
# Nouvelle partie
|
227 |
if st.button("Nouvelle partie"):
|
228 |
st.session_state.board = chess.Board()
|