Zual commited on
Commit
7678641
·
verified ·
1 Parent(s): 5fcf9d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -145
app.py CHANGED
@@ -1,122 +1,33 @@
1
  import streamlit as st
2
  import chess
 
3
  import os
4
  import git
5
  import sys
6
  import random
7
- from streamlit.components.v1 import html
8
 
9
  # Configuration de la page
10
  st.set_page_config(page_title="Échecs contre IA", layout="wide")
11
 
12
- def render_chessboard():
13
- """Render un échiquier interactif avec chessboard.js"""
14
- # Obtenir la position FEN actuelle
15
- fen = st.session_state.board.fen()
 
16
 
17
- # Code JavaScript et HTML pour l'échiquier interactif
18
- html_content = f"""
19
- <!DOCTYPE html>
20
- <html>
21
- <head>
22
- <meta charset="UTF-8">
23
- <link
24
- rel="stylesheet"
25
- href="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.css"
26
- integrity="sha512-TU/clvRaSqKB43MX6dvJPgxm0ytgRrg/6tkbTPCFwOXG6Ej70nGCkcFkatrbcPHqR0mlPCy3WuYNg936BGvNOg=="
27
- crossorigin="anonymous"
28
- />
29
- <script
30
- src="https://code.jquery.com/jquery-3.6.0.min.js"
31
- integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
32
- crossorigin="anonymous">
33
- </script>
34
- <script
35
- src="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.js"
36
- integrity="sha512-WfASs5HtTgTL/eZs0Td0JVJZ+8tNxF/MDNU99TzJI8D4jXrZdQZRO9G7EPIVQhvmb7yUEEH+AKY9PfGi4pqrw=="
37
- crossorigin="anonymous">
38
- </script>
39
- <script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>
40
- </head>
41
- <body>
42
- <div id="board" style="width: 400px; margin: auto;"></div>
43
- <script>
44
- // Initialisation du jeu
45
- var board = null;
46
- var game = new Chess('{fen}');
47
-
48
- function onDragStart (source, piece, position, orientation) {{
49
- // Autoriser uniquement les pièces blanches à être déplacées
50
- if (game.turn() === 'b' ||
51
- game.game_over() ||
52
- (game.turn() === 'w' && piece.search(/^b/) !== -1)) {{
53
- return false;
54
- }}
55
- }}
56
-
57
- function onDrop (source, target) {{
58
- // Vérifier si le coup est légal
59
- var move = game.move({{
60
- from: source,
61
- to: target,
62
- promotion: 'q'
63
- }});
64
-
65
- // Coup illégal
66
- if (move === null) return 'snapback';
67
-
68
- // Envoyer le coup à Streamlit
69
- window.parent.postMessage({{
70
- type: 'move',
71
- move: move.san
72
- }}, '*');
73
- }}
74
-
75
- function onSnapEnd () {{
76
- board.position(game.fen());
77
- }}
78
-
79
- // Configuration de l'échiquier
80
- var config = {{
81
- position: '{fen}',
82
- draggable: true,
83
- onDragStart: onDragStart,
84
- onDrop: onDrop,
85
- onSnapEnd: onSnapEnd,
86
- pieceTheme: 'https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/img/chesspieces/wikipedia/{{piece}}.png'
87
- }};
88
-
89
- // Initialisation de l'échiquier
90
- board = Chessboard('board', config);
91
-
92
- // S'assurer que l'échiquier est responsive
93
- $(window).resize(board.resize);
94
-
95
- // Gestion des messages de Streamlit
96
- window.addEventListener('message', function(e) {{
97
- if (e.data.type === 'update') {{
98
- board.position(e.data.fen);
99
- game.load(e.data.fen);
100
- }}
101
- }});
102
- </script>
103
- <style>
104
- .highlight-square {{
105
- box-shadow: inset 0 0 3px 3px yellow;
106
- }}
107
- </style>
108
- </body>
109
- </html>
110
- """
111
 
112
- html(html_content, height=450)
113
-
114
- def calculate_max_length(move_count):
115
- """Calcule le max_length optimal"""
116
- base_length = 10
117
- increment = 1
118
- max_length = 100
119
- return min(base_length + (move_count * increment), max_length)
 
 
120
 
121
  # Setup du modèle
122
  @st.cache_resource
