Docfile commited on
Commit
b293718
·
verified ·
1 Parent(s): 166ccea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -116
app.py CHANGED
@@ -1,42 +1,19 @@
1
  from flask import Flask, render_template, request, jsonify, session
2
- # -- Modification pour vérifier l'import --
3
  import sys
4
  import os
5
  import inspect # Ajout pour inspecter
6
 
7
- # --- Forcer l'utilisation de la bibliothèque locale si elle est à côté ---
8
- # Supposons la structure:
9
- # votre_projet/
10
- # ├── app.py
11
- # └── zhelyabuzhsky-stockfish/ <-- le répertoire complet de la bibliothèque
12
- # ├── stockfish/
13
- # │ ├── __init__.py
14
- # │ └── models.py
15
- # └── ... autres fichiers de la lib (setup.py, etc.)
16
-
17
- # Pour que "from stockfish import Stockfish" fonctionne avec cette structure,
18
- # le répertoire "zhelyabuzhsky-stockfish" doit être traitable comme un package.
19
- # Python recherche d'abord dans le répertoire courant, puis dans PYTHONPATH, puis dans les sites-packages.
20
- # Si vous avez une autre lib "stockfish" installée globalement, elle pourrait prendre le dessus.
21
- # On peut ajouter le répertoire parent de zhelyabuzhsky-stockfish/stockfish au path,
22
- # ou directement le chemin vers zhelyabuzhsky-stockfish si on l'importe comme un package.
23
-
24
- # Option 1: Ajouter le répertoire parent de votre projet au sys.path
25
- # pour que zhelyabuzhsky-stockfish soit vu comme un package de haut niveau.
26
- # current_script_dir = os.path.dirname(os.path.abspath(__file__))
27
- # project_root = os.path.dirname(current_script_dir) # Si app.py est dans un sous-dossier
28
- # if project_root not in sys.path:
29
- # sys.path.insert(0, project_root)
30
-
31
- # Option plus simple si zhelyabuzhsky-stockfish est à côté de app.py
32
- # et que vous voulez importer "from stockfish import ..."
33
- # Cela suppose que Python va scanner "zhelyabuzhsky-stockfish" et trouver le sous-module "stockfish".
34
- # Le plus sûr est d'installer votre bibliothèque localement.
35
- # `pip install -e ./zhelyabuzhsky-stockfish` depuis le répertoire parent.
36
-
37
- from stockfish import Stockfish, StockfishException # L'import
38
- print(f"--- Stockfish class imported from: {inspect.getfile(Stockfish)} ---") # VÉRIFICATION
39
- # --- Fin de la modification pour vérifier l'import --
40
 
41
  import chess
42
  import chess.svg
@@ -45,15 +22,13 @@ import logging
45
  app = Flask(__name__)
46
 
47
  # --- Configuration de la clé secrète ---
48
- # FORCER LE MODE DEBUG POUR LE DÉVELOPPEMENT LOCAL
49
- IS_DEBUG_MODE = True # Modifier cette ligne manuellement pour tester en mode prod-like si besoin
50
- # OU utiliser la variable d'environnement:
51
- # IS_DEBUG_MODE = os.environ.get("FLASK_DEBUG", "0") == "1"
52
 
53
  if IS_DEBUG_MODE:
54
- app.secret_key = 'dev_secret_key_pour_eviter_perte_session_rechargement_et_tests_v2'
55
  logging.warning("MODE DEBUG ACTIVÉ. Utilisation d'une clé secrète statique.")
56
- app.debug = True # S'assurer que Flask est aussi en mode debug
57
  else:
58
  app.secret_key = os.environ.get("FLASK_SECRET_KEY")
59
  if not app.secret_key:
@@ -61,7 +36,6 @@ else:
61
  logging.warning("MODE PRODUCTION. FLASK_SECRET_KEY non définie. Clé aléatoire générée.")
62
  app.debug = False
63
 
64
-
65
  # --- Configuration des Cookies de Session ---
