LMLK commited on
Commit
12998d4
·
verified ·
1 Parent(s): 45b600e

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +765 -19
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Neon Tic Tac Toe
3
- emoji:
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: neon-tic-tac-toe
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: purple
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,765 @@
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
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
9
+ <style>
10
+ :root {
11
+ --neon-blue: #00f2ff;
12
+ --neon-pink: #ff00ff;
13
+ --dark-bg: #0f0f1a;
14
+ --light-bg: #1a1a2e;
15
+ --text-light: #e6e6ff;
16
+ }
17
+
18
+ body {
19
+ font-family: 'Poppins', sans-serif;
20
+ background-color: var(--dark-bg);
21
+ color: var(--text-light);
22
+ min-height: 100vh;
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ justify-content: center;
27
+ overflow-x: hidden;
28
+ }
29
+
30
+ h1, h2, h3 {
31
+ font-family: 'Orbitron', sans-serif;
32
+ }
33
+
34
+ .neon-text-blue {
35
+ text-shadow: 0 0 5px var(--neon-blue), 0 0 10px var(--neon-blue);
36
+ color: var(--neon-blue);
37
+ }
38
+
39
+ .neon-text-pink {
40
+ text-shadow: 0 0 5px var(--neon-pink), 0 0 10px var(--neon-pink);
41
+ color: var(--neon-pink);
42
+ }
43
+
44
+ .neon-border-blue {
45
+ box-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-blue), inset 0 0 10px var(--neon-blue);
46
+ border: 1px solid var(--neon-blue);
47
+ }
48
+
49
+ .neon-border-pink {
50
+ box-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink), inset 0 0 10px var(--neon-pink);
51
+ border: 1px solid var(--neon-pink);
52
+ }
53
+
54
+ .cell {
55
+ width: 100px;
56
+ height: 100px;
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ font-size: 4rem;
61
+ cursor: pointer;
62
+ transition: all 0.3s ease;
63
+ position: relative;
64
+ overflow: hidden;
65
+ }
66
+
67
+ .cell:hover {
68
+ background-color: rgba(255, 255, 255, 0.05);
69
+ }
70
+
71
+ .cell.x::before, .cell.x::after {
72
+ content: '';
73
+ position: absolute;
74
+ width: 15px;
75
+ height: 80px;
76
+ background-color: var(--neon-blue);
77
+ transform: rotate(45deg);
78
+ }
79
+
80
+ .cell.x::after {
81
+ transform: rotate(-45deg);
82
+ }
83
+
84
+ .cell.o::before {
85
+ content: '';
86
+ position: absolute;
87
+ width: 60px;
88
+ height: 60px;
89
+ border-radius: 50%;
90
+ border: 15px solid var(--neon-pink);
91
+ }
92
+
93
+ .winning-cell {
94
+ animation: pulse 1s infinite alternate;
95
+ }
96
+
97
+ @keyframes pulse {
98
+ from {
99
+ transform: scale(1);
100
+ opacity: 1;
101
+ }
102
+ to {
103
+ transform: scale(1.1);
104
+ opacity: 0.8;
105
+ }
106
+ }
107
+
108
+ .board {
109
+ display: grid;
110
+ grid-template-columns: repeat(3, 1fr);
111
+ gap: 10px;
112
+ background-color: var(--light-bg);
113
+ padding: 20px;
114
+ border-radius: 10px;
115
+ position: relative;
116
+ }
117
+
118
+ .board::before {
119
+ content: '';
120
+ position: absolute;
121
+ top: 0;
122
+ left: 0;
123
+ right: 0;
124
+ bottom: 0;
125
+ background: linear-gradient(45deg, transparent 48%, var(--neon-blue) 49%, var(--neon-blue) 51%, transparent 52%),
126
+ linear-gradient(-45deg, transparent 48%, var(--neon-blue) 49%, var(--neon-blue) 51%, transparent 52%);
127
+ background-size: 10px 10px;
128
+ opacity: 0.05;
129
+ pointer-events: none;
130
+ }
131
+
132
+ .btn {
133
+ transition: all 0.3s ease;
134
+ font-family: 'Orbitron', sans-serif;
135
+ letter-spacing: 1px;
136
+ }
137
+
138
+ .btn:hover {
139
+ transform: translateY(-2px);
140
+ }
141
+
142
+ .btn-blue {
143
+ background-color: var(--neon-blue);
144
+ color: var(--dark-bg);
145
+ }
146
+
147
+ .btn-blue:hover {
148
+ box-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-blue);
149
+ }
150
+
151
+ .btn-pink {
152
+ background-color: var(--neon-pink);
153
+ color: var(--dark-bg);
154
+ }
155
+
156
+ .btn-pink:hover {
157
+ box-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink);
158
+ }
159
+
160
+ .modal {
161
+ display: none;
162
+ position: fixed;
163
+ top: 0;
164
+ left: 0;
165
+ width: 100%;
166
+ height: 100%;
167
+ background-color: rgba(0, 0, 0, 0.8);
168
+ z-index: 100;
169
+ align-items: center;
170
+ justify-content: center;
171
+ animation: fadeIn 0.3s ease;
172
+ }
173
+
174
+ @keyframes fadeIn {
175
+ from { opacity: 0; }
176
+ to { opacity: 1; }
177
+ }
178
+
179
+ .modal-content {
180
+ background-color: var(--light-bg);
181
+ padding: 2rem;
182
+ border-radius: 10px;
183
+ max-width: 500px;
184
+ width: 90%;
185
+ text-align: center;
186
+ position: relative;
187
+ animation: slideDown 0.3s ease;
188
+ }
189
+
190
+ @keyframes slideDown {
191
+ from { transform: translateY(-50px); opacity: 0; }
192
+ to { transform: translateY(0); opacity: 1; }
193
+ }
194
+
195
+ .close-modal {
196
+ position: absolute;
197
+ top: 10px;
198
+ right: 10px;
199
+ cursor: pointer;
200
+ font-size: 1.5rem;
201
+ }
202
+
203
+ .radio-tile-group {
204
+ display: flex;
205
+ flex-wrap: wrap;
206
+ justify-content: center;
207
+ gap: 1rem;
208
+ margin: 1rem 0;
209
+ }
210
+
211
+ .radio-tile {
212
+ display: flex;
213
+ flex-direction: column;
214
+ align-items: center;
215
+ justify-content: center;
216
+ padding: 1rem;
217
+ border-radius: 8px;
218
+ background-color: rgba(255, 255, 255, 0.05);
219
+ cursor: pointer;
220
+ transition: all 0.3s ease;
221
+ min-width: 100px;
222
+ }
223
+
224
+ .radio-tile:hover {
225
+ background-color: rgba(255, 255, 255, 0.1);
226
+ }
227
+
228
+ .radio-tile.selected {
229
+ background-color: var(--neon-blue);
230
+ color: var(--dark-bg);
231
+ }
232
+
233
+ .radio-tile.selected-pink {
234
+ background-color: var(--neon-pink);
235
+ color: var(--dark-bg);
236
+ }
237
+
238
+ input[type="radio"] {
239
+ display: none;
240
+ }
241
+
242
+ @media (max-width: 768px) {
243
+ .cell {
244
+ width: 80px;
245
+ height: 80px;
246
+ font-size: 3rem;
247
+ }
248
+
249
+ .cell.x::before, .cell.x::after {
250
+ height: 60px;
251
+ }
252
+
253
+ .cell.o::before {
254
+ width: 50px;
255
+ height: 50px;
256
+ border-width: 10px;
257
+ }
258
+ }
259
+ </style>
260
+ </head>
261
+ <body>
262
+ <div class="container mx-auto px-4 py-8 flex flex-col items-center">
263
+ <h1 class="text-4xl md:text-5xl font-bold mb-2 neon-text-blue">NEON</h1>
264
+ <h1 class="text-4xl md:text-5xl font-bold mb-8 neon-text-pink">TIC TAC TOE</h1>
265
+
266
+ <div class="flex flex-col md:flex-row gap-8 items-center justify-center w-full">
267
+ <!-- Game Controls -->
268
+ <div class="w-full md:w-1/3 max-w-md bg-gray-900 bg-opacity-50 rounded-xl p-6">
269
+ <h2 class="text-2xl font-bold mb-4 text-center">Game Settings</h2>
270
+
271
+ <div class="mb-6">
272
+ <h3 class="text-lg font-semibold mb-2">Game Mode</h3>
273
+ <div class="radio-tile-group">
274
+ <label class="radio-tile" id="pvp-label">
275
+ <input type="radio" name="gameMode" value="pvp" checked>
276
+ <span class="font-medium">Player vs Player</span>
277
+ </label>
278
+ <label class="radio-tile" id="pvc-label">
279
+ <input type="radio" name="gameMode" value="pvc">
280
+ <span class="font-medium">Player vs AI</span>
281
+ </label>
282
+ </div>
283
+ </div>
284
+
285
+ <div class="mb-6" id="ai-settings">
286
+ <h3 class="text-lg font-semibold mb-2">AI Difficulty</h3>
287
+ <div class="radio-tile-group">
288
+ <label class="radio-tile" id="easy-label">
289
+ <input type="radio" name="aiDifficulty" value="easy" checked>
290
+ <span class="font-medium">Easy</span>
291
+ </label>
292
+ <label class="radio-tile" id="medium-label">
293
+ <input type="radio" name="aiDifficulty" value="medium">
294
+ <span class="font-medium">Medium</span>
295
+ </label>
296
+ <label class="radio-tile" id="hard-label">
297
+ <input type="radio" name="aiDifficulty" value="hard">
298
+ <span class="font-medium">Hard</span>
299
+ </label>
300
+ </div>
301
+ </div>
302
+
303
+ <div class="mb-6" id="player-symbol">
304
+ <h3 class="text-lg font-semibold mb-2">Your Symbol</h3>
305
+ <div class="radio-tile-group">
306
+ <label class="radio-tile selected" id="x-label">
307
+ <input type="radio" name="playerSymbol" value="x" checked>
308
+ <span class="font-medium">X</span>
309
+ </label>
310
+ <label class="radio-tile" id="o-label">
311
+ <input type="radio" name="playerSymbol" value="o">
312
+ <span class="font-medium">O</span>
313
+ </label>
314
+ </div>
315
+ </div>
316
+
317
+ <div class="flex justify-center gap-4">
318
+ <button id="new-game-btn" class="btn btn-blue px-6 py-2 rounded-lg font-bold">New Game</button>
319
+ <button id="reset-score-btn" class="btn btn-pink px-6 py-2 rounded-lg font-bold">Reset Score</button>
320
+ </div>
321
+ </div>
322
+
323
+ <!-- Game Board -->
324
+ <div class="w-full md:w-2/3 flex flex-col items-center">
325
+ <div class="flex justify-between w-full max-w-sm mb-4">
326
+ <div id="player-x-score" class="text-center px-4 py-2 rounded-lg neon-border-blue">
327
+ <div class="text-sm">Player X</div>
328
+ <div class="text-2xl font-bold">0</div>
329
+ </div>
330
+ <div id="player-o-score" class="text-center px-4 py-2 rounded-lg neon-border-pink">
331
+ <div class="text-sm">Player O</div>
332
+ <div class="text-2xl font-bold">0</div>
333
+ </div>
334
+ </div>
335
+
336
+ <div class="board mb-6">
337
+ <div class="cell" data-index="0"></div>
338
+ <div class="cell" data-index="1"></div>
339
+ <div class="cell" data-index="2"></div>
340
+ <div class="cell" data-index="3"></div>
341
+ <div class="cell" data-index="4"></div>
342
+ <div class="cell" data-index="5"></div>
343
+ <div class="cell" data-index="6"></div>
344
+ <div class="cell" data-index="7"></div>
345
+ <div class="cell" data-index="8"></div>
346
+ </div>
347
+
348
+ <div id="game-status" class="text-xl font-bold mb-4 neon-text-blue">Player X's Turn</div>
349
+ </div>
350
+ </div>
351
+ </div>
352
+
353
+ <!-- Winner Modal -->
354
+ <div id="winner-modal" class="modal">
355
+ <div class="modal-content">
356
+ <span class="close-modal">&times;</span>
357
+ <h2 id="winner-text" class="text-3xl font-bold mb-4"></h2>
358
+ <p id="winner-subtext" class="mb-6"></p>
359
+ <button id="play-again-btn" class="btn btn-blue px-6 py-2 rounded-lg font-bold">Play Again</button>
360
+ </div>
361
+ </div>
362
+
363
+ <script>
364
+ document.addEventListener('DOMContentLoaded', () => {
365
+ // Game state
366
+ let board = ['', '', '', '', '', '', '', '', ''];
367
+ let currentPlayer = 'x';
368
+ let gameActive = true;
369
+ let scores = { x: 0, o: 0 };
370
+ let gameMode = 'pvp';
371
+ let aiDifficulty = 'easy';
372
+ let playerSymbol = 'x';
373
+
374
+ // DOM elements
375
+ const cells = document.querySelectorAll('.cell');
376
+ const gameStatus = document.getElementById('game-status');
377
+ const playerXScore = document.querySelector('#player-x-score div:last-child');
378
+ const playerOScore = document.querySelector('#player-o-score div:last-child');
379
+ const winnerModal = document.getElementById('winner-modal');
380
+ const winnerText = document.getElementById('winner-text');
381
+ const winnerSubtext = document.getElementById('winner-subtext');
382
+ const playAgainBtn = document.getElementById('play-again-btn');
383
+ const newGameBtn = document.getElementById('new-game-btn');
384
+ const resetScoreBtn = document.getElementById('reset-score-btn');
385
+ const closeModal = document.querySelector('.close-modal');
386
+ const aiSettings = document.getElementById('ai-settings');
387
+ const playerSymbolSection = document.getElementById('player-symbol');
388
+
389
+ // Radio button labels
390
+ const pvpLabel = document.getElementById('pvp-label');
391
+ const pvcLabel = document.getElementById('pvc-label');
392
+ const easyLabel = document.getElementById('easy-label');
393
+ const mediumLabel = document.getElementById('medium-label');
394
+ const hardLabel = document.getElementById('hard-label');
395
+ const xLabel = document.getElementById('x-label');
396
+ const oLabel = document.getElementById('o-label');
397
+
398
+ // Event listeners
399
+ cells.forEach(cell => cell.addEventListener('click', handleCellClick));
400
+ newGameBtn.addEventListener('click', startNewGame);
401
+ resetScoreBtn.addEventListener('click', resetScores);
402
+ playAgainBtn.addEventListener('click', startNewGame);
403
+ closeModal.addEventListener('click', () => winnerModal.style.display = 'none');
404
+
405
+ // Game mode radio buttons
406
+ document.querySelectorAll('input[name="gameMode"]').forEach(radio => {
407
+ radio.addEventListener('change', (e) => {
408
+ gameMode = e.target.value;
409
+ aiSettings.style.display = gameMode === 'pvc' ? 'block' : 'none';
410
+ playerSymbolSection.style.display = gameMode === 'pvc' ? 'block' : 'none';
411
+
412
+ // Update UI
413
+ if (gameMode === 'pvp') {
414
+ pvpLabel.classList.add('selected');
415
+ pvcLabel.classList.remove('selected');
416
+ } else {
417
+ pvpLabel.classList.remove('selected');
418
+ pvcLabel.classList.add('selected');
419
+ }
420
+
421
+ startNewGame();
422
+ });
423
+ });
424
+
425
+ // AI difficulty radio buttons
426
+ document.querySelectorAll('input[name="aiDifficulty"]').forEach(radio => {
427
+ radio.addEventListener('change', (e) => {
428
+ aiDifficulty = e.target.value;
429
+
430
+ // Update UI
431
+ easyLabel.classList.remove('selected');
432
+ mediumLabel.classList.remove('selected');
433
+ hardLabel.classList.remove('selected');
434
+
435
+ if (aiDifficulty === 'easy') {
436
+ easyLabel.classList.add('selected');
437
+ } else if (aiDifficulty === 'medium') {
438
+ mediumLabel.classList.add('selected');
439
+ } else {
440
+ hardLabel.classList.add('selected');
441
+ }
442
+ });
443
+ });
444
+
445
+ // Player symbol radio buttons
446
+ document.querySelectorAll('input[name="playerSymbol"]').forEach(radio => {
447
+ radio.addEventListener('change', (e) => {
448
+ playerSymbol = e.target.value;
449
+
450
+ // Update UI
451
+ xLabel.classList.remove('selected');
452
+ oLabel.classList.remove('selected');
453
+
454
+ if (playerSymbol === 'x') {
455
+ xLabel.classList.add('selected');
456
+ } else {
457
+ oLabel.classList.add('selected');
458
+ }
459
+
460
+ startNewGame();
461
+ });
462
+ });
463
+
464
+ // Initialize game
465
+ startNewGame();
466
+
467
+ function handleCellClick(e) {
468
+ const clickedCell = e.target;
469
+ const clickedCellIndex = parseInt(clickedCell.getAttribute('data-index'));
470
+
471
+ // If cell is already filled or game is not active, ignore click
472
+ if (board[clickedCellIndex] !== '' || !gameActive) return;
473
+
474
+ // If it's AI's turn in PVC mode, ignore click
475
+ if (gameMode === 'pvc' && currentPlayer !== playerSymbol) return;
476
+
477
+ // Update board and UI
478
+ board[clickedCellIndex] = currentPlayer;
479
+ updateCell(clickedCell, currentPlayer);
480
+
481
+ // Check for win or draw
482
+ const gameWon = checkWin();
483
+ const gameDraw = checkDraw();
484
+
485
+ if (gameWon) {
486
+ handleWin(gameWon);
487
+ return;
488
+ }
489
+
490
+ if (gameDraw) {
491
+ handleDraw();
492
+ return;
493
+ }
494
+
495
+ // Switch player
496
+ switchPlayer();
497
+
498
+ // If it's AI's turn in PVC mode, make AI move
499
+ if (gameMode === 'pvc' && currentPlayer !== playerSymbol && gameActive) {
500
+ setTimeout(makeAIMove, 500); // Small delay for better UX
501
+ }
502
+ }
503
+
504
+ function updateCell(cell, player) {
505
+ cell.classList.add(player);
506
+ }
507
+
508
+ function switchPlayer() {
509
+ currentPlayer = currentPlayer === 'x' ? 'o' : 'x';
510
+ updateGameStatus();
511
+ }
512
+
513
+ function updateGameStatus() {
514
+ if (gameMode === 'pvp') {
515
+ gameStatus.textContent = `Player ${currentPlayer.toUpperCase()}'s Turn`;
516
+ gameStatus.className = `text-xl font-bold mb-4 ${currentPlayer === 'x' ? 'neon-text-blue' : 'neon-text-pink'}`;
517
+ } else {
518
+ if (currentPlayer === playerSymbol) {
519
+ gameStatus.textContent = "Your Turn";
520
+ gameStatus.className = `text-xl font-bold mb-4 ${playerSymbol === 'x' ? 'neon-text-blue' : 'neon-text-pink'}`;
521
+ } else {
522
+ gameStatus.textContent = "AI's Turn";
523
+ gameStatus.className = "text-xl font-bold mb-4 text-gray-400";
524
+ }
525
+ }
526
+ }
527
+
528
+ function checkWin() {
529
+ // All possible winning combinations
530
+ const winPatterns = [
531
+ [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
532
+ [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
533
+ [0, 4, 8], [2, 4, 6] // diagonals
534
+ ];
535
+
536
+ for (let pattern of winPatterns) {
537
+ const [a, b, c] = pattern;
538
+
539
+ // Check if all cells in the pattern are filled by the same player
540
+ if (board[a] && board[a] === board[b] && board[a] === board[c]) {
541
+ return {
542
+ winner: board[a],
543
+ winningCells: pattern
544
+ };
545
+ }
546
+ }
547
+
548
+ return null;
549
+ }
550
+
551
+ function checkDraw() {
552
+ return !board.includes('') && !checkWin();
553
+ }
554
+
555
+ function handleWin(winInfo) {
556
+ gameActive = false;
557
+ scores[winInfo.winner]++;
558
+ updateScores();
559
+
560
+ // Highlight winning cells
561
+ winInfo.winningCells.forEach(index => {
562
+ cells[index].classList.add('winning-cell');
563
+ });
564
+
565
+ // Show winner modal
566
+ if (gameMode === 'pvp') {
567
+ winnerText.textContent = `Player ${winInfo.winner.toUpperCase()} Wins!`;
568
+ winnerText.className = `text-3xl font-bold mb-4 ${winInfo.winner === 'x' ? 'neon-text-blue' : 'neon-text-pink'}`;
569
+ winnerSubtext.textContent = `Player ${winInfo.winner.toUpperCase()} has won the game!`;
570
+ } else {
571
+ if (winInfo.winner === playerSymbol) {
572
+ winnerText.textContent = "You Win!";
573
+ winnerText.className = `text-3xl font-bold mb-4 ${playerSymbol === 'x' ? 'neon-text-blue' : 'neon-text-pink'}`;
574
+ winnerSubtext.textContent = "Congratulations! You defeated the AI.";
575
+ } else {
576
+ winnerText.textContent = "AI Wins!";
577
+ winnerText.className = "text-3xl font-bold mb-4 text-gray-400";
578
+ winnerSubtext.textContent = "The AI has won this round. Try again!";
579
+ }
580
+ }
581
+
582
+ winnerModal.style.display = 'flex';
583
+ }
584
+
585
+ function handleDraw() {
586
+ gameActive = false;
587
+
588
+ // Show draw modal
589
+ winnerText.textContent = "It's a Draw!";
590
+ winnerText.className = "text-3xl font-bold mb-4 text-gray-400";
591
+ winnerSubtext.textContent = "No one wins this time. Play again!";
592
+ winnerModal.style.display = 'flex';
593
+ }
594
+
595
+ function updateScores() {
596
+ playerXScore.textContent = scores.x;
597
+ playerOScore.textContent = scores.o;
598
+ }
599
+
600
+ function resetScores() {
601
+ scores = { x: 0, o: 0 };
602
+ updateScores();
603
+ startNewGame();
604
+ }
605
+
606
+ function startNewGame() {
607
+ // Reset board
608
+ board = ['', '', '', '', '', '', '', '', ''];
609
+ currentPlayer = 'x';
610
+ gameActive = true;
611
+
612
+ // Reset UI
613
+ cells.forEach(cell => {
614
+ cell.className = 'cell';
615
+ });
616
+
617
+ updateGameStatus();
618
+ winnerModal.style.display = 'none';
619
+
620
+ // If it's AI's turn in PVC mode and player is O, make AI move
621
+ if (gameMode === 'pvc' && playerSymbol === 'o') {
622
+ setTimeout(makeAIMove, 500); // Small delay for better UX
623
+ }
624
+ }
625
+
626
+ function makeAIMove() {
627
+ if (!gameActive) return;
628
+
629
+ let move;
630
+
631
+ switch (aiDifficulty) {
632
+ case 'easy':
633
+ move = getRandomMove();
634
+ break;
635
+ case 'medium':
636
+ move = getMediumAIMove();
637
+ break;
638
+ case 'hard':
639
+ move = getBestMove();
640
+ break;
641
+ default:
642
+ move = getRandomMove();
643
+ }
644
+
645
+ // Make the move
646
+ board[move] = currentPlayer;
647
+ updateCell(cells[move], currentPlayer);
648
+
649
+ // Check for win or draw
650
+ const gameWon = checkWin();
651
+ const gameDraw = checkDraw();
652
+
653
+ if (gameWon) {
654
+ handleWin(gameWon);
655
+ return;
656
+ }
657
+
658
+ if (gameDraw) {
659
+ handleDraw();
660
+ return;
661
+ }
662
+
663
+ // Switch player
664
+ switchPlayer();
665
+ }
666
+
667
+ function getRandomMove() {
668
+ // Get all available cells
669
+ const availableCells = board.map((cell, index) => cell === '' ? index : null).filter(val => val !== null);
670
+
671
+ // Return a random available cell
672
+ return availableCells[Math.floor(Math.random() * availableCells.length)];
673
+ }
674
+
675
+ function getMediumAIMove() {
676
+ // First, check if AI can win in the next move
677
+ for (let i = 0; i < board.length; i++) {
678
+ if (board[i] === '') {
679
+ board[i] = currentPlayer;
680
+ if (checkWin()) {
681
+ board[i] = ''; // Undo the move
682
+ return i;
683
+ }
684
+ board[i] = ''; // Undo the move
685
+ }
686
+ }
687
+
688
+ // Then, check if player can win in the next move and block them
689
+ const opponent = currentPlayer === 'x' ? 'o' : 'x';
690
+ for (let i = 0; i < board.length; i++) {
691
+ if (board[i] === '') {
692
+ board[i] = opponent;
693
+ if (checkWin()) {
694
+ board[i] = ''; // Undo the move
695
+ return i;
696
+ }
697
+ board[i] = ''; // Undo the move
698
+ }
699
+ }
700
+
701
+ // If neither, make a random move
702
+ return getRandomMove();
703
+ }
704
+
705
+ function getBestMove() {
706
+ // Minimax algorithm implementation
707
+ function minimax(board, depth, isMaximizing) {
708
+ const result = checkWin();
709
+
710
+ if (result) {
711
+ return result.winner === currentPlayer ? 10 - depth : depth - 10;
712
+ }
713
+
714
+ if (checkDraw()) {
715
+ return 0;
716
+ }
717
+
718
+ if (isMaximizing) {
719
+ let bestScore = -Infinity;
720
+ for (let i = 0; i < board.length; i++) {
721
+ if (board[i] === '') {
722
+ board[i] = currentPlayer;
723
+ const score = minimax(board, depth + 1, false);
724
+ board[i] = '';
725
+ bestScore = Math.max(score, bestScore);
726
+ }
727
+ }
728
+ return bestScore;
729
+ } else {
730
+ let bestScore = Infinity;
731
+ const opponent = currentPlayer === 'x' ? 'o' : 'x';
732
+ for (let i = 0; i < board.length; i++) {
733
+ if (board[i] === '') {
734
+ board[i] = opponent;
735
+ const score = minimax(board, depth + 1, true);
736
+ board[i] = '';
737
+ bestScore = Math.min(score, bestScore);
738
+ }
739
+ }
740
+ return bestScore;
741
+ }
742
+ }
743
+
744
+ let bestScore = -Infinity;
745
+ let bestMove;
746
+
747
+ for (let i = 0; i < board.length; i++) {
748
+ if (board[i] === '') {
749
+ board[i] = currentPlayer;
750
+ const score = minimax(board, 0, false);
751
+ board[i] = '';
752
+
753
+ if (score > bestScore) {
754
+ bestScore = score;
755
+ bestMove = i;
756
+ }
757
+ }
758
+ }
759
+
760
+ return bestMove;
761
+ }
762
+ });
763
+ </script>
764
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=LMLK/neon-tic-tac-toe" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
765
+ </html>
prompts.txt ADDED
File without changes