jeevav62 commited on
Commit
721b5f8
·
verified ·
1 Parent(s): 8c62d5d

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +639 -19
index.html CHANGED
@@ -1,19 +1,639 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Neon Tic Tac Toe</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;500;700&display=swap" rel="stylesheet">
10
+
11
+ <style>
12
+ :root {
13
+ --bg-color: #121212;
14
+ --card-bg: #1e1e1e;
15
+ --text-color: #e0e0e0;
16
+ --accent-x: #00f2ff; /* Cyan */
17
+ --accent-o: #ff0055; /* Neon Red */
18
+ --accent-draw: #ffd700; /* Gold */
19
+ --grid-gap: 15px;
20
+ --cell-size: 100px;
21
+ }
22
+
23
+ * {
24
+ box-sizing: border-box;
25
+ margin: 0;
26
+ padding: 0;
27
+ }
28
+
29
+ body {
30
+ font-family: 'Outfit', sans-serif;
31
+ background-color: var(--bg-color);
32
+ color: var(--text-color);
33
+ display: flex;
34
+ flex-direction: column;
35
+ align-items: center;
36
+ justify-content: center;
37
+ min-height: 100vh;
38
+ overflow-x: hidden;
39
+ }
40
+
41
+ /* --- Header --- */
42
+ header {
43
+ position: absolute;
44
+ top: 20px;
45
+ text-align: center;
46
+ width: 100%;
47
+ }
48
+
49
+ h1 {
50
+ font-weight: 700;
51
+ letter-spacing: 2px;
52
+ text-transform: uppercase;
53
+ font-size: 2rem;
54
+ background: linear-gradient(45deg, var(--accent-x), var(--accent-o));
55
+ -webkit-background-clip: text;
56
+ -webkit-text-fill-color: transparent;
57
+ margin-bottom: 10px;
58
+ }
59
+
60
+ .anycoder-link {
61
+ font-size: 0.8rem;
62
+ color: #666;
63
+ text-decoration: none;
64
+ border-bottom: 1px solid transparent;
65
+ transition: 0.3s;
66
+ }
67
+
68
+ .anycoder-link:hover {
69
+ color: var(--accent-x);
70
+ border-bottom: 1px solid var(--accent-x);
71
+ }
72
+
73
+ /* --- Containers --- */
74
+ .container {
75
+ width: 100%;
76
+ max-width: 500px;
77
+ padding: 20px;
78
+ display: flex;
79
+ flex-direction: column;
80
+ align-items: center;
81
+ }
82
+
83
+ /* --- Setup Screen --- */
84
+ #setup-screen {
85
+ background: var(--card-bg);
86
+ padding: 40px;
87
+ border-radius: 20px;
88
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
89
+ text-align: center;
90
+ width: 100%;
91
+ animation: fadeIn 0.5s ease-out;
92
+ }
93
+
94
+ .input-group {
95
+ margin-bottom: 20px;
96
+ text-align: left;
97
+ }
98
+
99
+ label {
100
+ display: block;
101
+ font-size: 0.9rem;
102
+ margin-bottom: 8px;
103
+ color: #aaa;
104
+ }
105
+
106
+ input {
107
+ width: 100%;
108
+ padding: 12px 15px;
109
+ background: #2a2a2a;
110
+ border: 2px solid transparent;
111
+ border-radius: 8px;
112
+ color: white;
113
+ font-family: 'Outfit', sans-serif;
114
+ font-size: 1rem;
115
+ transition: 0.3s;
116
+ outline: none;
117
+ }
118
+
119
+ input:focus {
120
+ border-color: var(--accent-x);
121
+ }
122
+
123
+ .btn {
124
+ background: linear-gradient(90deg, var(--accent-x), #00c2ff);
125
+ color: #000;
126
+ border: none;
127
+ padding: 12px 30px;
128
+ font-size: 1rem;
129
+ font-weight: 700;
130
+ border-radius: 50px;
131
+ cursor: pointer;
132
+ transition: transform 0.2s, box-shadow 0.2s;
133
+ width: 100%;
134
+ margin-top: 10px;
135
+ text-transform: uppercase;
136
+ letter-spacing: 1px;
137
+ }
138
+
139
+ .btn:hover {
140
+ transform: translateY(-2px);
141
+ box-shadow: 0 5px 15px rgba(0, 242, 255, 0.4);
142
+ }
143
+
144
+ .btn-secondary {
145
+ background: transparent;
146
+ border: 1px solid #444;
147
+ color: #aaa;
148
+ margin-top: 10px;
149
+ }
150
+
151
+ .btn-secondary:hover {
152
+ background: #333;
153
+ color: white;
154
+ box-shadow: none;
155
+ }
156
+
157
+ /* --- Game Screen --- */
158
+ #game-screen {
159
+ display: none; /* Hidden by default */
160
+ width: 100%;
161
+ flex-direction: column;
162
+ align-items: center;
163
+ animation: slideUp 0.5s ease-out;
164
+ }
165
+
166
+ /* Scoreboard */
167
+ .scoreboard {
168
+ display: flex;
169
+ justify-content: space-between;
170
+ width: 100%;
171
+ margin-bottom: 30px;
172
+ background: var(--card-bg);
173
+ padding: 15px;
174
+ border-radius: 15px;
175
+ box-shadow: 0 4px 10px rgba(0,0,0,0.3);
176
+ }
177
+
178
+ .player-score {
179
+ text-align: center;
180
+ flex: 1;
181
+ }
182
+
183
+ .player-score h3 {
184
+ font-size: 0.9rem;
185
+ color: #888;
186
+ margin-bottom: 5px;
187
+ }
188
+
189
+ .score-num {
190
+ font-size: 1.5rem;
191
+ font-weight: 700;
192
+ }
193
+
194
+ .p-x .score-num { color: var(--accent-x); }
195
+ .p-o .score-num { color: var(--accent-o); }
196
+ .p-d .score-num { color: var(--accent-draw); }
197
+
198
+ .active-turn {
199
+ background: rgba(255,255,255,0.05);
200
+ border-radius: 10px;
201
+ }
202
+
203
+ .turn-indicator {
204
+ margin-bottom: 20px;
205
+ font-size: 1.2rem;
206
+ font-weight: 500;
207
+ }
208
+
209
+ .turn-text span {
210
+ font-weight: 700;
211
+ }
212
+
213
+ /* The Grid */
214
+ .board {
215
+ display: grid;
216
+ grid-template-columns: repeat(3, 1fr);
217
+ gap: var(--grid-gap);
218
+ margin-bottom: 30px;
219
+ }
220
+
221
+ .cell {
222
+ width: var(--cell-size);
223
+ height: var(--cell-size);
224
+ background: var(--card-bg);
225
+ border-radius: 15px;
226
+ display: flex;
227
+ align-items: center;
228
+ justify-content: center;
229
+ font-size: 3rem;
230
+ font-weight: 700;
231
+ cursor: pointer;
232
+ transition: all 0.2s ease;
233
+ box-shadow: 0 4px 6px rgba(0,0,0,0.2);
234
+ }
235
+
236
+ .cell:hover:not(.taken) {
237
+ background: #2a2a2a;
238
+ transform: scale(1.02);
239
+ }
240
+
241
+ .cell.x { color: var(--accent-x); text-shadow: 0 0 10px rgba(0, 242, 255, 0.5); }
242
+ .cell.o { color: var(--accent-o); text-shadow: 0 0 10px rgba(255, 0, 85, 0.5); }
243
+
244
+ /* Animations */
245
+ @keyframes pop {
246
+ 0% { transform: scale(0); }
247
+ 80% { transform: scale(1.1); }
248
+ 100% { transform: scale(1); }
249
+ }
250
+
251
+ .cell.animate {
252
+ animation: pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
253
+ }
254
+
255
+ @keyframes fadeIn {
256
+ from { opacity: 0; }
257
+ to { opacity: 1; }
258
+ }
259
+
260
+ @keyframes slideUp {
261
+ from { transform: translateY(50px); opacity: 0; }
262
+ to { transform: translateY(0); opacity: 1; }
263
+ }
264
+
265
+ /* Game Over Modal */
266
+ .modal {
267
+ position: fixed;
268
+ top: 0;
269
+ left: 0;
270
+ width: 100%;
271
+ height: 100%;
272
+ background: rgba(0,0,0,0.8);
273
+ display: flex;
274
+ justify-content: center;
275
+ align-items: center;
276
+ z-index: 100;
277
+ opacity: 0;
278
+ pointer-events: none;
279
+ transition: opacity 0.3s;
280
+ backdrop-filter: blur(5px);
281
+ }
282
+
283
+ .modal.show {
284
+ opacity: 1;
285
+ pointer-events: all;
286
+ }
287
+
288
+ .modal-content {
289
+ background: var(--card-bg);
290
+ padding: 40px;
291
+ border-radius: 20px;
292
+ text-align: center;
293
+ transform: scale(0.8);
294
+ transition: transform 0.3s;
295
+ border: 1px solid #333;
296
+ }
297
+
298
+ .modal.show .modal-content {
299
+ transform: scale(1);
300
+ }
301
+
302
+ .modal h2 {
303
+ font-size: 2rem;
304
+ margin-bottom: 10px;
305
+ }
306
+
307
+ .modal p {
308
+ margin-bottom: 30px;
309
+ color: #aaa;
310
+ }
311
+
312
+ /* Responsive adjustments */
313
+ @media (max-width: 400px) {
314
+ :root {
315
+ --cell-size: 80px;
316
+ --grid-gap: 10px;
317
+ }
318
+ }
319
+ </style>
320
+ </head>
321
+ <body>
322
+
323
+ <header>
324
+ <h1>Tic Tac Toe</h1>
325
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
326
+ </header>
327
+
328
+ <div class="container">
329
+ <!-- SETUP SCREEN -->
330
+ <div id="setup-screen">
331
+ <h2 style="margin-bottom: 25px;">Enter Players</h2>
332
+
333
+ <div class="input-group">
334
+ <label for="p1-name">Player X Name</label>
335
+ <input type="text" id="p1-name" placeholder="Player X" maxlength="12">
336
+ </div>
337
+
338
+ <div class="input-group">
339
+ <label for="p2-name">Player O Name</label>
340
+ <input type="text" id="p2-name" placeholder="Player O" maxlength="12">
341
+ </div>
342
+
343
+ <button class="btn" onclick="startGame()">Start Game</button>
344
+ <button class="btn btn-secondary" onclick="resetHistory()">Reset History</button>
345
+ </div>
346
+
347
+ <!-- GAME SCREEN -->
348
+ <div id="game-screen">
349
+ <!-- Scoreboard -->
350
+ <div class="scoreboard">
351
+ <div class="player-score p-x" id="score-x-container">
352
+ <h3 id="p1-display">Player X</h3>
353
+ <div class="score-num" id="score-wins-x">0</div>
354
+ <div style="font-size: 0.7rem; color: #666;">Wins</div>
355
+ </div>
356
+
357
+ <div class="player-score p-d">
358
+ <h3>DRAWS</h3>
359
+ <div class="score-num" id="score-draws">0</div>
360
+ </div>
361
+
362
+ <div class="player-score p-o" id="score-o-container">
363
+ <h3 id="p2-display">Player O</h3>
364
+ <div class="score-num" id="score-wins-o">0</div>
365
+ <div style="font-size: 0.7rem; color: #666;">Wins</div>
366
+ </div>
367
+ </div>
368
+
369
+ <div class="turn-indicator">
370
+ <div class="turn-text">Current Turn: <span id="current-turn-text" style="color: var(--accent-x)">Player X</span></div>
371
+ </div>
372
+
373
+ <div class="board" id="board">
374
+ <!-- Cells generated by JS -->
375
+ </div>
376
+
377
+ <button class="btn btn-secondary" style="width: auto; padding: 10px 20px;" onclick="quitGame()">Quit Game</button>
378
+ </div>
379
+ </div>
380
+
381
+ <!-- RESULT MODAL -->
382
+ <div id="result-modal" class="modal">
383
+ <div class="modal-content">
384
+ <h2 id="modal-title">Winner!</h2>
385
+ <p id="modal-message">Player X Wins!</p>
386
+ <button class="btn" onclick="nextRound()">Next Round</button>
387
+ <button class="btn btn-secondary" onclick="quitGame()">Main Menu</button>
388
+ </div>
389
+ </div>
390
+
391
+ <script>
392
+ // Game State
393
+ let currentPlayer = 'X';
394
+ let gameActive = false;
395
+ let gameState = ["", "", "", "", "", "", "", "", ""];
396
+ let player1Name = "Player X";
397
+ let player2Name = "Player O";
398
+
399
+ // Stats Storage
400
+ let stats = {
401
+ 'default_X': { wins: 0, losses: 0 },
402
+ 'default_O': { wins: 0, losses: 0 },
403
+ 'draws': 0
404
+ };
405
+
406
+ // DOM Elements
407
+ const setupScreen = document.getElementById('setup-screen');
408
+ const gameScreen = document.getElementById('game-screen');
409
+ const boardElement = document.getElementById('board');
410
+ const modal = document.getElementById('result-modal');
411
+
412
+ // Winning Combinations
413
+ const winningConditions = [
414
+ [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows
415
+ [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns
416
+ [0, 4, 8], [2, 4, 6] // Diagonals
417
+ ];
418
+
419
+ // Initialize
420
+ loadStats();
421
+ createBoard();
422
+
423
+ function createBoard() {
424
+ boardElement.innerHTML = "";
425
+ for (let i = 0; i < 9; i++) {
426
+ const cell = document.createElement('div');
427
+ cell.classList.add('cell');
428
+ cell.setAttribute('data-index', i);
429
+ cell.addEventListener('click', handleCellClick);
430
+ boardElement.appendChild(cell);
431
+ }
432
+ }
433
+
434
+ function startGame() {
435
+ const p1Input = document.getElementById('p1-name').value.trim();
436
+ const p2Input = document.getElementById('p2-name').value.trim();
437
+
438
+ player1Name = p1Input ? p1Input : "Player X";
439
+ player2Name = p2Input ? p2Input : "Player O";
440
+
441
+ // Save custom names to local storage keys for persistence
442
+ // Simplify keys for this demo: using fixed keys for X and O positions
443
+ // In a real app, you'd map IDs to names.
444
+ // Here we just reset the current session stats.
445
+
446
+ setupScreen.style.display = 'none';
447
+ gameScreen.style.display = 'flex';
448
+
449
+ updateScoreboardUI();
450
+ handlePlayerTurnChange();
451
+
452
+ gameActive = true;
453
+ currentPlayer = 'X';
454
+ }
455
+
456
+ function handleCellClick(clickedCellEvent) {
457
+ const clickedCell = clickedCellEvent.target;
458
+ const clickedCellIndex = parseInt(clickedCell.getAttribute('data-index'));
459
+
460
+ if (gameState[clickedCellIndex] !== "" || !gameActive) {
461
+ return;
462
+ }
463
+
464
+ handleCellPlayed(clickedCell, clickedCellIndex);
465
+ handleResultValidation();
466
+ }
467
+
468
+ function handleCellPlayed(clickedCell, clickedCellIndex) {
469
+ gameState[clickedCellIndex] = currentPlayer;
470
+ clickedCell.innerHTML = currentPlayer;
471
+ clickedCell.classList.add('taken');
472
+ clickedCell.classList.add(currentPlayer.toLowerCase());
473
+
474
+ // Add pop animation
475
+ clickedCell.classList.add('animate');
476
+ setTimeout(() => clickedCell.classList.remove('animate'), 300);
477
+ }
478
+
479
+ function handleResultValidation() {
480
+ let roundWon = false;
481
+ for (let i = 0; i <= 7; i++) {
482
+ const winCondition = winningConditions[i];
483
+ let a = gameState[winCondition[0]];
484
+ let b = gameState[winCondition[1]];
485
+ let c = gameState[winCondition[2]];
486
+
487
+ if (a === '' || b === '' || c === '') {
488
+ continue;
489
+ }
490
+ if (a === b && b === c) {
491
+ roundWon = true;
492
+ break;
493
+ }
494
+ }
495
+
496
+ if (roundWon) {
497
+ endGame(false); // false means not a draw
498
+ return;
499
+ }
500
+
501
+ let roundDraw = !gameState.includes("");
502
+ if (roundDraw) {
503
+ endGame(true); // true means draw
504
+ return;
505
+ }
506
+
507
+ handlePlayerTurnChange();
508
+ }
509
+
510
+ function handlePlayerTurnChange() {
511
+ currentPlayer = currentPlayer === "X" ? "O" : "X";
512
+ const turnText = document.getElementById('current-turn-text');
513
+ turnText.innerText = currentPlayer === 'X' ? player1Name : player2Name;
514
+ turnText.style.color = currentPlayer === 'X' ? 'var(--accent-x)' : 'var(--accent-o)';
515
+
516
+ // Highlight active player in scoreboard
517
+ if(currentPlayer === 'X') {
518
+ document.getElementById('score-x-container').classList.add('active-turn');
519
+ document.getElementById('score-o-container').classList.remove('active-turn');
520
+ } else {
521
+ document.getElementById('score-x-container').classList.remove('active-turn');
522
+ document.getElementById('score-o-container').classList.add('active-turn');
523
+ }
524
+ }
525
+
526
+ function endGame(isDraw) {
527
+ gameActive = false;
528
+ const modalTitle = document.getElementById('modal-title');
529
+ const modalMsg = document.getElementById('modal-message');
530
+
531
+ // Update Stats Logic
532
+ if (isDraw) {
533
+ stats['draws']++;
534
+ modalTitle.innerText = "Draw!";
535
+ modalTitle.style.color = "var(--accent-draw)";
536
+ modalMsg.innerText = `It's a tie between ${player1Name} and ${player2Name}`;
537
+ } else {
538
+ if (currentPlayer === 'X') {
539
+ stats['p1_wins'] = (stats['p1_wins'] || 0) + 1;
540
+ // p1 losses implies p2 wins
541
+ stats['p2_losses'] = (stats['p2_losses'] || 0) + 1;
542
+ } else {
543
+ stats['p2_wins'] = (stats['p2_wins'] || 0) + 1;
544
+ stats['p1_losses'] = (stats['p1_losses'] || 0) + 1;
545
+ }
546
+
547
+ const winnerName = currentPlayer === 'X' ? player1Name : player2Name;
548
+ modalTitle.innerText = "Winner!";
549
+ modalTitle.style.color = currentPlayer === 'X' ? "var(--accent-x)" : "var(--accent-o)";
550
+ modalMsg.innerText = `${winnerName} takes the round!`;
551
+ }
552
+
553
+ saveStats();
554
+ updateScoreboardUI();
555
+
556
+ // Show Modal
557
+ setTimeout(() => {
558
+ modal.classList.add('show');
559
+ }, 500);
560
+ }
561
+
562
+ function nextRound() {
563
+ modal.classList.remove('show');
564
+ gameState = ["", "", "", "", "", "", "", "", ""];
565
+ gameActive = true;
566
+ currentPlayer = 'X';
567
+
568
+ // Reset board UI
569
+ document.querySelectorAll('.cell').forEach(cell => {
570
+ cell.innerHTML = "";
571
+ cell.classList.remove('x', 'o', 'taken');
572
+ });
573
+
574
+ handlePlayerTurnChange();
575
+ }
576
+
577
+ function quitGame() {
578
+ modal.classList.remove('show');
579
+ gameScreen.style.display = 'none';
580
+ setupScreen.style.display = 'block';
581
+
582
+ // Reset Board
583
+ gameState = ["", "", "", "", "", "", "", "", ""];
584
+ document.querySelectorAll('.cell').forEach(cell => {
585
+ cell.innerHTML = "";
586
+ cell.classList.remove('x', 'o', 'taken');
587
+ });
588
+ }
589
+
590
+ // --- Stats Management ---
591
+
592
+ function updateScoreboardUI() {
593
+ // Update Names
594
+ document.getElementById('p1-display').innerText = player1Name;
595
+ document.getElementById('p2-display').innerText = player2Name;
596
+
597
+ // Update Counts
598
+ // We are tracking wins generally in this session based on who was X or O
599
+ // For a persistent history across name changes, we usually use IDs,
600
+ // but here we just show "X Wins" and "O Wins" based on the current session logic
601
+ // or if we want history to persist by name, we need to store an object.
602
+
603
+ // Let's implement session specific tracking
604
+ let xWins = stats[`x_session_${player1Name}`] || 0;
605
+ let oWins = stats[`o_session_${player2Name}`] || 0;
606
+
607
+ // Actually, let's just use the global counters for simplicity in this single file:
608
+ // Wins for whoever played X in this specific setup
609
+ document.getElementById('score-wins-x').innerText = stats['p1_wins'] || 0;
610
+ document.getElementById('score-wins-o').innerText = stats['p2_wins'] || 0;
611
+ document.getElementById('score-draws').innerText = stats['draws'] || 0;
612
+ }
613
+
614
+ function saveStats() {
615
+ localStorage.setItem('ttt_stats', JSON.stringify(stats));
616
+ }
617
+
618
+ function loadStats() {
619
+ const saved = localStorage.getItem('ttt_stats');
620
+ if (saved) {
621
+ stats = JSON.parse(saved);
622
+ }
623
+ }
624
+
625
+ function resetHistory() {
626
+ if(confirm("Are you sure you want to clear all game history?")) {
627
+ stats = {
628
+ 'p1_wins': 0, 'p1_losses': 0,
629
+ 'p2_wins': 0, 'p2_losses': 0,
630
+ 'draws': 0
631
+ };
632
+ saveStats();
633
+ alert("History reset!");
634
+ }
635
+ }
636
+
637
+ </script>
638
+ </body>
639
+ </html>