66
  app.config.update(
67
  SESSION_COOKIE_SECURE=False,
@@ -71,69 +45,59 @@ app.config.update(
71
 
72
  logging.basicConfig(level=logging.DEBUG)
73
 
74
- # ... (le reste du code de app.py reste identique à la version précédente)
75
- # ... (find_stockfish, get_stockfish_engine, routes, etc.)
76
-
77
- # --- Assurez-vous que le find_stockfish et HAS_STOCKFISH sont définis globalement ---
78
- STOCKFISH_PATH_GLOBAL = "stockfish" # Variable globale pour le chemin
79
- HAS_STOCKFISH_GLOBAL = False
80
 
81
  def find_stockfish_on_startup():
82
- global STOCKFISH_PATH_GLOBAL, HAS_STOCKFISH_GLOBAL
83
- # Tenter le chemin par défaut ou celui de l'env
84
- stockfish_env_path = os.environ.get("STOCKFISH_EXECUTABLE_PATH", "stockfish")
85
- paths_to_check = [stockfish_env_path, STOCKFISH_PATH_GLOBAL, "/usr/games/stockfish", "/usr/local/bin/stockfish", "/opt/homebrew/bin/stockfish", "stockfish.exe", "./stockfish"]
 
 
 
 
 
 
 
86
 
87
  for p in paths_to_check:
88
  if p and os.path.exists(p) and os.access(p, os.X_OK):
89
- STOCKFISH_PATH_GLOBAL = p
90
- HAS_STOCKFISH_GLOBAL = True
91
- app.logger.info(f"Stockfish exécutable trouvé à: {STOCKFISH_PATH_GLOBAL}")
92
  return
93
- app.logger.warning(f"AVERTISSEMENT: Stockfish non trouvé. L'IA ne fonctionnera pas.")
94
- HAS_STOCKFISH_GLOBAL = False
95
-
96
- find_stockfish_on_startup() # Exécuter au démarrage
 
 
97
 
 
98
 
99
  def get_stockfish_engine():
100
- """Initialise et retourne une instance de Stockfish."""
101
- if not HAS_STOCKFISH_GLOBAL:
102
- app.logger.error("Stockfish non disponible (vérification au démarrage échouée). L'IA ne peut pas démarrer.")
103
  return None
104
  try:
105
- # Utiliser STOCKFISH_PATH_GLOBAL qui a été déterminé au démarrage
106
- engine = Stockfish(path=STOCKFISH_PATH_GLOBAL, depth=15, parameters={"Threads": 1, "Hash": 64})
107
  if engine._stockfish.poll() is not None:
108
  app.logger.error("Le processus Stockfish s'est terminé de manière inattendue lors de l'initialisation.")
109
  raise StockfishException("Stockfish process terminated unexpectedly on init.")
110
- engine.set_fen_position(chess.STARTING_FEN)
111
  engine.get_best_move()
112
- engine.set_fen_position(chess.STARTING_FEN)
113
- app.logger.info(f"Moteur Stockfish initialisé avec succès depuis {STOCKFISH_PATH_GLOBAL}.")
114
  return engine
115
  except Exception as e:
116
- app.logger.error(f"Erreur lors de l'initialisation de Stockfish ({STOCKFISH_PATH_GLOBAL}): {e}", exc_info=True)
117
  return None
118
 
119
- # --- Collez ici le reste de vos routes : index, get_outcome_message, make_move, reset_game, set_mode_route ---
120
- # (Pour éviter de répéter 500 lignes, je ne les remets pas, mais elles restent inchangées par rapport à votre dernière version
121
- # SAUF si le AttributeError persiste, auquel cas il faudra vérifier la version de la lib Stockfish)
122
-
123
- # ... (Collez ici le reste des routes : index, get_outcome_message, make_move, reset_game, set_mode_route)
124
- # ... (depuis la version précédente que je vous ai donnée)
125
-
126
- # Par exemple, la route make_move commencerait comme ça:
127
- @app.route('/make_move', methods=['POST'])
128
- def make_move():
129
- app.logger.debug(f"Session au début de POST /make_move: {dict(session.items())}")
130
- if 'board_fen' not in session:
131
- app.logger.error("ERREUR CRITIQUE: 'board_fen' non trouvé dans la session pour POST /make_move!")
132
- return jsonify({'error': 'Erreur de session, "board_fen" manquant. Veuillez rafraîchir ou réinitialiser.',
133
- 'fen': chess.Board().fen(), 'game_over': False, 'board_svg': chess.svg.board(board=chess.Board(), size=400)}), 500
134
- # ... et ainsi de suite pour toute la fonction make_move et les autres routes.
135
 
136
- # (Le code des routes est omis pour la brièveté, mais doit être inclus)
137
  @app.route('/')
138
  def index():
139
  app.logger.debug(f"Session au début de GET /: {dict(session.items())}")
@@ -141,7 +105,7 @@ def index():
141
  app.logger.info("Initialisation de la session (board_fen, game_mode, player_color) dans GET /")
142
  session['board_fen'] = chess.Board().fen()
143
  session['game_mode'] = 'pvp'
144
- session['player_color'] = 'white' # Couleur du joueur humain si mode AI
145
 
146
  board = chess.Board(session['board_fen'])
147
  app.logger.debug(f"Session à la fin de GET /: {dict(session.items())}")
@@ -154,7 +118,6 @@ def index():
154
  outcome=get_outcome_message(board) if board.is_game_over() else "",
155
  current_turn = 'white' if board.turn == chess.WHITE else 'black')
156
 
157
-
158
  def get_outcome_message(board):
159
  if board.is_checkmate():
160
  winner_color = "Blancs" if board.turn == chess.BLACK else "Noirs"
@@ -167,7 +130,7 @@ def get_outcome_message(board):
167
  return ""
168
 
169
  @app.route('/make_move', methods=['POST'])
170
- def make_move_impl(): # Renommé pour éviter conflit de nom si vous avez collé
171
  app.logger.debug(f"Session au début de POST /make_move: {dict(session.items())}")
172
  if 'board_fen' not in session:
173
  app.logger.error("ERREUR CRITIQUE: 'board_fen' non trouvé dans la session pour POST /make_move!")
@@ -186,9 +149,8 @@ def make_move_impl(): # Renommé pour éviter conflit de nom si vous avez collé
186
 
187
  ai_move_made = False
188
  ai_move_uci = None
189
- last_player_move = None
190
  move_to_highlight = None
191
- move = None # initialisation
192
 
193
  try:
194
  move = board.parse_uci(move_uci_san)
@@ -201,9 +163,8 @@ def make_move_impl(): # Renommé pour éviter conflit de nom si vous avez collé
201
  app.logger.warning(f"Mouvement invalide (ni UCI ni SAN): {move_uci_san} pour FEN {board.fen()}")
202
  return jsonify({'error': f'Mouvement invalide: {move_uci_san}', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)})
