Docfile commited on
Commit
dfaf016
·
verified ·
1 Parent(s): 8a91eec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +141 -151
app.py CHANGED
@@ -1,208 +1,198 @@
1
- # app.py
2
  from flask import Flask, render_template, request, jsonify, session
3
  from stockfish import Stockfish
4
  import uuid
5
- import chess
6
- import chess.pgn
7
- from datetime import datetime
8
 
9
  app = Flask(__name__)
10
  app.secret_key = 'your-secret-key-change-this'
11
 
12
  # Configuration Stockfish
13
- try:
14
- stockfish = Stockfish(
15
- path="/usr/local/bin/stockfish", # Ajustez selon votre installation
16
- parameters={
17
- "Threads": 2,
18
- "Hash": 256,
19
- "Skill Level": 15, # Niveau IA (0-20)
20
- "Minimum Thinking Time": 100
21
- }
22
- )
23
- except:
24
- stockfish = None
25
- print("Stockfish non trouvé. Mode IA désactivé.")
26
 
27
  class ChessGame:
28
- def __init__(self, game_id, mode='human'):
29
  self.game_id = game_id
30
- self.mode = mode # 'human' ou 'ai'
31
- self.board = chess.Board()
32
  self.moves_history = []
33
- self.current_player = 'white'
34
- self.game_status = 'active' # 'active', 'checkmate', 'stalemate', 'draw'
35
- self.created_at = datetime.now()
36
 
37
- def make_move(self, move_uci):
38
- """Effectue un coup et retourne le résultat"""
39
- try:
40
- move = chess.Move.from_uci(move_uci)
 
 
 
 
 
 
 
41
 
42
- if move in self.board.legal_moves:
43
- self.board.push(move)
44
- self.moves_history.append(move_uci)
45
-
46
- # Changer de joueur
47
- self.current_player = 'black' if self.current_player == 'white' else 'white'
48
-
49
- # Vérifier l'état du jeu
50
- self._update_game_status()
51
-
52
- return {
53
- 'success': True,
54
- 'move': move_uci,
55
- 'board_fen': self.board.fen(),
56
- 'current_player': self.current_player,
57
- 'game_status': self.game_status,
58
- 'legal_moves': [move.uci() for move in self.board.legal_moves],
59
- 'is_check': self.board.is_check()
60
- }
61
- else:
62
- return {'success': False, 'error': 'Coup illégal'}
63
-
64
- except Exception as e:
65
- return {'success': False, 'error': str(e)}
66
 
67
- def get_ai_move(self):
68
- """Obtient le coup de l'IA via Stockfish"""
69
- if not stockfish or self.mode != 'ai':
70
- return None
 
 
 
 
 
 
 
 
 
 
71
 
72
- try:
73
- stockfish.set_fen_position(self.board.fen())
74
- ai_move = stockfish.get_best_move()
75
- return ai_move
76
- except:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  return None
 
 
 
 
 
 
 
 
 
78
 
79
- def _update_game_status(self):
80
- """Met à jour l'état du jeu"""
81
- if self.board.is_checkmate():
82
- winner = 'black' if self.current_player == 'white' else 'white'
83
- self.game_status = f'checkmate_{winner}'
84
- elif self.board.is_stalemate():
85
- self.game_status = 'stalemate'
86
- elif self.board.is_insufficient_material():
87
- self.game_status = 'draw_material'
88
- elif self.board.is_seventyfive_moves():
89
- self.game_status = 'draw_75moves'
90
- elif self.board.is_fivefold_repetition():
91
- self.game_status = 'draw_repetition'
92
-
93
- def get_board_state(self):
94
- """Retourne l'état complet du plateau"""
95
  return {
96
- 'fen': self.board.fen(),
97
- 'current_player': self.current_player,
98
- 'game_status': self.game_status,
99
- 'legal_moves': [move.uci() for move in self.board.legal_moves],
100
- 'is_check': self.board.is_check(),
101
- 'moves_history': self.moves_history,
102
- 'move_count': len(self.moves_history)
 
103
  }
104
 
105
- # Stockage des parties en mémoire (remplacez par une base de données en production)
106
- games = {}
107
-
108
  @app.route('/')
109
  def index():
110
  return render_template('index.html')
111
 
112
- @app.route('/game/<mode>')
113
- def game(mode):
114
- if mode not in ['human', 'ai']:
115
- return "Mode de jeu invalide", 400
 
116
 
117
- # Créer une nouvelle partie
118
  game_id = str(uuid.uuid4())
119
- games[game_id] = ChessGame(game_id, mode)
 
 
 
120
  session['game_id'] = game_id
121
 
122
- return render_template('game.html', mode=mode, game_id=game_id)
 
 
 
123
 
124
- @app.route('/api/game/state')
125
- def get_game_state():
126
- game_id = session.get('game_id')
127
- if not game_id or game_id not in games:
128
- return jsonify({'error': 'Partie non trouvée'}), 404
129
-
130
- game = games[game_id]
131
- return jsonify(game.get_board_state())
132
-
133
- @app.route('/api/game/move', methods=['POST'])
134
  def make_move():
