fmlemos commited on
Commit
a2c86b9
·
verified ·
1 Parent(s): 3a76116

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +508 -19
index.html CHANGED
@@ -1,19 +1,508 @@
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>Cyber Neon Tic Tac Toe</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
9
+ <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
11
+
12
+ :root {
13
+ --neon-pink: #ff2a6d;
14
+ --neon-blue: #05d9e8;
15
+ --neon-purple: #d300c5;
16
+ --neon-green: #00ff9d;
17
+ --dark-bg: #0d0221;
18
+ }
19
+
20
+ body {
21
+ font-family: 'Orbitron', sans-serif;
22
+ background-color: var(--dark-bg);
23
+ color: white;
24
+ overflow-x: hidden;
25
+ }
26
+
27
+ .neon-text-pink {
28
+ color: var(--neon-pink);
29
+ text-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink);
30
+ }
31
+
32
+ .neon-text-blue {
33
+ color: var(--neon-blue);
34
+ text-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-blue);
35
+ }
36
+
37
+ .neon-border {
38
+ border: 2px solid var(--neon-blue);
39
+ box-shadow: 0 0 10px var(--neon-blue), inset 0 0 10px var(--neon-blue);
40
+ }
41
+
42
+ .neon-glow {
43
+ animation: glow 2s infinite alternate;
44
+ }
45
+
46
+ @keyframes glow {
47
+ from {
48
+ box-shadow: 0 0 5px var(--neon-blue), 0 0 10px var(--neon-blue);
49
+ }
50
+ to {
51
+ box-shadow: 0 0 15px var(--neon-blue), 0 0 30px var(--neon-blue);
52
+ }
53
+ }
54
+
55
+ .cell {
56
+ width: 100px;
57
+ height: 100px;
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ font-size: 3rem;
62
+ cursor: pointer;
63
+ transition: all 0.3s ease;
64
+ position: relative;
65
+ overflow: hidden;
66
+ }
67
+
68
+ .cell:hover {
69
+ background-color: rgba(5, 217, 232, 0.1);
70
+ }
71
+
72
+ .cell.x::before, .cell.x::after {
73
+ content: '';
74
+ position: absolute;
75
+ width: 80%;
76
+ height: 8px;
77
+ background-color: var(--neon-pink);
78
+ transform: rotate(45deg);
79
+ box-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink);
80
+ }
81
+
82
+ .cell.x::after {
83
+ transform: rotate(-45deg);
84
+ }
85
+
86
+ .cell.o::before {
87
+ content: '';
88
+ position: absolute;
89
+ width: 60%;
90
+ height: 60%;
91
+ border-radius: 50%;
92
+ border: 8px solid var(--neon-blue);
93
+ box-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-blue);
94
+ }
95
+
96
+ .explosion {
97
+ position: absolute;
98
+ width: 100%;
99
+ height: 100%;
100
+ pointer-events: none;
101
+ z-index: 10;
102
+ }
103
+
104
+ .particle {
105
+ position: absolute;
106
+ width: 8px;
107
+ height: 8px;
108
+ border-radius: 50%;
109
+ background-color: var(--neon-green);
110
+ box-shadow: 0 0 5px var(--neon-green), 0 0 10px var(--neon-green);
111
+ }
112
+
113
+ .cyber-btn {
114
+ background: linear-gradient(45deg, var(--neon-purple), var(--neon-blue));
115
+ border: none;
116
+ color: white;
117
+ padding: 12px 24px;
118
+ font-family: 'Orbitron', sans-serif;
119
+ font-weight: bold;
120
+ letter-spacing: 2px;
121
+ text-transform: uppercase;
122
+ cursor: pointer;
123
+ transition: all 0.3s ease;
124
+ position: relative;
125
+ overflow: hidden;
126
+ }
127
+
128
+ .cyber-btn:hover {
129
+ transform: translateY(-3px);
130
+ box-shadow: 0 5px 15px rgba(5, 217, 232, 0.4);
131
+ }
132
+
133
+ .cyber-btn:active {
134
+ transform: translateY(1px);
135
+ }
136
+
137
+ .cyber-btn::before {
138
+ content: '';
139
+ position: absolute;
140
+ top: -10px;
141
+ left: -10px;
142
+ right: -10px;
143
+ bottom: -10px;
144
+ background: linear-gradient(45deg, var(--neon-purple), var(--neon-blue), var(--neon-green));
145
+ z-index: -1;
146
+ filter: blur(10px);
147
+ opacity: 0;
148
+ transition: opacity 0.3s ease;
149
+ }
150
+
151
+ .cyber-btn:hover::before {
152
+ opacity: 0.7;
153
+ }
154
+
155
+ .grid-lines {
156
+ position: absolute;
157
+ background-color: rgba(5, 217, 232, 0.3);
158
+ }
159
+
160
+ .grid-line-h {
161
+ width: 100%;
162
+ height: 2px;
163
+ }
164
+
165
+ .grid-line-v {
166
+ width: 2px;
167
+ height: 100%;
168
+ }
169
+
170
+ .ai-selection {
171
+ display: flex;
172
+ gap: 20px;
173
+ margin-top: 20px;
174
+ }
175
+
176
+ .ai-option {
177
+ padding: 10px 20px;
178
+ border: 2px solid var(--neon-blue);
179
+ cursor: pointer;
180
+ transition: all 0.3s ease;
181
+ }
182
+
183
+ .ai-option:hover {
184
+ background-color: rgba(5, 217, 232, 0.2);
185
+ }
186
+
187
+ .ai-option.selected {
188
+ background-color: var(--neon-blue);
189
+ color: var(--dark-bg);
190
+ font-weight: bold;
191
+ }
192
+
193
+ .scanline {
194
+ position: fixed;
195
+ top: 0;
196
+ left: 0;
197
+ width: 100%;
198
+ height: 100%;
199
+ background: linear-gradient(
200
+ to bottom,
201
+ transparent 0%,
202
+ rgba(13, 2, 33, 0.1) 50%,
203
+ transparent 100%
204
+ );
205
+ background-size: 100% 8px;
206
+ pointer-events: none;
207
+ animation: scanline 6s linear infinite;
208
+ z-index: 100;
209
+ opacity: 0.3;
210
+ }
211
+
212
+ @keyframes scanline {
213
+ 0% {
214
+ background-position: 0 0;
215
+ }
216
+ 100% {
217
+ background-position: 0 100vh;
218
+ }
219
+ }
220
+ </style>
221
+ </head>
222
+ <body class="min-h-screen flex flex-col items-center justify-center p-4 relative">
223
+ <div class="scanline"></div>
224
+
225
+ <div class="absolute top-0 left-0 w-full h-full overflow-hidden z-0">
226
+ <div class="grid-line-h top-1/3" style="top: 33.33%"></div>
227
+ <div class="grid-line-h top-2/3" style="top: 66.66%"></div>
228
+ <div class="grid-line-v left-1/3" style="left: 33.33%"></div>
229
+ <div class="grid-line-v left-2/3" style="left: 66.66%"></div>
230
+ </div>
231
+
232
+ <h1 class="text-5xl font-bold mb-8 neon-text-pink">CYBER TAC TOE</h1>
233
+
234
+ <div id="game-container" class="relative z-10">
235
+ <div id="ai-selection" class="mb-8 text-center">
236
+ <h2 class="text-xl neon-text-blue mb-4">SELECT AI OPPONENT</h2>
237
+ <div class="ai-selection justify-center">
238
+ <div class="ai-option selected" data-difficulty="easy">NOVICE</div>
239
+ <div class="ai-option" data-difficulty="medium">ADEPT</div>
240
+ <div class="ai-option" data-difficulty="hard">MASTER</div>
241
+ </div>
242
+ </div>
243
+
244
+ <div id="status" class="text-xl neon-text-blue mb-6 text-center h-8"></div>
245
+
246
+ <div class="grid grid-cols-3 gap-2 neon-border p-2 mb-8 relative">
247
+ <div class="cell" data-index="0"></div>
248
+ <div class="cell" data-index="1"></div>
249
+ <div class="cell" data-index="2"></div>
250
+ <div class="cell" data-index="3"></div>
251
+ <div class="cell" data-index="4"></div>
252
+ <div class="cell" data-index="5"></div>
253
+ <div class="cell" data-index="6"></div>
254
+ <div class="cell" data-index="7"></div>
255
+ <div class="cell" data-index="8"></div>
256
+ </div>
257
+
258
+ <div class="flex justify-center">
259
+ <button id="reset-btn" class="cyber-btn neon-glow">NEW GAME</button>
260
+ </div>
261
+ </div>
262
+
263
+ <div class="mt-8 text-sm neon-text-blue">
264
+ <p>SYSTEM STATUS: <span class="neon-text-green">OPERATIONAL</span></p>
265
+ </div>
266
+
267
+ <script>
268
+ document.addEventListener('DOMContentLoaded', () => {
269
+ const cells = document.querySelectorAll('.cell');
270
+ const statusDisplay = document.getElementById('status');
271
+ const resetButton = document.getElementById('reset-btn');
272
+ const aiOptions = document.querySelectorAll('.ai-option');
273
+
274
+ let gameActive = true;
275
+ let currentPlayer = 'X';
276
+ let gameState = ['', '', '', '', '', '', '', '', ''];
277
+ let aiDifficulty = 'easy';
278
+
279
+ const winningConditions = [
280
+ [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
281
+ [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
282
+ [0, 4, 8], [2, 4, 6] // diagonals
283
+ ];
284
+
285
+ // AI difficulty selection
286
+ aiOptions.forEach(option => {
287
+ option.addEventListener('click', () => {
288
+ aiOptions.forEach(opt => opt.classList.remove('selected'));
289
+ option.classList.add('selected');
290
+ aiDifficulty = option.dataset.difficulty;
291
+ resetGame();
292
+ });
293
+ });
294
+
295
+ // Handle cell click
296
+ function handleCellClick(e) {
297
+ const clickedCell = e.target;
298
+ const clickedCellIndex = parseInt(clickedCell.getAttribute('data-index'));
299
+
300
+ if (gameState[clickedCellIndex] !== '' || !gameActive) return;
301
+
302
+ handleCellPlayed(clickedCell, clickedCellIndex);
303
+ handleResultValidation();
304
+
305
+ // AI move if game is still active and it's O's turn
306
+ if (gameActive && currentPlayer === 'O') {
307
+ setTimeout(() => {
308
+ makeAIMove();
309
+ }, 800);
310
+ }
311
+ }
312
+
313
+ // Handle cell played
314
+ function handleCellPlayed(clickedCell, clickedCellIndex) {
315
+ gameState[clickedCellIndex] = currentPlayer;
316
+ clickedCell.classList.add(currentPlayer.toLowerCase());
317
+ createExplosion(clickedCell);
318
+ }
319
+
320
+ // Create explosion effect
321
+ function createExplosion(element) {
322
+ const explosion = document.createElement('div');
323
+ explosion.className = 'explosion';
324
+ element.appendChild(explosion);
325
+
326
+ const color = currentPlayer === 'X' ? 'var(--neon-pink)' : 'var(--neon-blue)';
327
+
328
+ // Create particles
329
+ for (let i = 0; i < 20; i++) {
330
+ const particle = document.createElement('div');
331
+ particle.className = 'particle';
332
+ particle.style.backgroundColor = color;
333
+ particle.style.boxShadow = `0 0 5px ${color}, 0 0 10px ${color}`;
334
+
335
+ // Random position
336
+ const angle = Math.random() * Math.PI * 2;
337
+ const distance = 10 + Math.random() * 50;
338
+ const x = 50 + Math.cos(angle) * distance;
339
+ const y = 50 + Math.sin(angle) * distance;
340
+
341
+ particle.style.left = `${x}%`;
342
+ particle.style.top = `${y}%`;
343
+
344
+ // Animation
345
+ gsap.to(particle, {
346
+ x: Math.cos(angle) * 100,
347
+ y: Math.sin(angle) * 100,
348
+ opacity: 0,
349
+ duration: 1,
350
+ ease: 'power2.out',
351
+ onComplete: () => {
352
+ particle.remove();
353
+ }
354
+ });
355
+
356
+ explosion.appendChild(particle);
357
+ }
358
+
359
+ // Remove explosion after animation
360
+ setTimeout(() => {
361
+ explosion.remove();
362
+ }, 1000);
363
+ }
364
+
365
+ // Validate game result
366
+ function handleResultValidation() {
367
+ let roundWon = false;
368
+
369
+ for (let i = 0; i < winningConditions.length; i++) {
370
+ const [a, b, c] = winningConditions[i];
371
+
372
+ if (gameState[a] === '' || gameState[b] === '' || gameState[c] === '') continue;
373
+
374
+ if (gameState[a] === gameState[b] && gameState[b] === gameState[c]) {
375
+ roundWon = true;
376
+ break;
377
+ }
378
+ }
379
+
380
+ if (roundWon) {
381
+ statusDisplay.textContent = `PLAYER ${currentPlayer} DOMINATES!`;
382
+ gameActive = false;
383
+ highlightWinningCells();
384
+ return;
385
+ }
386
+
387
+ const roundDraw = !gameState.includes('');
388
+ if (roundDraw) {
389
+ statusDisplay.textContent = 'SYSTEM STALEMATE!';
390
+ gameActive = false;
391
+ return;
392
+ }
393
+
394
+ currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
395
+ statusDisplay.textContent = `PLAYER ${currentPlayer} TURN`;
396
+ }
397
+
398
+ // Highlight winning cells
399
+ function highlightWinningCells() {
400
+ for (let condition of winningConditions) {
401
+ const [a, b, c] = condition;
402
+
403
+ if (gameState[a] === '' || gameState[b] === '' || gameState[c] === '') continue;
404
+
405
+ if (gameState[a] === gameState[b] && gameState[b] === gameState[c]) {
406
+ cells[a].classList.add('neon-glow');
407
+ cells[b].classList.add('neon-glow');
408
+ cells[c].classList.add('neon-glow');
409
+
410
+ const color = currentPlayer === 'X' ? 'var(--neon-pink)' : 'var(--neon-blue)';
411
+ cells[a].style.boxShadow = `0 0 15px ${color}, 0 0 30px ${color}`;
412
+ cells[b].style.boxShadow = `0 0 15px ${color}, 0 0 30px ${color}`;
413
+ cells[c].style.boxShadow = `0 0 15px ${color}, 0 0 30px ${color}`;
414
+ break;
415
+ }
416
+ }
417
+ }
418
+
419
+ // AI move logic
420
+ function makeAIMove() {
421
+ if (!gameActive) return;
422
+
423
+ let move;
424
+
425
+ switch (aiDifficulty) {
426
+ case 'easy':
427
+ move = getRandomMove();
428
+ break;
429
+ case 'medium':
430
+ // 50% chance to make a smart move, 50% random
431
+ move = Math.random() < 0.5 ? getSmartMove() : getRandomMove();
432
+ break;
433
+ case 'hard':
434
+ move = getSmartMove();
435
+ break;
436
+ default:
437
+ move = getRandomMove();
438
+ }
439
+
440
+ if (move !== -1) {
441
+ const cell = cells[move];
442
+ handleCellPlayed(cell, move);
443
+ handleResultValidation();
444
+ }
445
+ }
446
+
447
+ // Get random available move
448
+ function getRandomMove() {
449
+ const availableMoves = gameState.map((cell, index) => cell === '' ? index : null).filter(val => val !== null);
450
+ if (availableMoves.length === 0) return -1;
451
+ return availableMoves[Math.floor(Math.random() * availableMoves.length)];
452
+ }
453
+
454
+ // Get smart move (tries to win or block)
455
+ function getSmartMove() {
456
+ // Check if AI can win
457
+ for (let condition of winningConditions) {
458
+ const [a, b, c] = condition;
459
+ if (gameState[a] === 'O' && gameState[b] === 'O' && gameState[c] === '') return c;
460
+ if (gameState[a] === 'O' && gameState[c] === 'O' && gameState[b] === '') return b;
461
+ if (gameState[b] === 'O' && gameState[c] === 'O' && gameState[a] === '') return a;
462
+ }
463
+
464
+ // Check if player can win and block
465
+ for (let condition of winningConditions) {
466
+ const [a, b, c] = condition;
467
+ if (gameState[a] === 'X' && gameState[b] === 'X' && gameState[c] === '') return c;
468
+ if (gameState[a] === 'X' && gameState[c] === 'X' && gameState[b] === '') return b;
469
+ if (gameState[b] === 'X' && gameState[c] === 'X' && gameState[a] === '') return a;
470
+ }
471
+
472
+ // Try to take center
473
+ if (gameState[4] === '') return 4;
474
+
475
+ // Try to take a corner
476
+ const corners = [0, 2, 6, 8];
477
+ const availableCorners = corners.filter(index => gameState[index] === '');
478
+ if (availableCorners.length > 0) {
479
+ return availableCorners[Math.floor(Math.random() * availableCorners.length)];
480
+ }
481
+
482
+ // Take any available move
483
+ return getRandomMove();
484
+ }
485
+
486
+ // Reset game
487
+ function resetGame() {
488
+ gameActive = true;
489
+ currentPlayer = 'X';
490
+ gameState = ['', '', '', '', '', '', '', '', ''];
491
+ statusDisplay.textContent = `PLAYER ${currentPlayer} TURN`;
492
+
493
+ cells.forEach(cell => {
494
+ cell.classList.remove('x', 'o', 'neon-glow');
495
+ cell.style.boxShadow = '';
496
+ });
497
+ }
498
+
499
+ // Event listeners
500
+ cells.forEach(cell => cell.addEventListener('click', handleCellClick));
501
+ resetButton.addEventListener('click', resetGame);
502
+
503
+ // Initialize game
504
+ resetGame();
505
+ });
506
+ </script>
507
+ </body>
508
+ </html>