203
 
204
- if move and move in board.legal_moves: # Vérifier que 'move' est non None
205
  board.push(move)
206
- last_player_move = move
207
  move_to_highlight = move
208
  session['board_fen'] = board.fen()
209
  app.logger.info(f"Mouvement joueur {move.uci()} appliqué. Nouveau FEN: {board.fen()}")
@@ -235,31 +196,26 @@ def make_move_impl(): # Renommé pour éviter conflit de nom si vous avez collé
235
  else:
236
  app.logger.warning("L'IA (Stockfish) n'a pas retourné de coup.")
237
 
238
- # Vérifier si la méthode existe avant de l'appeler
239
- if hasattr(stockfish_engine, 'send_quit_command'):
240
- stockfish_engine.send_quit_command()
241
- app.logger.info("Moteur Stockfish arrêté après le coup de l'IA.")
242
- elif hasattr(stockfish_engine, '__del__'):
243
- # Si send_quit_command n'existe pas, on espère que __del__ fait le travail.
244
- # Ou on pourrait juste faire `del stockfish_engine` pour déclencher __del__
245
- app.logger.warning("send_quit_command() n'existe pas, __del__ sera utilisé implicitement.")
246
- else:
247
- app.logger.error("Ni send_quit_command ni __del__ ne semblent disponibles pour arrêter Stockfish proprement.")
248
 
249
  else:
250
  app.logger.error("Moteur Stockfish non disponible pour le coup de l'IA.")
251
- elif move: # 'move' est défini mais pas légal
252
  app.logger.warning(f"Mouvement illégal tenté: {move.uci() if hasattr(move, 'uci') else move_uci_san} depuis FEN: {session['board_fen']}")
253
- legal_moves_str = ", ".join([board.san(m) for m in board.legal_moves])
254
- app.logger.debug(f"Coups légaux: {legal_moves_str[:200]}")
255
  return jsonify({'error': f'Mouvement illégal: {move.uci() if hasattr(move, "uci") else move_uci_san}', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)})