135
- game_id = session.get('game_id')
136
- if not game_id or game_id not in games:
137
- return jsonify({'error': 'Partie non trouvée'}), 404
138
-
139
  data = request.json
 
140
  move = data.get('move')
141
 
142
- if not move:
143
- return jsonify({'error': 'Coup manquant'}), 400
144
-
145
- game = games[game_id]
146
- result = game.make_move(move)
147
-
148
- return jsonify(result)
149
-
150
- @app.route('/api/game/ai-move', methods=['POST'])
151
- def get_ai_move():
152
- game_id = session.get('game_id')
153
  if not game_id or game_id not in games:
154
- return jsonify({'error': 'Partie non trouvée'}), 404
155
 
156
  game = games[game_id]
 
157
 
158
- if game.mode != 'ai':
159
- return jsonify({'error': 'Mode IA non activé'}), 400
160
-
161
- if game.current_player != 'black': # IA joue les noirs
162
- return jsonify({'error': 'Ce n\'est pas le tour de l\'IA'}), 400
163
 
164
- ai_move = game.get_ai_move()
165
- if not ai_move:
166
- return jsonify({'error': 'IA ne peut pas jouer'}), 500
 
167
 
168
- # Effectuer le coup de l'IA
169
- result = game.make_move(ai_move)
170
- result['ai_move'] = True
 
 
 
 
171
 
172
- return jsonify(result)
173
 
174
- @app.route('/api/game/reset', methods=['POST'])
175
- def reset_game():
 
176
  game_id = session.get('game_id')
 
177
  if not game_id or game_id not in games:
178
- return jsonify({'error': 'Partie non trouvée'}), 404
179
 
180
  game = games[game_id]
181
- # Réinitialiser la partie
182
- games[game_id] = ChessGame(game_id, game.mode)
183
-
184
- return jsonify({'success': True, 'message': 'Partie réinitialisée'})
185
 
186
- @app.route('/api/game/legal-moves')
187
  def get_legal_moves():
 
188
  game_id = session.get('game_id')
189
- if not game_id or game_id not in games:
190
- return jsonify({'error': 'Partie non trouvée'}), 404
191
-
192
- data = request.args
193
- square = data.get('square')
194
 
195
- if not square:
196
- return jsonify({'error': 'Case manquante'}), 400
197
 
198
  game = games[game_id]
199
- legal_moves = []
 
 
 
 
 
 
 
 
200
 
201
- for move in game.board.legal_moves:
202
- if move.from_square == chess.parse_square(square):
203
- legal_moves.append(chess.square_name(move.to_square))
 
 
 
 
 
204
 
205
- return jsonify({'legal_moves': legal_moves})
206
 
207
  if __name__ == '__main__':
208
  app.run(debug=True)
 
 
1
  from flask import Flask, render_template, request, jsonify, session
2
  from stockfish import Stockfish
3
  import uuid
4
+ import json
 
 
5
 
6
  app = Flask(__name__)
7
  app.secret_key = 'your-secret-key-change-this'
8
 
9
  # Configuration Stockfish
10
+ STOCKFISH_PATH = "/usr/games/stockfish" # Ajustez selon votre installation
11
+
12
+ # Stockage des parties en cours (en production, utilisez une base de données)
13
+ games = {}
 
 
 
 
 
 
 
 
 
14
 
15
  class ChessGame:
16
+ def __init__(self, game_id, mode="human"):
17
  self.game_id = game_id
18
+ self.mode = mode # "human" ou "ai"
19
+ self.current_player = "white"
20
  self.moves_history = []
21
+ self.game_over = False
22
+ self.winner = None
 
23
 
24
+ # Initialiser Stockfish pour le mode AI
25
+ if mode == "ai":
26
+ try:
27
+ self.stockfish = Stockfish(path=STOCKFISH_PATH)
28
+ self.stockfish.set_depth(10)
29
+ except:
30
+ # Fallback si Stockfish n'est pas trouvé
31
+ self.stockfish = None
32
+ print("Attention: Stockfish non trouvé, mode AI désactivé")
33
+ else:
34
+ self.stockfish = None
35
 
36
+ # Position de départ FEN
37
+ self.fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
38
+
39
+ if self.stockfish:
40
+ self.stockfish.set_fen_position(self.fen)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ def make_move(self, move):
43
+ """Effectuer un coup"""
44
+ if self.game_over:
45
+ return False, "La partie est terminée"
46
+
47
+ if self.stockfish:
48
+ # Vérifier si le coup est légal
49
+ legal_moves = self.stockfish.get_legal_moves()
50
+ if move not in legal_moves:
51
+ return False, "Coup illégal"
52
+
53
+ # Effectuer le coup
54
+ self.stockfish.make_moves_from_current_position([move])
55
+ self.fen = self.stockfish.get_fen_position()
56
 
