api-ix commited on
Commit
314b4a8
·
verified ·
1 Parent(s): c94943b

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +38 -71
index.html CHANGED
@@ -12,7 +12,7 @@
12
  --bg-color: #212121;
13
  --text-color: #e0e0e0;
14
  --accent-color: #4caf50;
15
- --danger-color: #f44336;
16
  }
17
 
18
  body {
@@ -26,7 +26,7 @@
26
  padding: 20px;
27
  }
28
 
29
- h1 { margin-bottom: 10px; }
30
 
31
  .container {
32
  display: flex;
@@ -37,14 +37,19 @@
37
  width: 100%;
38
  }
39
 
 
40
  #board {
41
- width: 400px;
 
 
 
 
42
  }
43
 
44
  .panel {
45
  flex: 1;
46
  min-width: 300px;
47
- background: #333;
48
  padding: 20px;
49
  border-radius: 8px;
50
  display: flex;
@@ -61,17 +66,9 @@
61
 
62
  .stats-label { font-size: 0.85em; color: #aaa; display: block; margin-bottom: 5px; }
63
  .stats-value { font-size: 1.1em; font-weight: bold; }
 
64
 
65
- #best-line {
66
- font-family: monospace;
67
- color: #81c784;
68
- }
69
-
70
- .controls {
71
- display: flex;
72
- gap: 10px;
73
- margin-top: auto;
74
- }
75
 
76
  button {
77
  padding: 10px 20px;
@@ -79,14 +76,11 @@
79
  border-radius: 4px;
80
  cursor: pointer;
81
  font-weight: bold;
82
- transition: opacity 0.2s;
 
83
  }
84
-
85
  button:hover { opacity: 0.9; }
86
-
87
- #analyzeBtn { background-color: var(--accent-color); color: white; }
88
- #resetBtn { background-color: #555; color: white; }
89
- #flipBtn { background-color: #555; color: white; }
90
 
91
  .status-indicator {
92
  display: inline-block;
@@ -98,7 +92,6 @@
98
  }
99
  .status-indicator.ready { background-color: var(--accent-color); }
100
  .status-indicator.thinking { background-color: #ffeb3b; animation: pulse 1s infinite; }
101
-
102
  @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } }
103
  </style>
104
  </head>
@@ -121,7 +114,7 @@
121
  </div>
122
 
123
  <div class="stats-box">
124
- <span class="stats-label">Best Route (Best Move & Continuation)</span>
125
  <span class="stats-value" id="best-line">WAITING FOR MOVE...</span>
126
  </div>
127
 
@@ -131,12 +124,9 @@
131
  </div>
132
 
133
  <div class="controls">
134
- <button id="resetBtn">Reset Board</button>
135
  <button id="flipBtn">Flip Board</button>
136
  </div>
137
- <p style="font-size: 0.8em; color: #777; margin-top: 10px;">
138
- Drag pieces to play. The engine analyzes automatically.
139
- </p>
140
  </div>
141
  </div>
142
 
@@ -151,50 +141,49 @@
151
  let board = null;
152
  let game = new Chess();
153
  let engine = null;
154
- let evaluation = 0;
155
 
156
- // --- UI ELEMENTS ---
157
  const $status = $('#gameStatus');
158
- const $fen = $('#fen');
159
  const $evaluation = $('#evaluation');
160
  const $bestLine = $('#best-line');
161
  const $engineStatus = $('#engineStatus');
162
  const $engineText = $('#engineText');
163
 
164
- // --- INITIALIZATION ---
165
  function initGame() {
166
- // Initialize Board
167
  const config = {
168
  draggable: true,
169
  position: 'start',
170
  onDragStart: onDragStart,
171
  onDrop: onDrop,
172
- onSnapEnd: onSnapEnd
 
173
  };
 
 
174
  board = Chessboard('board', config);
175
 
176
- // Initialize Engine
177
  initStockfish();
178
-
179
  updateStatus();
 
 
 
180
  }
181
 
