Docfile commited on
Commit
2cbb5b0
·
verified ·
1 Parent(s): bf22ad3

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +237 -402
templates/index.html CHANGED
@@ -3,439 +3,274 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Chess vs Stockfish</title>
7
-
8
- <!-- Chess.js et Chessboard.js -->
9
- <link rel="stylesheet" href="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.css">
10
- <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
11
- <script src="https://unpkg.com/[email protected]/chess.min.js"></script>
12
- <script src="https://unpkg.com/@chrisoakman/[email protected]/dist/chessboard-1.0.0.min.js"></script>
13
-
14
  <style>
15
- body {
16
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
17
- max-width: 1200px;
18
- margin: 0 auto;
19
- padding: 20px;
20
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
21
- min-height: 100vh;
22
- box-sizing: border-box;
23
- }
24
-
25
- .container {
26
- background: rgba(255, 255, 255, 0.95);
27
- border-radius: 20px;
28
- padding: 30px;
29
- box-shadow: 0 20px 40px rgba(0,0,0,0.1);
30
- backdrop-filter: blur(10px);
31
- }
32
-
33
- h1 {
34
- text-align: center;
35
- color: #333;
36
- margin-bottom: 30px;
37
- font-size: 2.5em;
38
- text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
39
- }
40
-
41
- .game-container {
42
- display: flex;
43
- gap: 30px;
44
- justify-content: center;
45
- align-items: flex-start;
46
- flex-wrap: wrap;
47
- }
48
-
49
- .board-container {
50
- flex-shrink: 0;
51
- }
52
-
53
- #myBoard {
54
- border: 4px solid #8B4513;
55
- border-radius: 10px;
56
- box-shadow: 0 10px 25px rgba(0,0,0,0.3);
57
- }
58
-
59
- .info-panel {
60
- background: #f8f9fa;
61
- border-radius: 15px;
62
- padding: 25px;
63
- min-width: 300px;
64
- box-shadow: 0 5px 15px rgba(0,0,0,0.1);
65
- }
66
-
67
- .status {
68
- font-size: 1.2em;
69
- font-weight: bold;
70
- margin-bottom: 15px;
71
- padding: 15px;
72
- border-radius: 10px;
73
- text-align: center;
74
- }
75
-
76
- .status.playing {
77
- background: linear-gradient(45deg, #4CAF50, #45a049);
78
- color: white;
79
- }
80
-
81
- .status.game-over {
82
- background: linear-gradient(45deg, #f44336, #d32f2f);
83
- color: white;
84
- }
85
-
86
- .controls {
87
- display: flex;
88
- flex-direction: column;
89
- gap: 15px;
90
- margin-top: 20px;
91
- }
92
-
93
- button {
94
- background: linear-gradient(45deg, #667eea, #764ba2);
95
- color: white;
96
- border: none;
97
- padding: 12px 20px;
98
- border-radius: 8px;
99
- cursor: pointer;
100
- font-size: 1em;
101
- font-weight: bold;
102
- transition: all 0.3s ease;
103
- box-shadow: 0 4px 10px rgba(0,0,0,0.2);
104
- }
105
-
106
- button:hover:not(:disabled) {
107
- transform: translateY(-2px);
108
- box-shadow: 0 6px 15px rgba(0,0,0,0.3);
109
- }
110
-
111
- button:disabled {
112
- background: #ccc;
113
- cursor: not-allowed;
114
- transform: none;
115
- box-shadow: none;
116
- }
117
-
118
- .evaluation {
119
- background: #e3f2fd;
120
- padding: 15px;
121
- border-radius: 10px;
122
- margin: 15px 0;
123
- border-left: 4px solid #2196F3;
124
- }
125
-
126
- .evaluation h3 {
127
- margin: 0 0 10px 0;
128
- color: #1976D2;
129
- }
130
-
131
- .move-history {
132
- background: #fff3e0;
133
- padding: 15px;
134
- border-radius: 10px;
135
- margin: 15px 0;
136
- border-left: 4px solid #FF9800;
137
- max-height: 200px;
138
- overflow-y: auto;
139
- }
140
-
141
- .move-history h3 {
142
- margin: 0 0 10px 0;
143
- color: #F57C00;
144
- }
145
-
146
- .loading {
147
- display: none;
148
- text-align: center;
149
- color: #666;
150
- font-style: italic;
151
- margin: 10px 0;
152
- }
153
-
154
- .loading.show {
155
  display: block;
 
 
 
156
  }
157
-
158
- .error {
159
- background: #ffebee;
160
- color: #c62828;
161
- padding: 10px;
162
- border-radius: 5px;
163
- margin: 10px 0;
164
- border-left: 4px solid #f44336;
165
- }
166
-
167
- @media (max-width: 768px) {
168
- .game-container {
169
- flex-direction: column;
170
- align-items: center;
171
- }
172
-
173
- .info-panel {
174
- min-width: auto;
175
- width: 100%;
176
- max-width: 500px;
177
- }
178
  }
179
  </style>
180
  </head>
181
- <body>
182
- <div class="container">
183
- <h1>🏁 Chess vs Stockfish</h1>
184
-
185
- <div class="game-container">
186
- <div class="board-container">
187
- <div id="myBoard" style="width: 400px"></div>
188
- </div>
189
-
190
- <div class="info-panel">
191
- <div id="status" class="status playing">À vous de jouer !</div>
192
-
193
- <div class="loading" id="loading">
194
- Stockfish réfléchit...
 
 
 
 
195
  </div>
196
-
197
- <div class="evaluation">
198
- <h3>📊 Évaluation</h3>
199
- <div id="evaluation">Position de départ</div>
 
 
 
 
 
 
 
 
 
 
200
  </div>
 
 
 
 
 
 
201
 
202
- <div class="move-history">
203
- <h3>📝 Derniers coups</h3>
204
- <div id="moveHistory">Nouvelle partie</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  </div>
206
-
207
- <div class="controls">
208
- <button id="newGameBtn">🔄 Nouvelle partie</button>
209
- <button id="analyzeBtn">🔍 Analyser position</button>
210
- <button id="flipBtn">🔄 Retourner échiquier</button>
211
  </div>
212
-
213
- <div id="error" class="error" style="display: none;"></div>
214
  </div>
215
  </div>
216
  </div>
217
 
218
  <script>
219
- let game = new Chess();
220
- let board = null;
221
- let gameOver = false;
222
- let moveHistory = [];
223
-
224
- // Configuration de l'échiquier
225
- const config = {
226
- draggable: true,
227
- position: 'start',
228
- onDragStart: onDragStart,
229
- onDrop: onDrop,
230
- onSnapEnd: onSnapEnd
231
- };
232
-
233
- board = Chessboard('myBoard', config);
234
-
235
- function onDragStart(source, piece, position, orientation) {
236
- // Ne pas permettre de déplacer les pièces si c'est terminé
237
- if (gameOver) return false;
238
-
239
- // Ne permettre de déplacer que les pièces blanches (joueur)
240
- if (piece.search(/^b/) !== -1) return false;
241
-
242
- // Ne pas permettre de déplacer si ce n'est pas le tour des blancs
243
- if (game.turn() === 'b') return false;
244
- }
245
-
246
- function onDrop(source, target) {
247
- // Voir si le coup est légal
248
- const move = game.move({
249
- from: source,
250
- to: target,
251
- promotion: 'q' // Toujours promouvoir en dame pour simplifier
252
- });
253
 
254
- // Coup illégal
255
- if (move === null) return 'snapback';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
 
257
- // Coup légal - envoyer au serveur
258
- makeMove(move.san);
259
  }
260
-
261
- function onSnapEnd() {
262
- board.position(game.fen());
263
- }
264
-
265
- function makeMove(userMove) {
266
- if (gameOver) return;
267
-
268
- showLoading(true);
269
- hideError();
270
-
271
- fetch('/api/move', {
272
- method: 'POST',
273
- headers: {
274
- 'Content-Type': 'application/json',
275
- },
276
- body: JSON.stringify({
277
- fen: game.fen(),
278
- move: userMove
279
- })
280
- })
281
- .then(response => response.json())
282
- .then(data => {
283
- showLoading(false);
284
-
285
- if (data.error) {
286
- showError(data.error);
287
- // Rétablir la position précédente
288
- game.undo();
289
- board.position(game.fen());
290
- return;
291
- }
292
-
293
- // Mettre à jour le jeu avec la nouvelle position
294
- game.load(data.fen);
295
- board.position(game.fen());
296
-
297
- // Ajouter les coups à l'historique
298
- if (data.stockfish_move) {
299
- addToMoveHistory(userMove, data.stockfish_move);
300
- } else {
301
- addToMoveHistory(userMove, null);
302
- }
303
-
304
- // Mettre à jour l'évaluation
305
- updateEvaluation(data.evaluation);
306
-
307
- // Vérifier si la partie est terminée
308
- if (data.game_over) {
309
- gameOver = true;
310
- updateStatus(data.result || 'Partie terminée', true);
311
  } else {
312
- updateStatus('À vous de jouer !', false);
 
 
 
 
 
313
  }
314
- })
315
- .catch(error => {
316
- showLoading(false);
317
- showError('Erreur de communication: ' + error.message);
318
- // Rétablir la position précédente
319
- game.undo();
320
- board.position(game.fen());
321
- });
322
- }
323
-
324
- function showLoading(show) {
325
- const loading = document.getElementById('loading');
326
- if (show) {
327
- loading.classList.add('show');
328
- } else {
329
- loading.classList.remove('show');
330
  }
331
  }
332
-
333
- function showError(message) {
334
- const errorDiv = document.getElementById('error');
335
- errorDiv.textContent = message;
336
- errorDiv.style.display = 'block';
337
- }
338
-
339
- function hideError() {
340
- document.getElementById('error').style.display = 'none';
341
- }
342
-
343
- function updateStatus(message, isGameOver = false) {
344
- const statusDiv = document.getElementById('status');
345
- statusDiv.textContent = message;
346
- statusDiv.className = isGameOver ? 'status game-over' : 'status playing';
347
- }
348
-
349
- function updateEvaluation(evaluation) {
350
- const evalDiv = document.getElementById('evaluation');
351
-
352
- if (evaluation.type === 'cp') {
353
- const centipawns = evaluation.value;
354
- const pawns = (centipawns / 100).toFixed(2);
355
- if (pawns > 0) {
356
- evalDiv.textContent = `Blancs +${pawns}`;
357
- } else if (pawns < 0) {
358
- evalDiv.textContent = `Noirs +${Math.abs(pawns)}`;
359
  } else {
360
- evalDiv.textContent = 'Position équilibrée';
 
361
  }
362
- } else if (evaluation.type === 'mate') {
363
- const mateIn = evaluation.value;
364
- if (mateIn > 0) {
365
- evalDiv.textContent = `Mat en ${mateIn} pour les blancs`;
366
- } else if (mateIn < 0) {
367
- evalDiv.textContent = `Mat en ${Math.abs(mateIn)} pour les noirs`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  } else {
369
- evalDiv.textContent = 'Mat ou Pat';
370
  }
 
 
 
 
 
 
371
  }
372
- }
373
-
374
- function addToMoveHistory(userMove, stockfishMove) {
375
- moveHistory.push({user: userMove, stockfish: stockfishMove});
376
-
377
- const historyDiv = document.getElementById('moveHistory');
378
- const lastMoves = moveHistory.slice(-5); // Garder les 5 derniers coups
379
-
380
- let historyText = '';
381
- lastMoves.forEach((moves, index) => {
382
- const moveNum = moveHistory.length - lastMoves.length + index + 1;
383
- historyText += `${moveNum}. ${moves.user}`;
384
- if (moves.stockfish) {
385
- historyText += ` ${moves.stockfish}`;
386
- }
387
- historyText += '\n';
388
- });
389
-
390
- historyDiv.textContent = historyText || 'Aucun coup joué';
391
- }
392
-
393
- // Gestionnaires d'événements pour les boutons
394
- document.getElementById('newGameBtn').addEventListener('click', function() {
395
- // Réinitialiser directement côté client
396
- game = new Chess();
397
- board.start();
398
- gameOver = false;
399
- moveHistory = [];
400
- updateStatus('À vous de jouer !', false);
401
- updateEvaluation({type: 'cp', value: 0});
402
- document.getElementById('moveHistory').textContent = 'Nouvelle partie';
403
- hideError();
404
-
405
- console.log('Nouvelle partie démarrée');
406
  });
407
-
408
- document.getElementById('analyzeBtn').addEventListener('click', function() {
409
- fetch('/api/analyze', {
410
- method: 'POST',
411
- headers: {
412
- 'Content-Type': 'application/json',
413
- },
414
- body: JSON.stringify({fen: game.fen()})
415
- })
416
- .then(response => response.json())
417
- .then(data => {
418
  if (data.error) {
419
- showError(data.error);
420
- return;
421
- }
422
-
423
- updateEvaluation(data.evaluation);
424
- if (data.best_move) {
425
- showError(`Meilleur coup suggéré: ${data.best_move}`);
 
 
 
 
 
 
 
 
 
426
  }
427
- })
428
- .catch(error => {
429
- showError('Erreur d\'analyse: ' + error.message);
430
- });
431
- });
432
-
433
- document.getElementById('flipBtn').addEventListener('click', function() {
434
- board.flip();
435
- });
436
-
437
- // Initialiser l'évaluation de départ
438
- updateEvaluation({type: 'cp', value: 0});
 
 
 
 
 
 
439
  </script>
440
  </body>
441
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Jeu d'Échecs Flask</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
 
 
 
 
 
 
8
  <style>
9
+ /* Pour centrer le SVG et éviter qu'il ne soit trop large sur mobile */
10
+ .board-container svg {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  display: block;
12
+ margin: 0 auto;
13
+ max-width: 100%;
14
+ height: auto;
15
  }
16
+ /* Simple highlight pour la dernière case jouée par l'IA */
17
+ .highlight-last-move rect.lastmove {
18
+ fill: rgba(255, 255, 0, 0.4) !important; /* Jaune semi-transparent */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
  </style>
21
  </head>
22
+ <body class="bg-gray-900 text-gray-100 min-h-screen flex flex-col items-center p-4">
23
+
24
+ <div class="container mx-auto max-w-4xl">
25
+ <h1 class="text-4xl font-bold text-center my-6 text-teal-400">Jeu d'Échecs</h1>
26
+
27
+ <div class="bg-gray-800 p-6 rounded-lg shadow-xl mb-6">
28
+ <h2 class="text-2xl font-semibold mb-3 text-sky-400">Configuration</h2>
29
+ <div class="flex flex-wrap gap-4 items-center">
30
+ <button id="setPvP" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
31
+ Humain vs Humain
32
+ </button>
33
+ <div>
34
+ <button id="setPvAIWhite" class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
35
+ Jouer vs IA (Blancs)
36
+ </button>
37
+ <button id="setPvAIBlack" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline mt-2 sm:mt-0 sm:ml-2">
38
+ Jouer vs IA (Noirs)
39
+ </button>
40
  </div>
41
+ <button id="resetGame" class="bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
42
+ Nouvelle Partie (Reset)
43
+ </button>
44
+ </div>
45
+ <p class="mt-3 text-sm text-gray-400">Mode Actuel: <span id="currentMode" class="font-semibold">{{ game_mode.upper() }}</span></p>
46
+ <p id="playerColorInfo" class="mt-1 text-sm text-gray-400 {% if game_mode != 'ai' %}hidden{% endif %}">
47
+ Vous jouez avec les: <span id="currentPlayerColor" class="font-semibold">{{ player_color.capitalize() if player_color else 'N/A' }}</span>
48
+ </p>
49
+ </div>
50
+
51
+ <div class="grid md:grid-cols-3 gap-6">
52
+ <div class="md:col-span-2 bg-gray-800 p-2 sm:p-6 rounded-lg shadow-xl board-container">
53
+ <div id="boardDisplay" class="highlight-last-move">
54
+ {{ initial_board_svg|safe }}
55
  </div>
56
+ </div>
57
+
58
+ <div class="bg-gray-800 p-6 rounded-lg shadow-xl">
59
+ <h3 class="text-xl font-semibold mb-3 text-sky-400">Informations</h3>
60
+ <p id="turnDisplay" class="mb-2">Tour des: <span class="font-bold">Blancs</span></p>
61
+ <p id="status" class="text-yellow-400 font-semibold mb-4 h-6"></p>
62
 
63
+ <form id="moveForm" class="space-y-3">
64
+ <div>
65
+ <label for="moveInput" class="block text-sm font-medium text-gray-300">Votre coup (ex: e2e4, Nf3):</label>
66
+ <input type="text" id="moveInput" name="move"
67
+ class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-sky-500 focus:border-sky-500 sm:text-sm text-white"
68
+ placeholder="e.g., e2e4">
69
+ </div>
70
+ <button type="submit"
71
+ class="w-full bg-teal-600 hover:bg-teal-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline transition duration-150 ease-in-out">
72
+ Jouer
73
+ </button>
74
+ </form>
75
+
76
+ <div id="outcomeDisplay" class="mt-4 text-lg font-bold text-center">
77
+ {% if is_game_over %}
78
+ <p class="text-green-400">{{ outcome }}</p>
79
+ {% endif %}
80
  </div>
81
+ <div class="mt-4">
82
+ <p class="text-sm text-gray-400">Dernier coup IA:</p>
83
+ <p id="lastAIMove" class="text-gray-200 font-mono">-</p>
 
 
84
  </div>
 
 
85
  </div>
86
  </div>
87
  </div>
88
 
89
  <script>
90
+ const boardDisplay = document.getElementById('boardDisplay');
91
+ const moveForm = document.getElementById('moveForm');
92
+ const moveInput = document.getElementById('moveInput');
93
+ const statusDisplay = document.getElementById('status');
94
+ const turnDisplay = document.getElementById('turnDisplay').querySelector('span');
95
+ const outcomeDisplay = document.getElementById('outcomeDisplay');
96
+ const lastAIMoveDisplay = document.getElementById('lastAIMove');
97
+
98
+ const currentModeDisplay = document.getElementById('currentMode');
99
+ const playerColorInfoDisplay = document.getElementById('playerColorInfo');
100
+ const currentPlayerColorDisplay = document.getElementById('currentPlayerColor');
101
+
102
+ let currentFEN = "{{ initial_fen }}";
103
+ let gameMode = "{{ game_mode }}";
104
+ let playerColor = "{{ player_color if player_color else 'white' }}"; // Couleur du joueur humain en mode AI
105
+ let isPlayerTurn = true; // Utilisé en mode AI
106
+
107
+ function updateBoard(data) {
108
+ if (data.board_svg) {
109
+ boardDisplay.innerHTML = data.board_svg;
110
+ }
111
+ currentFEN = data.fen;
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ if (data.turn) {
114
+ turnDisplay.textContent = data.turn === 'white' ? 'Blancs' : 'Noirs';
115
+ } else {
116
+ // Déduire du FEN si non fourni explicitement
117
+ const fenTurn = data.fen.split(' ')[1];
118
+ turnDisplay.textContent = fenTurn === 'w' ? 'Blancs' : 'Noirs';
119
+ }
120
+
121
+ if (data.ai_move_uci) {
122
+ lastAIMoveDisplay.textContent = data.ai_move_uci;
123
+ } else if (!data.game_over) {
124
+ // Ne pas effacer si la partie est finie et que le dernier coup était humain
125
+ // lastAIMoveDisplay.textContent = "-";
126
+ }
127
+
128
+
129
+ if (data.game_over) {
130
+ statusDisplay.textContent = "Partie terminée!";
131
+ outcomeDisplay.innerHTML = `<p class="text-green-400">${data.outcome}</p>`;
132
+ moveInput.disabled = true;
133
+ moveForm.querySelector('button[type="submit"]').disabled = true;
134
+ } else {
135
+ statusDisplay.textContent = '';
136
+ outcomeDisplay.innerHTML = '';
137
+ moveInput.disabled = false;
138
+ moveForm.querySelector('button[type="submit"]').disabled = false;
139
+ }
140
 
141
+ // Gérer le tour du joueur en mode AI
142
+ updatePlayerTurnState();
143
  }
144
+
145
+ function updatePlayerTurnState() {
146
+ const fenTurn = currentFEN.split(' ')[1]; // 'w' or 'b'
147
+ if (gameMode === 'ai') {
148
+ const aiIsWhite = (playerColor === 'black');
149
+ const aiIsBlack = (playerColor === 'white');
150
+
151
+ if ((aiIsWhite && fenTurn === 'w') || (aiIsBlack && fenTurn === 'b')) {
152
+ isPlayerTurn = false;
153
+ moveInput.disabled = true;
154
+ moveForm.querySelector('button[type="submit"]').disabled = true;
155
+ statusDisplay.textContent = "L'IA réfléchit...";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  } else {
157
+ isPlayerTurn = true;
158
+ if (!currentFEN.split(' ')[0].includes('k') || !currentFEN.split(' ')[0].includes('K')) { // Check si la partie est terminée
159
+ moveInput.disabled = false;
160
+ moveForm.querySelector('button[type="submit"]').disabled = false;
161
+ }
162
+ statusDisplay.textContent = "À vous de jouer.";
163
  }
164
+ } else { // PvP mode
165
+ isPlayerTurn = true; // Toujours au tour du joueur en PvP
166
+ moveInput.disabled = false;
167
+ moveForm.querySelector('button[type="submit"]').disabled = false;
 
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
  }
170
+
171
+
172
+ moveForm.addEventListener('submit', async (e) => {
173
+ e.preventDefault();
174
+ const move = moveInput.value.trim();
175
+ if (!move) return;
176
+
177
+ statusDisplay.textContent = 'Traitement...';
178
+ lastAIMoveDisplay.textContent = "-"; // Clear last AI move when player submits
179
+
180
+ try {
181
+ const response = await fetch('/make_move', {
182
+ method: 'POST',
183
+ headers: { 'Content-Type': 'application/json' },
184
+ body: JSON.stringify({ move: move })
185
+ });
186
+ const data = await response.json();
187
+
188
+ if (data.error) {
189
+ statusDisplay.textContent = `Erreur: ${data.error}`;
 
 
 
 
 
 
 
190
  } else {
191
+ updateBoard(data);
192
+ moveInput.value = ''; // Clear input on successful move
193
  }
194
+ } catch (error) {
195
+ console.error("Erreur lors de la communication:", error);
196
+ statusDisplay.textContent = "Erreur de communication avec le serveur.";
197
+ }
198
+ });
199
+
200
+ document.getElementById('resetGame').addEventListener('click', async () => {
201
+ statusDisplay.textContent = 'Réinitialisation...';
202
+ try {
203
+ const response = await fetch('/reset_game', { method: 'POST' });
204
+ const data = await response.json();
205
+ updateBoard(data); // data contient fen et board_svg
206
+ lastAIMoveDisplay.textContent = "-";
207
+ // Réinitialiser l'état du jeu pour une nouvelle partie
208
+ moveInput.disabled = false;
209
+ moveForm.querySelector('button[type="submit"]').disabled = false;
210
+ outcomeDisplay.innerHTML = ''; // Effacer le message de fin de partie
211
+ // Mettre à jour l'affichage du mode et de la couleur
212
+ currentModeDisplay.textContent = data.game_mode ? data.game_mode.toUpperCase() : 'PVP';
213
+ if (data.game_mode === 'ai' && data.player_color) {
214
+ currentPlayerColorDisplay.textContent = data.player_color.charAt(0).toUpperCase() + data.player_color.slice(1);
215
+ playerColorInfoDisplay.classList.remove('hidden');
216
  } else {
217
+ playerColorInfoDisplay.classList.add('hidden');
218
  }
219
+ // Mettre à jour l'état du tour
220
+ updatePlayerTurnState();
221
+
222
+ } catch (error) {
223
+ console.error("Erreur lors de la réinitialisation:", error);
224
+ statusDisplay.textContent = "Erreur lors de la réinitialisation.";
225
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  });
227
+
228
+ async function setGameMode(mode, pColor = 'white') {
229
+ statusDisplay.textContent = `Changement de mode vers ${mode.toUpperCase()}...`;
230
+ lastAIMoveDisplay.textContent = "-";
231
+ try {
232
+ const response = await fetch('/set_mode', {
233
+ method: 'POST',
234
+ headers: { 'Content-Type': 'application/json' },
235
+ body: JSON.stringify({ game_mode: mode, player_color: pColor })
236
+ });
237
+ const data = await response.json();
238
  if (data.error) {
239
+ statusDisplay.textContent = `Erreur: ${data.error}`;
240
+ } else {
241
+ gameMode = data.game_mode;
242
+ playerColor = data.player_color;
243
+ updateBoard(data); // data contient fen, board_svg, etc.
244
+ currentModeDisplay.textContent = gameMode.toUpperCase();
245
+ if (gameMode === 'ai') {
246
+ currentPlayerColorDisplay.textContent = playerColor.charAt(0).toUpperCase() + playerColor.slice(1);
247
+ playerColorInfoDisplay.classList.remove('hidden');
248
+ } else {
249
+ playerColorInfoDisplay.classList.add('hidden');
250
+ }
251
+ statusDisplay.textContent = data.message;
252
+ if (data.initial_ai_move_uci) {
253
+ lastAIMoveDisplay.textContent = data.initial_ai_move_uci;
254
+ }
255
  }
256
+ } catch (error) {
257
+ console.error("Erreur de changement de mode:", error);
258
+ statusDisplay.textContent = "Erreur de changement de mode.";
259
+ }
260
+ }
261
+
262
+ document.getElementById('setPvP').addEventListener('click', () => setGameMode('pvp'));
263
+ document.getElementById('setPvAIWhite').addEventListener('click', () => setGameMode('ai', 'white'));
264
+ document.getElementById('setPvAIBlack').addEventListener('click', () => setGameMode('ai', 'black'));
265
+
266
+ // Initialiser l'état du tour au chargement de la page
267
+ updatePlayerTurnState();
268
+ // Afficher la couleur du joueur si en mode AI au chargement
269
+ if (gameMode === 'ai') {
270
+ currentPlayerColorDisplay.textContent = playerColor.charAt(0).toUpperCase() + playerColor.slice(1);
271
+ playerColorInfoDisplay.classList.remove('hidden');
272
+ }
273
+
274
  </script>
275
  </body>
276
  </html>