256
- else: # 'move' est None, n'a pas pu être parsé
257
- # L'erreur a déjà été gérée par le bloc try/except du parsing
258
- # Ce bloc else ne devrait pas être atteint si le parsing échoue et retourne.
259
  app.logger.error("La variable 'move' est None après la tentative de parsing, ce qui ne devrait pas arriver ici.")
260
  return jsonify({'error': 'Erreur interne de parsing de coup.', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)}), 500
261
 
262
-
263
  game_over = board.is_game_over()
264
  outcome = get_outcome_message(board) if game_over else ""
265
  if game_over:
@@ -329,13 +285,17 @@ def set_mode_route():
329
  except Exception as e:
330
  app.logger.error(f"Erreur en appliquant le premier coup de l'IA {best_move_ai}: {e}", exc_info=True)
331
 
332
- if hasattr(stockfish_engine, 'send_quit_command'):
333
- stockfish_engine.send_quit_command()
334
- app.logger.info("Moteur Stockfish arrêté après le premier coup de l'IA.")
335
- elif hasattr(stockfish_engine, '__del__'):
336
- app.logger.warning("send_quit_command() n'existe pas, __del__ sera utilisé implicitement pour le premier coup IA.")
337
- else:
338
- app.logger.error("Ni send_quit_command ni __del__ pour arrêter Stockfish (premier coup IA).")
 
 
 
 
339
  else:
340
  app.logger.error("Moteur Stockfish non disponible pour le premier coup de l'IA.")
341
 
@@ -355,6 +315,5 @@ def set_mode_route():
355
  app.logger.warning(f"Tentative de définir un mode de jeu invalide: {mode}")
356
  return jsonify({'error': 'Mode invalide'}), 400
357
 
358
-
359
  if __name__ == '__main__':
360
  app.run(host='0.0.0.0', port=5000) # IS_DEBUG_MODE et app.debug sont gérés plus haut
 
1
  from flask import Flask, render_template, request, jsonify, session
 
2
  import sys
3
  import os
4
  import inspect # Ajout pour inspecter
5
 
6
+ # --- VÉRIFICATION DE L'IMPORT DE STOCKFISH (Doit être au tout début) ---
7
+ # Cet import doit être celui de la bibliothèque zhelyabuzhsky-stockfish
8
+ try:
9
+ from stockfish import Stockfish, StockfishException
10
+ STOCKFISH_LIB_PATH = inspect.getfile(Stockfish)
11
+ print(f"--- Stockfish class imported from: {STOCKFISH_LIB_PATH} ---")
12
+ except ImportError as e:
13
+ print(f"ERREUR CRITIQUE: Impossible d'importer la bibliothèque Stockfish: {e}")
14
+ print("Assurez-vous que la bibliothèque zhelyabuzhsky-stockfish est dans votre PYTHONPATH ou installée.")
15
+ sys.exit(1) # Arrêter si la lib principale manque
16
+ # --- Fin de la vérification ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  import chess
19
  import chess.svg
 
22
  app = Flask(__name__)
23
 
24
  # --- Configuration de la clé secrète ---
25
+ IS_DEBUG_MODE = True # Forcer le mode debug pour le développement local
26
+ # Pour la production, gérez FLASK_DEBUG et FLASK_SECRET_KEY via les variables d'environnement
 
 
27
 
28
  if IS_DEBUG_MODE:
29
+ app.secret_key = 'dev_secret_key_pour_eviter_perte_session_rechargement_et_tests_v3' # Changez si besoin
30
  logging.warning("MODE DEBUG ACTIVÉ. Utilisation d'une clé secrète statique.")
31
+ app.debug = True
32
  else:
33
  app.secret_key = os.environ.get("FLASK_SECRET_KEY")
34
  if not app.secret_key:
 
36
  logging.warning("MODE PRODUCTION. FLASK_SECRET_KEY non définie. Clé aléatoire générée.")
37
  app.debug = False
38
 
 
39
  # --- Configuration des Cookies de Session ---