57
+ # Vérifier fin de partie
58
+ if self.stockfish.is_game_over():
59
+ self.game_over = True
60
+ if self.stockfish.is_checkmate():
61
+ self.winner = self.current_player
62
+ else:
63
+ self.winner = "draw"
64
+ else:
65
+ # Mode basique sans validation (pour le mode humain sans Stockfish)
66
+ pass
67
+
68
+ self.moves_history.append(move)
69
+ self.current_player = "black" if self.current_player == "white" else "white"
70
+
71
+ return True, "Coup effectué"
72
+
73
+ def get_ai_move(self):
74
+ """Obtenir le coup de l'IA"""
75
+ if not self.stockfish or self.current_player != "black":
76
  return None
77
+
78
+ best_move = self.stockfish.get_best_move()
79
+ return best_move
80
+
81
+ def get_legal_moves(self):
82
+ """Obtenir les coups légaux"""
83
+ if self.stockfish:
84
+ return self.stockfish.get_legal_moves()
85
+ return []
86
 
87
+ def get_game_state(self):
88
+ """Obtenir l'état complet du jeu"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  return {
90
+ "game_id": self.game_id,
91
+ "mode": self.mode,
92
+ "current_player": self.current_player,
93
+ "fen": self.fen,
94
+ "moves_history": self.moves_history,
95
+ "game_over": self.game_over,
96
+ "winner": self.winner,
97
+ "legal_moves": self.get_legal_moves()
98
  }
99
 
 
 
 
100
  @app.route('/')
101
  def index():
102
  return render_template('index.html')
103
 
104
+ @app.route('/api/new_game', methods=['POST'])
105
+ def new_game():
106
+ """Créer une nouvelle partie"""
107
+ data = request.json
108
+ mode = data.get('mode', 'human') # 'human' ou 'ai'
109
 
 
110
  game_id = str(uuid.uuid4())
111
+ game = ChessGame(game_id, mode)
112
+ games[game_id] = game
113
+
114
+ # Stocker l'ID de partie dans la session
115
  session['game_id'] = game_id
116
 
117
+ return jsonify({
118
+ "success": True,
119
+ "game_state": game.get_game_state()
120
+ })
121
 
122
+ @app.route('/api/make_move', methods=['POST'])
 
 
 
 
 
 
 
 
 
123
  def make_move():
124
+ """Effectuer un coup"""
 
 
 
125
  data = request.json
126
+ game_id = session.get('game_id')
127
  move = data.get('move')
128
 
 
 
 
 
 
 
 
 
 
 
 
129
  if not game_id or game_id not in games:
130
+ return jsonify({"success": False, "error": "Partie non trouvée"})
131
 
132
  game = games[game_id]
133
+ success, message = game.make_move(move)
134
 
135
+ if not success:
136
+ return jsonify({"success": False, "error": message})
 
 
 
137
 
138
+ response_data = {
139
+ "success": True,
140
+ "game_state": game.get_game_state()
141
+ }
142
 
143
+ # Si c'est le mode AI et c'est au tour de l'IA
144
+ if game.mode == "ai" and game.current_player == "black" and not game.game_over:
145
+ ai_move = game.get_ai_move()
146
+ if ai_move:
147
+ game.make_move(ai_move)
148
+ response_data["ai_move"] = ai_move
149
+ response_data["game_state"] = game.get_game_state()
150
 
151
+ return jsonify(response_data)
152
 
153
+ @app.route('/api/game_state', methods=['GET'])
154
+ def get_game_state():
155
+ """Obtenir l'état actuel du jeu"""
156
  game_id = session.get('game_id')
157
+
158
  if not game_id or game_id not in games:
159
+ return jsonify({"success": False, "error": "Partie non trouvée"})
160
 
161
  game = games[game_id]
162
+ return jsonify({
163
+ "success": True,
164
+ "game_state": game.get_game_state()
165
+ })
166
 
167
+ @app.route('/api/legal_moves', methods=['GET'])
168
  def get_legal_moves():
169
+ """Obtenir les coups légaux pour la position actuelle"""
170
  game_id = session.get('game_id')
 
 
 
 
 
171
 
172
+ if not game_id or game_id not in games:
173
+ return jsonify({"success": False, "error": "Partie non trouvée"})
174
 
175
  game = games[game_id]
176
+ return jsonify({
177
+ "success": True,
178
+ "legal_moves": game.get_legal_moves()
179
+ })
180
+
181
+ @app.route('/api/reset_game', methods=['POST'])
182
+ def reset_game():
183
+ """Réinitialiser la partie actuelle"""
184
+ game_id = session.get('game_id')
185
 
186
+ if game_id and game_id in games:
187
+ mode = games[game_id].mode
188
+ games[game_id] = ChessGame(game_id, mode)
189
+
190
+ return jsonify({
191
+ "success": True,
192
+ "game_state": games[game_id].get_game_state()
193
+ })
194
 
195
+ return jsonify({"success": False, "error": "Partie non trouvée"})
196
 
197
  if __name__ == '__main__':
198
  app.run(debug=True)