@@ -134,11 +45,11 @@ def setup_inference():
134
  )
135
  return ChessGenerator(config)
136
 
137
- # Initialisation du modèle
138
  try:
139
  generator = setup_inference()
140
  except Exception as e:
141
- st.error("Erreur lors de l'initialisation du modèle.")
142
  st.stop()
143
 
144
  # Initialisation de l'état
@@ -147,6 +58,13 @@ if 'board' not in st.session_state:
147
  if 'moves' not in st.session_state:
148
  st.session_state.moves = []
149
 
 
 
 
 
 
 
 
150
  def get_ai_move(prompt):
151
  """Obtient le coup de l'IA"""
152
  moves_count = len(st.session_state.moves)
@@ -159,10 +77,10 @@ def get_ai_move(prompt):
159
  else:
160
  moves = prompt.split()
161
  last_moves = " ".join(moves[-4:])
162
- if len(moves) % 2 == 0: # Si on vient de finir un coup noir
163
  next_move_num = f"{(len(moves)//2 + 1)}."
164
  response = generator.generate(f"{last_moves} {next_move_num}")
165
- else: # Si on vient de finir un coup blanc
166
  response = generator.generate(f"{last_moves}")
167
 
168
  moves = response[0].split() if isinstance(response, list) else response.split()
@@ -182,9 +100,8 @@ def get_ai_move(prompt):
182
  if legal_moves:
183
  random_move = random.choice(legal_moves)
184
  return st.session_state.board.san(random_move)
185
-
186
  except Exception as e:
187
- print(f"Erreur dans get_ai_move: {e}")
188
  return None
189
 
190
  def try_move(move_str):
@@ -211,24 +128,34 @@ def get_game_string():
211
  result.append(st.session_state.moves[i+1])
212
  return " ".join(result)
213
 
 
 
 
 
 
 
214
  # Interface utilisateur
215
  st.title("♟️ Échecs contre IA")
216
 
217
  col1, col2 = st.columns([2, 1])
218
 
219
  with col1:
220
- # Échiquier interactif
221
- render_chessboard()
222
 
223
- # Input texte comme méthode alternative
224
  move = st.text_input(
225
- "Ou saisissez votre coup ici",
226
  key=f"move_input_{len(st.session_state.moves)}",
227
  placeholder="ex: e4, Nf3, O-O"
228
  )
 
 
 
 
229
 
230
  with col2:
231
- # Informations de la partie
232
  st.subheader("Partie en cours")
233
  game_str = get_game_string()
234
  if game_str:
@@ -237,15 +164,13 @@ with col2:
237
  # Instructions
238
  st.markdown("""
239
  **Comment jouer:**
240
- - Glissez-déposez les pièces blanches
241
- - Ou utilisez la notation algébrique :
242
- - Pion: e4, d5
243
- - Cavalier: Nf3, Nc6
244
- - Fou: Bc4, Be7
245
- - Tour: Ra1, Rd8
246
- - Dame: Qd1, Qh4
247
- - Roi: Ke2, Kg8
248
- - Roque: O-O ou O-O-O
249
  """)
250
 
251
  # Nouvelle partie
@@ -254,24 +179,7 @@ with col2:
254
  st.session_state.moves = []
255
  st.rerun()
256
 
257
- # Gestion des messages du JavaScript
258
- if 'js_move' in st.session_state:
259
- move = st.session_state.js_move
260
- st.session_state.js_move = None
261
- if try_move(move):
262
- game_str = get_game_string()
263
- with st.spinner("L'IA réfléchit..."):
264
- ai_move = get_ai_move(game_str)
265
- if ai_move and try_move(ai_move):
266
- if st.session_state.board.is_checkmate():
267
- st.success("Échec et mat!")
268
- elif st.session_state.board.is_game_over():
269
- st.info("Partie terminée!")
270
- else:
271
- st.error("Problème avec le coup de l'IA")
272
- st.rerun()
273
-
274
- # Gestion des coups via input texte
275
  if move:
276
  if try_move(move):
277
  game_str = get_game_string()
 
1
  import streamlit as st
2
  import chess
3
+ import chess.svg
4
  import os
5
  import git
6
  import sys
7
  import random
 
8
 
9
  # Configuration de la page
10
  st.set_page_config(page_title="Échecs contre IA", layout="wide")