182
- // --- STOCKFISH ENGINE LOGIC ---
183
  function initStockfish() {
184
- // Note: Web Workers require the file to be served, not local file://
185
  try {
186
  engine = new Worker(STOCKFISH_PATH);
187
 
188
  engine.onmessage = function(event) {
189
  const line = event.data;
190
 
191
- // Allow the engine to start
192
  if (line === 'uciok') {
193
  $engineStatus.addClass('ready');
194
  $engineText.text('Engine Ready');
195
  }
196
 
197
- // Parse Analysis info (Depth, Score, PV)
198
  if (line.startsWith('info') && line.includes('score cp')) {
199
  const matchScore = line.match(/score cp (-?\d+)/);
200
  const matchMate = line.match(/score mate (-?\d+)/);
@@ -204,9 +193,7 @@
204
  $evaluation.text(`Mate in ${Math.abs(matchMate[1])}`);
205
  $evaluation.css('color', '#f44336');
206
  } else if (matchScore) {
207
- // Centipawns to standard pawn value
208
  const score = parseInt(matchScore[1]) / 100;
209
- // If black to move, negate score for absolute evaluation
210
  const finalScore = game.turn() === 'b' ? -score : score;
211
  $evaluation.text(finalScore > 0 ? `+${finalScore}` : finalScore);
212
  $evaluation.css('color', finalScore >= 0 ? '#4caf50' : '#f44336');
@@ -220,34 +207,23 @@
220
 
221
  engine.postMessage('uci');
222
  engine.postMessage('isready');
223
-
224
  } catch (e) {
225
- console.error("Stockfish failed to load. Are you running on a local server?");
226
  $engineText.text('Engine Error (CORS)');
 
227
  }
228
  }
229
 
230
  function analyzePosition() {
231
  if (!engine) return;
232
-
233
  $engineStatus.removeClass('ready').addClass('thinking');
234
  $engineText.text('Calculating...');
235
-
236
- // Get current FEN
237
- const fen = game.fen();
238
-
239
- // Send to Stockfish
240
- engine.postMessage(`position fen ${fen}`);
241
- // Search to depth 15 (good balance of speed/strength for web)
242
  engine.postMessage('go depth 15');
243
  }
244
 
245
- // --- CHESS LOGIC (Chess.js) ---
246
- function onDragStart(source, piece, position, orientation) {
247
- // Do not pick up pieces if the game is over
248
  if (game.game_over()) return false;
249
-
250
- // Only pick up pieces for the side to move
251
  if ((game.turn() === 'w' && piece.search(/^b/) !== -1) ||
252
  (game.turn() === 'b' && piece.search(/^w/) !== -1)) {
253
  return false;
@@ -255,18 +231,16 @@
255
  }
256
 
257
  function onDrop(source, target) {
258
- // see if the move is legal
259
  const move = game.move({
260
  from: source,
261
  to: target,
262
- promotion: 'q' // NOTE: always promote to a queen for simplicity
263
  });
264
 
265
- // illegal move
266
  if (move === null) return 'snapback';
267
 
268
  updateStatus();
269
- analyzePosition(); // Trigger analysis after move
270
  }
271
 
272
  function onSnapEnd() {
@@ -275,26 +249,20 @@
275
 
276
  function updateStatus() {
277
  let status = '';
278
- let moveColor = 'White';
279
- if (game.turn() === 'b') {
280
- moveColor = 'Black';
281
- }
282
 
283
  if (game.in_checkmate()) {
284
- status = 'Game over, ' + moveColor + ' is in checkmate.';
285
  } else if (game.in_draw()) {
286
  status = 'Game over, drawn position';
287
  } else {
288
- status = moveColor + ' to move';
289
- if (game.in_check()) {
290
- status += ', ' + moveColor + ' is in check';
291
- }
292
  }
293
 
294
  $status.text(status);
295
  }
296
 
297
- // --- BUTTONS ---
298
  $('#resetBtn').on('click', function() {
299
  game.reset();
300
  board.start();
@@ -305,9 +273,8 @@
305
 
306
  $('#flipBtn').on('click', board.flip);
307
 
308
- // Start everything
309
  $(document).ready(initGame);
310
-
311
  </script>
312
  </body>
313
  </html>
 
12
  --bg-color: #212121;
13
  --text-color: #e0e0e0;
14
  --accent-color: #4caf50;
15
+ --panel-bg: #333;
16
  }
17
 
18
  body {
 
26
  padding: 20px;
27
  }
28
 
29
+ h1 { margin-bottom: 20px; }
30
 
31
  .container {
32
  display: flex;
 
37
  width: 100%;
38
  }
39
 
40
+ /* FORCE BOARD SIZE */
41
  #board {
42
+ width: 100%;
43
+ max-width: 400px;
44
+ margin: 0 auto;
45
+ /* Fallback border to see the box if JS fails */
46
+ border: 2px solid #555;
47
  }
48
 
49
  .panel {
50
  flex: 1;
51
  min-width: 300px;
52
+ background: var(--panel-bg);
53
  padding: 20px;
54
  border-radius: 8px;
55
  display: flex;
 
66
 
67
  .stats-label { font-size: 0.85em; color: #aaa; display: block; margin-bottom: 5px; }
68
  .stats-value { font-size: 1.1em; font-weight: bold; }
69
+ #best-line { font-family: monospace; color: #81c784; word-break: break-all; }
70
 
71
+ .controls { display: flex; gap: 10px; margin-top: auto; }
 
 
 
 
 
 
 
 
 
72
 
73
  button {
74
  padding: 10px 20px;
 
76
  border-radius: 4px;
77
  cursor: pointer;
78
  font-weight: bold;
79
+ color: white;
80
+ background-color: #555;
81
  }
 
82
  button:hover { opacity: 0.9; }
83
+ #flipBtn { background-color: var(--accent-color); }
 
 
 
84
 
85
  .status-indicator {
86
  display: inline-block;
 
92
  }
93
  .status-indicator.ready { background-color: var(--accent-color); }
94
  .status-indicator.thinking { background-color: #ffeb3b; animation: pulse 1s infinite; }
 
95
  @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } }
96
  </style>
97
  </head>
 
114
  </div>
115
 
116
  <div class="stats-box">
117
+ <span class="stats-label">Best Move Sequence</span>
118
  <span class="stats-value" id="best-line">WAITING FOR MOVE...</span>
119
  </div>
120
 
 
124
  </div>
125
 
126
  <div class="controls">
127
+ <button id="resetBtn">Reset</button>
128
  <button id="flipBtn">Flip Board</button>
129
  </div>
 
 
 
130
  </div>
131
  </div>
132
 
 
141
  let board = null;
142
  let game = new Chess();
143
  let engine = null;
 
144
 
145
+ // UI Selectors
146
  const $status = $('#gameStatus');
 
147
  const $evaluation = $('#evaluation');
148
  const $bestLine = $('#best-line');
149
  const $engineStatus = $('#engineStatus');
150
  const $engineText = $('#engineText');
151
 
 
152
  function initGame() {
153
+ // --- FIX IS HERE: pieceTheme points to online images ---
154
  const config = {
155
  draggable: true,
156
  position: 'start',
157
  onDragStart: onDragStart,
158
  onDrop: onDrop,
159
+ onSnapEnd: onSnapEnd,
160
+ pieceTheme: 'https://chessboardjs.com/img/chesspieces/wikipedia/{piece}.png'
161
  };
162
+
163
+ // Create board
164
  board = Chessboard('board', config);
165
 
166
+ // Start Engine
167
  initStockfish();
 
168
  updateStatus();
169
+
170
+ // Handle window resize for responsiveness
171
+ $(window).resize(board.resize);
172
  }
173
 
174
+ // --- ENGINE LOGIC ---
175
  function initStockfish() {
 
176
  try {
177
  engine = new Worker(STOCKFISH_PATH);
178
 
179
  engine.onmessage = function(event) {
180
  const line = event.data;
181
 
 
182
  if (line === 'uciok') {
183
  $engineStatus.addClass('ready');
184
  $engineText.text('Engine Ready');
185
  }
186
 
 
187
  if (line.startsWith('info') && line.includes('score cp')) {
188
  const matchScore = line.match(/score cp (-?\d+)/);
189
  const matchMate = line.match(/score mate (-?\d+)/);
 
193
  $evaluation.text(`Mate in ${Math.abs(matchMate[1])}`);
194
  $evaluation.css('color', '#f44336');
195
  } else if (matchScore) {
 
196
  const score = parseInt(matchScore[1]) / 100;
 
197
  const finalScore = game.turn() === 'b' ? -score : score;
198
  $evaluation.text(finalScore > 0 ? `+${finalScore}` : finalScore);
199
  $evaluation.css('color', finalScore >= 0 ? '#4caf50' : '#f44336');
 
207
 
208
  engine.postMessage('uci');
209
  engine.postMessage('isready');
 
210
  } catch (e) {
 
211
  $engineText.text('Engine Error (CORS)');
212
+ console.error(e);
213
  }
214
  }
215
 
216
  function analyzePosition() {
217
  if (!engine) return;
 
218
  $engineStatus.removeClass('ready').addClass('thinking');
219
  $engineText.text('Calculating...');
220
+ engine.postMessage(`position fen ${game.fen()}`);
 
 
 
 
 
 
221
  engine.postMessage('go depth 15');
222
  }
223
 
224
+ // --- GAME LOGIC ---
225
+ function onDragStart(source, piece) {
 
226
  if (game.game_over()) return false;
 
 
227
  if ((game.turn() === 'w' && piece.search(/^b/) !== -1) ||
228
  (game.turn() === 'b' && piece.search(/^w/) !== -1)) {
229
  return false;
 
231
  }
232
 
233
  function onDrop(source, target) {
 
234
  const move = game.move({
235
  from: source,
236
  to: target,
237
+ promotion: 'q'
238
  });
239
 
 
240
  if (move === null) return 'snapback';
241
 
242
  updateStatus();
243
+ analyzePosition();
244
  }
245
 
246
  function onSnapEnd() {
 
249
 
250
  function updateStatus() {
251
  let status = '';
252
+ let moveColor = game.turn() === 'b' ? 'Black' : 'White';
 
 
 
253
 
254
  if (game.in_checkmate()) {
255
+ status = `Game over, ${moveColor} is in checkmate.`;
256
  } else if (game.in_draw()) {
257
  status = 'Game over, drawn position';
258
  } else {
259
+ status = `${moveColor} to move`;
260
+ if (game.in_check()) status += `, ${moveColor} is in check`;
 
 
261
  }
262
 
263
  $status.text(status);
264
  }
265
 
 
266
  $('#resetBtn').on('click', function() {
267
  game.reset();
268
  board.start();
 
273
 
274
  $('#flipBtn').on('click', board.flip);
275
 
276
+ // Start
277
  $(document).ready(initGame);
 
278
  </script>
279
  </body>
280
  </html>