40
  app.config.update(
41
  SESSION_COOKIE_SECURE=False,
 
45
 
46
  logging.basicConfig(level=logging.DEBUG)
47
 
48
+ # --- Configuration Globale de Stockfish (Exécutable) ---
49
+ STOCKFISH_EXECUTABLE_PATH_GLOBAL = "stockfish" # Valeur par défaut
50
+ HAS_STOCKFISH_EXECUTABLE_GLOBAL = False
 
 
 
51
 
52
  def find_stockfish_on_startup():
53
+ global STOCKFISH_EXECUTABLE_PATH_GLOBAL, HAS_STOCKFISH_EXECUTABLE_GLOBAL
54
+
55
+ # Priorité à une variable d'environnement si définie
56
+ env_path = os.environ.get("STOCKFISH_EXECUTABLE_PATH")
57
+ paths_to_check = [env_path] if env_path else []
58
+
59
+ paths_to_check.extend([
60
+ "stockfish", "./stockfish", # Relatif au répertoire de travail
61
+ "/usr/games/stockfish", "/usr/local/bin/stockfish",
62
+ "/opt/homebrew/bin/stockfish", "stockfish.exe" # Chemins communs
63
+ ])
64
 
65
  for p in paths_to_check:
66
  if p and os.path.exists(p) and os.access(p, os.X_OK):
67
+ STOCKFISH_EXECUTABLE_PATH_GLOBAL = p
68
+ HAS_STOCKFISH_EXECUTABLE_GLOBAL = True
69
+ app.logger.info(f"Stockfish exécutable trouvé à: {STOCKFISH_EXECUTABLE_PATH_GLOBAL}")
70
  return
71
+
72
+ app.logger.warning(
73
+ "AVERTISSEMENT: Exécutable Stockfish non trouvé dans les chemins courants ou via STOCKFISH_EXECUTABLE_PATH. "
74
+ "L'IA ne fonctionnera pas. Veuillez installer Stockfish ou définir la variable d'environnement."
75
+ )
76
+ HAS_STOCKFISH_EXECUTABLE_GLOBAL = False
77
 
78
+ find_stockfish_on_startup() # Exécuter au démarrage de l'application
79
 
80
  def get_stockfish_engine():
81
+ """Initialise et retourne une instance de la classe Stockfish."""
82
+ if not HAS_STOCKFISH_EXECUTABLE_GLOBAL:
83
+ app.logger.error("Exécutable Stockfish non disponible. L'IA ne peut pas démarrer.")
84
  return None
85
  try:
86
+ engine = Stockfish(path=STOCKFISH_EXECUTABLE_PATH_GLOBAL, depth=15, parameters={"Threads": 1, "Hash": 64})
 
87
  if engine._stockfish.poll() is not None:
88
  app.logger.error("Le processus Stockfish s'est terminé de manière inattendue lors de l'initialisation.")
89
  raise StockfishException("Stockfish process terminated unexpectedly on init.")
90
+ engine.set_fen_position(chess.STARTING_FEN) # Test léger
91
  engine.get_best_move()
92
+ engine.set_fen_position(chess.STARTING_FEN) # Reset après test
93
+ app.logger.info(f"Moteur Stockfish (classe) initialisé avec succès utilisant l'exécutable: {STOCKFISH_EXECUTABLE_PATH_GLOBAL}.")
94
  return engine
95
  except Exception as e:
96
+ app.logger.error(f"Erreur lors de l'initialisation de la classe Stockfish (exécutable: {STOCKFISH_EXECUTABLE_PATH_GLOBAL}): {e}", exc_info=True)
97
  return None
98
 
99
+ # --- Définition des Routes ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
 
101
  @app.route('/')
102
  def index():
103
  app.logger.debug(f"Session au début de GET /: {dict(session.items())}")
 
105
  app.logger.info("Initialisation de la session (board_fen, game_mode, player_color) dans GET /")
106
  session['board_fen'] = chess.Board().fen()
107
  session['game_mode'] = 'pvp'
108
+ session['player_color'] = 'white'
109
 
110
  board = chess.Board(session['board_fen'])
111
  app.logger.debug(f"Session à la fin de GET /: {dict(session.items())}")
 
118
  outcome=get_outcome_message(board) if board.is_game_over() else "",
119
  current_turn = 'white' if board.turn == chess.WHITE else 'black')
120
 
 
121
  def get_outcome_message(board):
122
  if board.is_checkmate():
123
  winner_color = "Blancs" if board.turn == chess.BLACK else "Noirs"
 
130
  return ""
131
 
132
  @app.route('/make_move', methods=['POST'])
133
+ def make_move():
134
  app.logger.debug(f"Session au début de POST /make_move: {dict(session.items())}")
135
  if 'board_fen' not in session:
136
  app.logger.error("ERREUR CRITIQUE: 'board_fen' non trouvé dans la session pour POST /make_move!")
 