11
 
12
+ def render_board():
13
+ """Rendre l'échiquier en SVG avec mise en évidence des coups légaux"""
14
+ # Déterminer les cases à mettre en évidence
15
+ squares = None
16
+ last_move = None
17
 
18
+ if st.session_state.board.move_stack:
19
+ last_move = st.session_state.board.peek()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ # Créer le SVG
22
+ board_svg = chess.svg.board(
23
+ board=st.session_state.board,
24
+ size=400,
25
+ lastmove=last_move,
26
+ check=st.session_state.board.king(st.session_state.board.turn) if st.session_state.board.is_check() else None
27
+ )
28
+
29
+ # On utilise unsafe_allow_html=True car on sait que le SVG est sûr (généré par python-chess)
30
+ st.write(board_svg, unsafe_allow_html=True)
31
 
32
  # Setup du modèle
33
  @st.cache_resource
 
45
  )
46
  return ChessGenerator(config)
47
 
48
+ # Initialisation
49
  try:
50
  generator = setup_inference()
51
  except Exception as e:
52
+ st.error(f"Erreur lors de l'initialisation: {str(e)}")
53
  st.stop()
54
 
55
  # Initialisation de l'état
 
58
  if 'moves' not in st.session_state:
59
  st.session_state.moves = []
60
 
61
+ def calculate_max_length(move_count):
62
+ """Calcule le max_length optimal"""
63
+ base_length = 10
64
+ increment = 1
65
+ max_length = 100
66
+ return min(base_length + (move_count * increment), max_length)
67
+
68
  def get_ai_move(prompt):
69
  """Obtient le coup de l'IA"""
70
  moves_count = len(st.session_state.moves)
 
77
  else:
78
  moves = prompt.split()
79
  last_moves = " ".join(moves[-4:])
80
+ if len(moves) % 2 == 0:
81
  next_move_num = f"{(len(moves)//2 + 1)}."
82
  response = generator.generate(f"{last_moves} {next_move_num}")
83
+ else:
84
  response = generator.generate(f"{last_moves}")
85
 
86
  moves = response[0].split() if isinstance(response, list) else response.split()
 
100
  if legal_moves:
101
  random_move = random.choice(legal_moves)
102
  return st.session_state.board.san(random_move)
 
103
  except Exception as e:
104
+ st.error(f"Erreur lors de la génération du coup de l'IA: {str(e)}")
105
  return None
106
 
107
  def try_move(move_str):
 
128
  result.append(st.session_state.moves[i+1])
129
  return " ".join(result)
130
 
131
+ def display_legal_moves():
132
+ """Affiche les coups légaux possibles"""
133
+ legal_moves = [st.session_state.board.san(move) for move in st.session_state.board.legal_moves]
134
+ st.text("Coups légaux possibles:")
135
+ st.code(", ".join(legal_moves))
136
+
137
  # Interface utilisateur
138
  st.title("♟️ Échecs contre IA")
139
 
140
  col1, col2 = st.columns([2, 1])
141
 
142
  with col1:
143
+ # Échiquier
144
+ render_board()
145
 
146
+ # Input du coup
147
  move = st.text_input(
148
+ "Votre coup",
149
  key=f"move_input_{len(st.session_state.moves)}",
150
  placeholder="ex: e4, Nf3, O-O"
151
  )
152
+
153
+ # Afficher les coups légaux si demandé
154
+ if st.checkbox("Afficher les coups possibles"):
155
+ display_legal_moves()
156
 
157
  with col2:
158
+ # Historique et état de la partie
159
  st.subheader("Partie en cours")
160
  game_str = get_game_string()
161
  if game_str:
 
164
  # Instructions
165
  st.markdown("""
166
  **Comment jouer:**
167
+ - Pion: e4, d5
168
+ - Cavalier: Nf3, Nc6
169
+ - Fou: Bc4, Be7
170
+ - Tour: Ra1, Rd8
171
+ - Dame: Qd1, Qh4
172
+ - Roi: Ke2, Kg8
173
+ - Roque: O-O ou O-O-O
 
 
174
  """)
175
 
176
  # Nouvelle partie
 
179
  st.session_state.moves = []
180
  st.rerun()
181
 
182
+ # Logique du jeu
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  if move:
184
  if try_move(move):
185
  game_str = get_game_string()