149
 
150
  ai_move_made = False
151
  ai_move_uci = None
 
152
  move_to_highlight = None
153
+ move = None
154
 
155
  try:
156
  move = board.parse_uci(move_uci_san)
 
163
  app.logger.warning(f"Mouvement invalide (ni UCI ni SAN): {move_uci_san} pour FEN {board.fen()}")
164
  return jsonify({'error': f'Mouvement invalide: {move_uci_san}', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)})
165
 
166
+ if move and move in board.legal_moves:
167
  board.push(move)
 
168
  move_to_highlight = move
169
  session['board_fen'] = board.fen()
170
  app.logger.info(f"Mouvement joueur {move.uci()} appliqué. Nouveau FEN: {board.fen()}")
 
196
  else:
197
  app.logger.warning("L'IA (Stockfish) n'a pas retourné de coup.")
198
 
199
+ # APPEL À send_quit_command() COMMENTÉ COMME DEMANDÉ
200
+ # if hasattr(stockfish_engine, 'send_quit_command'):
201
+ # stockfish_engine.send_quit_command()
202
+ # app.logger.info("Moteur Stockfish arrêté après le coup de l'IA.")
203
+ # elif hasattr(stockfish_engine, '__del__') and callable(getattr(stockfish_engine, '__del__')):
204
+ # app.logger.warning("send_quit_command() n'existe pas, __del__ sera potentiellement utilisé.")
205
+ # else:
206
+ # app.logger.error("Ni send_quit_command ni __del__ ne semblent disponibles pour arrêter Stockfish proprement.")
207
+ app.logger.info("Appel explicite à send_quit_command retiré (après coup IA). Le processus Stockfish peut rester actif.")
208
+ # del stockfish_engine # Optionnel: pour essayer de forcer __del__ si la lib le gère bien
209
 
210
  else:
211
  app.logger.error("Moteur Stockfish non disponible pour le coup de l'IA.")
212
+ elif move:
213
  app.logger.warning(f"Mouvement illégal tenté: {move.uci() if hasattr(move, 'uci') else move_uci_san} depuis FEN: {session['board_fen']}")
 
 
214
  return jsonify({'error': f'Mouvement illégal: {move.uci() if hasattr(move, "uci") else move_uci_san}', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)})
215
+ else:
 
 
216
  app.logger.error("La variable 'move' est None après la tentative de parsing, ce qui ne devrait pas arriver ici.")
217
  return jsonify({'error': 'Erreur interne de parsing de coup.', 'fen': board.fen(), 'game_over': board.is_game_over(), 'board_svg': chess.svg.board(board=board, size=400)}), 500
218
 
 
219
  game_over = board.is_game_over()
220
  outcome = get_outcome_message(board) if game_over else ""
221
  if game_over:
 
285
  except Exception as e:
286
  app.logger.error(f"Erreur en appliquant le premier coup de l'IA {best_move_ai}: {e}", exc_info=True)
287
 
288
+ # APPEL À send_quit_command() COMMENTÉ COMME DEMANDÉ
289
+ # if hasattr(stockfish_engine, 'send_quit_command'):
290
+ # stockfish_engine.send_quit_command()
291
+ # app.logger.info("Moteur Stockfish arrêté après le premier coup de l'IA.")
292
+ # elif hasattr(stockfish_engine, '__del__') and callable(getattr(stockfish_engine, '__del__')):
293
+ # app.logger.warning("send_quit_command() n'existe pas, __del__ sera potentiellement utilisé.")
294
+ # else:
295
+ # app.logger.error("Ni send_quit_command ni __del__ pour arrêter Stockfish (premier coup IA).")
296
+ app.logger.info("Appel explicite à send_quit_command retiré (après premier coup IA). Le processus Stockfish peut rester actif.")
297
+ # del stockfish_engine # Optionnel
298
+
299
  else:
300
  app.logger.error("Moteur Stockfish non disponible pour le premier coup de l'IA.")
301
 
 
315
  app.logger.warning(f"Tentative de définir un mode de jeu invalide: {mode}")
316
  return jsonify({'error': 'Mode invalide'}), 400
317
 
 
318
  if __name__ == '__main__':
319
  app.run(host='0.0.0.0', port=5000) # IS_DEBUG_MODE et app.debug sont gérés plus haut