miiann commited on
Commit
8dbc359
·
verified ·
1 Parent(s): babccc6

also add draw count - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +489 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Tic Toc Toe
3
- emoji: 🏆
4
- colorFrom: yellow
5
- colorTo: purple
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: tic-toc-toe
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: pink
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,489 @@
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 rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
11
+
12
+ body {
13
+ font-family: 'Orbitron', sans-serif;
14
+ background-color: #0f0f1a;
15
+ overflow: hidden;
16
+ perspective: 1000px;
17
+ height: 100vh;
18
+ width: 100vw;
19
+ }
20
+
21
+ .glass-box {
22
+ background: rgba(15, 15, 30, 0.2);
23
+ backdrop-filter: blur(10px);
24
+ border: 1px solid rgba(255, 255, 255, 0.1);
25
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
26
+ border-radius: 10px;
27
+ transition: all 0.3s ease;
28
+ }
29
+
30
+ .cell {
31
+ position: relative;
32
+ transition: all 0.3s ease;
33
+ transform-style: preserve-3d;
34
+ }
35
+
36
+ .cell:hover {
37
+ transform: translateZ(20px);
38
+ box-shadow: 0 0 20px rgba(0, 255, 255, 0.7);
39
+ }
40
+
41
+ .cell::before {
42
+ content: '';
43
+ position: absolute;
44
+ top: 0;
45
+ left: 0;
46
+ right: 0;
47
+ bottom: 0;
48
+ border-radius: 8px;
49
+ background: linear-gradient(135deg, rgba(0, 255, 255, 0.1), rgba(255, 0, 255, 0.1));
50
+ opacity: 0;
51
+ transition: opacity 0.3s ease;
52
+ }
53
+
54
+ .cell:hover::before {
55
+ opacity: 1;
56
+ }
57
+
58
+ .x-symbol {
59
+ color: #ff2d75;
60
+ text-shadow: 0 0 10px #ff2d75, 0 0 20px #ff2d75;
61
+ }
62
+
63
+ .o-symbol {
64
+ color: #00ffff;
65
+ text-shadow: 0 0 10px #00ffff, 0 0 20px #00ffff;
66
+ }
67
+
68
+ .winning-cell {
69
+ animation: pulse 0.5s infinite alternate;
70
+ }
71
+
72
+ @keyframes pulse {
73
+ 0% {
74
+ transform: scale(1) translateZ(0);
75
+ box-shadow: 0 0 10px currentColor;
76
+ }
77
+ 100% {
78
+ transform: scale(1.1) translateZ(10px);
79
+ box-shadow: 0 0 30px currentColor;
80
+ }
81
+ }
82
+
83
+ .confetti {
84
+ position: absolute;
85
+ width: 10px;
86
+ height: 10px;
87
+ background-color: currentColor;
88
+ opacity: 0;
89
+ }
90
+
91
+ .bg-pattern {
92
+ position: fixed;
93
+ top: 0;
94
+ left: 0;
95
+ width: 100%;
96
+ height: 100%;
97
+ z-index: -1;
98
+ opacity: 0.1;
99
+ }
100
+
101
+ .bg-symbol {
102
+ position: absolute;
103
+ font-size: 1rem;
104
+ opacity: 0;
105
+ animation: float 15s linear infinite;
106
+ pointer-events: none;
107
+ }
108
+
109
+ @keyframes float {
110
+ 0% {
111
+ transform: translateY(100vh) rotate(0deg);
112
+ opacity: 0;
113
+ }
114
+ 10% {
115
+ opacity: 0.3;
116
+ }
117
+ 90% {
118
+ opacity: 0.3;
119
+ }
120
+ 100% {
121
+ transform: translateY(-100px) rotate(360deg);
122
+ opacity: 0;
123
+ }
124
+ }
125
+
126
+ .explosion {
127
+ position: absolute;
128
+ width: 10px;
129
+ height: 10px;
130
+ border-radius: 50%;
131
+ background-color: white;
132
+ opacity: 0;
133
+ }
134
+
135
+ .smoke {
136
+ position: absolute;
137
+ width: 20px;
138
+ height: 20px;
139
+ border-radius: 50%;
140
+ background-color: rgba(255, 255, 255, 0.3);
141
+ opacity: 0;
142
+ }
143
+
144
+ .neon-text {
145
+ text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #00ffff, 0 0 20px #00ffff;
146
+ }
147
+
148
+ .neon-border {
149
+ box-shadow: 0 0 10px #00ffff, 0 0 20px #00ffff inset;
150
+ }
151
+ </style>
152
+ </head>
153
+ <body class="h-screen w-screen flex flex-col items-center justify-center p-4 overflow-hidden">
154
+ <div class="bg-pattern" id="bgPattern"></div>
155
+
156
+ <div class="text-center mb-8">
157
+ <h1 class="text-4xl md:text-5xl font-bold text-white neon-text mb-2">NEON TIC-TAC-TOE</h1>
158
+ <div class="flex justify-center space-x-8 text-white text-xl">
159
+ <div class="glass-box px-4 py-2 rounded-lg">
160
+ <span class="text-pink-500">X</span> Wins: <span id="xWins" class="text-white">0</span>
161
+ </div>
162
+ <div class="glass-box px-4 py-2 rounded-lg">
163
+ <span class="text-cyan-400">O</span> Wins: <span id="oWins" class="text-white">0</span>
164
+ </div>
165
+ <div class="glass-box px-4 py-2 rounded-lg">
166
+ <span class="text-yellow-400">Draws:</span> <span id="draws" class="text-white">0</span>
167
+ </div>
168
+ </div>
169
+ </div>
170
+
171
+ <div class="relative">
172
+ <div id="gameBoard" class="grid grid-cols-3 gap-4 glass-box p-6 rounded-xl neon-border">
173
+ <!-- Cells will be generated by JavaScript -->
174
+ </div>
175
+ </div>
176
+
177
+ <div class="mt-8">
178
+ <button id="resetBtn" class="glass-box px-6 py-3 rounded-lg text-white text-lg font-bold hover:bg-cyan-500 hover:text-white transition-all duration-300 hover:scale-105">
179
+ RESET GAME
180
+ </button>
181
+ </div>
182
+
183
+ <script>
184
+ document.addEventListener('DOMContentLoaded', () => {
185
+ // Game state
186
+ let board = ['', '', '', '', '', '', '', '', ''];
187
+ let currentPlayer = 'X';
188
+ let gameActive = true;
189
+ let xWins = 0;
190
+ let oWins = 0;
191
+ let draws = 0;
192
+
193
+ // DOM elements
194
+ const gameBoard = document.getElementById('gameBoard');
195
+ const xWinsElement = document.getElementById('xWins');
196
+ const oWinsElement = document.getElementById('oWins');
197
+ const drawsElement = document.getElementById('draws');
198
+ const resetBtn = document.getElementById('resetBtn');
199
+ const bgPattern = document.getElementById('bgPattern');
200
+
201
+ // Create background floating symbols
202
+ createFloatingSymbols();
203
+
204
+ // Create game board cells
205
+ createBoard();
206
+
207
+ // Create floating symbols in background
208
+ function createFloatingSymbols() {
209
+ for (let i = 0; i < 30; i++) {
210
+ const symbol = document.createElement('div');
211
+ symbol.className = `bg-symbol ${Math.random() > 0.5 ? 'x-symbol' : 'o-symbol'}`;
212
+ symbol.innerHTML = Math.random() > 0.5 ? '×' : '○';
213
+ symbol.style.left = `${Math.random() * 100}%`;
214
+ symbol.style.animationDuration = `${10 + Math.random() * 20}s`;
215
+ symbol.style.animationDelay = `${Math.random() * 5}s`;
216
+ bgPattern.appendChild(symbol);
217
+ }
218
+ }
219
+
220
+ // Create game board
221
+ function createBoard() {
222
+ gameBoard.innerHTML = '';
223
+ for (let i = 0; i < 9; i++) {
224
+ const cell = document.createElement('div');
225
+ cell.className = 'cell w-20 h-20 md:w-24 md:h-24 flex items-center justify-center text-5xl glass-box cursor-pointer';
226
+ cell.setAttribute('data-index', i);
227
+ cell.addEventListener('click', handleCellClick);
228
+
229
+ // Add hover effect that throws symbols
230
+ cell.addEventListener('mousemove', (e) => {
231
+ if (cell.textContent !== '' || !gameActive) return;
232
+
233
+ const rect = cell.getBoundingClientRect();
234
+ const x = e.clientX - rect.left;
235
+ const y = e.clientY - rect.top;
236
+
237
+ const symbol = document.createElement('div');
238
+ symbol.className = `absolute text-xl ${currentPlayer === 'X' ? 'x-symbol' : 'o-symbol'}`;
239
+ symbol.textContent = currentPlayer === 'X' ? '×' : '○';
240
+ symbol.style.left = `${x}px`;
241
+ symbol.style.top = `${y}px`;
242
+ symbol.style.opacity = '0';
243
+ symbol.style.transform = 'scale(0)';
244
+ symbol.style.transition = 'all 0.5s ease-out';
245
+
246
+ cell.appendChild(symbol);
247
+
248
+ setTimeout(() => {
249
+ symbol.style.opacity = '0.7';
250
+ symbol.style.transform = 'scale(1) translate(-50%, -50%)';
251
+ setTimeout(() => {
252
+ symbol.style.opacity = '0';
253
+ symbol.style.transform = 'scale(0.5) translate(-50%, -50%)';
254
+ setTimeout(() => {
255
+ cell.removeChild(symbol);
256
+ }, 500);
257
+ }, 300);
258
+ }, 10);
259
+ });
260
+
261
+ gameBoard.appendChild(cell);
262
+ }
263
+ }
264
+
265
+ // Handle cell click
266
+ function handleCellClick(e) {
267
+ const cell = e.target;
268
+ const index = parseInt(cell.getAttribute('data-index'));
269
+
270
+ if (board[index] !== '' || !gameActive) return;
271
+
272
+ // Update board
273
+ board[index] = currentPlayer;
274
+ cell.textContent = currentPlayer;
275
+ cell.classList.add(currentPlayer === 'X' ? 'x-symbol' : 'o-symbol');
276
+
277
+ // Add animation
278
+ cell.style.transform = 'translateZ(30px)';
279
+ cell.style.boxShadow = `0 0 30px ${currentPlayer === 'X' ? '#ff2d75' : '#00ffff'}`;
280
+
281
+ setTimeout(() => {
282
+ cell.style.transform = 'translateZ(10px)';
283
+ cell.style.boxShadow = `0 0 20px ${currentPlayer === 'X' ? '#ff2d75' : '#00ffff'}`;
284
+ }, 300);
285
+
286
+ // Check for winner
287
+ if (checkWinner()) {
288
+ gameActive = false;
289
+ celebrateWin();
290
+ return;
291
+ }
292
+
293
+ // Check for draw
294
+ if (!board.includes('')) {
295
+ gameActive = false;
296
+ draws++;
297
+ drawsElement.textContent = draws;
298
+ setTimeout(() => {
299
+ alert('Game ended in a draw!');
300
+ }, 500);
301
+ return;
302
+ }
303
+
304
+ // Switch player
305
+ currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
306
+
307
+ // Add floating indicator
308
+ const indicator = document.createElement('div');
309
+ indicator.className = `absolute -top-8 text-xl ${currentPlayer === 'X' ? 'x-symbol' : 'o-symbol'}`;
310
+ indicator.textContent = currentPlayer === 'X' ? '×' : '○';
311
+ indicator.style.opacity = '0';
312
+ indicator.style.transform = 'translateY(20px)';
313
+ gameBoard.parentNode.appendChild(indicator);
314
+
315
+ setTimeout(() => {
316
+ indicator.style.opacity = '1';
317
+ indicator.style.transform = 'translateY(0)';
318
+ setTimeout(() => {
319
+ indicator.style.opacity = '0';
320
+ indicator.style.transform = 'translateY(-20px)';
321
+ setTimeout(() => {
322
+ gameBoard.parentNode.removeChild(indicator);
323
+ }, 500);
324
+ }, 1000);
325
+ }, 10);
326
+ }
327
+
328
+ // Check for winner
329
+ function checkWinner() {
330
+ const winningCombos = [
331
+ [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
332
+ [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
333
+ [0, 4, 8], [2, 4, 6] // diagonals
334
+ ];
335
+
336
+ for (let combo of winningCombos) {
337
+ const [a, b, c] = combo;
338
+ if (board[a] && board[a] === board[b] && board[a] === board[c]) {
339
+ // Highlight winning cells
340
+ document.querySelectorAll(`[data-index="${a}"], [data-index="${b}"], [data-index="${c}"]`).forEach(cell => {
341
+ cell.classList.add('winning-cell');
342
+ });
343
+
344
+ // Update score
345
+ if (board[a] === 'X') {
346
+ xWins++;
347
+ xWinsElement.textContent = xWins;
348
+ } else {
349
+ oWins++;
350
+ oWinsElement.textContent = oWins;
351
+ }
352
+
353
+ return true;
354
+ }
355
+ }
356
+ return false;
357
+ }
358
+
359
+ // Celebrate win with confetti
360
+ function celebrateWin() {
361
+ const winner = currentPlayer;
362
+ const color = winner === 'X' ? '#ff2d75' : '#00ffff';
363
+
364
+ for (let i = 0; i < 100; i++) {
365
+ const confetti = document.createElement('div');
366
+ confetti.className = 'confetti';
367
+ confetti.style.backgroundColor = color;
368
+ confetti.style.left = `${Math.random() * 100}%`;
369
+ confetti.style.top = `${Math.random() * 100}%`;
370
+ confetti.style.transform = `rotate(${Math.random() * 360}deg)`;
371
+
372
+ const size = Math.random() * 10 + 5;
373
+ confetti.style.width = `${size}px`;
374
+ confetti.style.height = `${size}px`;
375
+
376
+ if (Math.random() > 0.5) {
377
+ confetti.style.borderRadius = '50%';
378
+ }
379
+
380
+ document.body.appendChild(confetti);
381
+
382
+ setTimeout(() => {
383
+ confetti.style.opacity = '1';
384
+ confetti.style.transform = `translate(${Math.random() * 200 - 100}px, ${Math.random() * 200 + 100}px) rotate(${Math.random() * 360}deg)`;
385
+
386
+ setTimeout(() => {
387
+ confetti.style.opacity = '0';
388
+ setTimeout(() => {
389
+ document.body.removeChild(confetti);
390
+ }, 1000);
391
+ }, 2000);
392
+ }, i * 20);
393
+ }
394
+
395
+ // Add celebration text
396
+ const celebration = document.createElement('div');
397
+ celebration.className = 'absolute inset-0 flex items-center justify-center pointer-events-none';
398
+ celebration.innerHTML = `<div class="text-6xl font-bold ${winner === 'X' ? 'x-symbol' : 'o-symbol'} opacity-0 transform scale(0)">${winner} WINS!</div>`;
399
+ gameBoard.parentNode.appendChild(celebration);
400
+
401
+ setTimeout(() => {
402
+ celebration.firstChild.style.opacity = '1';
403
+ celebration.firstChild.style.transform = 'scale(1)';
404
+
405
+ setTimeout(() => {
406
+ celebration.firstChild.style.opacity = '0';
407
+ celebration.firstChild.style.transform = 'scale(1.5)';
408
+ setTimeout(() => {
409
+ gameBoard.parentNode.removeChild(celebration);
410
+ }, 500);
411
+ }, 2000);
412
+ }, 100);
413
+ }
414
+
415
+ // Reset game
416
+ resetBtn.addEventListener('click', () => {
417
+ // Create explosion effect
418
+ const cells = document.querySelectorAll('.cell');
419
+ cells.forEach(cell => {
420
+ if (cell.textContent !== '') {
421
+ // Create explosion particles
422
+ for (let i = 0; i < 10; i++) {
423
+ const particle = document.createElement('div');
424
+ particle.className = 'explosion';
425
+ particle.style.left = `${Math.random() * 80 + 10}%`;
426
+ particle.style.top = `${Math.random() * 80 + 10}%`;
427
+ particle.style.backgroundColor = cell.classList.contains('x-symbol') ? '#ff2d75' : '#00ffff';
428
+ cell.appendChild(particle);
429
+
430
+ setTimeout(() => {
431
+ particle.style.opacity = '1';
432
+ particle.style.transform = `translate(${Math.random() * 100 - 50}px, ${Math.random() * 100 - 50}px) scale(${Math.random() * 2 + 1})`;
433
+
434
+ setTimeout(() => {
435
+ particle.style.opacity = '0';
436
+ setTimeout(() => {
437
+ if (cell.contains(particle)) {
438
+ cell.removeChild(particle);
439
+ }
440
+ }, 500);
441
+ }, 300);
442
+ }, 10);
443
+ }
444
+
445
+ // Create smoke
446
+ for (let i = 0; i < 5; i++) {
447
+ const smoke = document.createElement('div');
448
+ smoke.className = 'smoke';
449
+ smoke.style.left = `${Math.random() * 80 + 10}%`;
450
+ smoke.style.top = `${Math.random() * 80 + 10}%`;
451
+ cell.appendChild(smoke);
452
+
453
+ setTimeout(() => {
454
+ smoke.style.opacity = '0.5';
455
+ smoke.style.transform = `translate(${Math.random() * 40 - 20}px, ${Math.random() * 40 - 20}px) scale(${Math.random() * 3 + 1})`;
456
+
457
+ setTimeout(() => {
458
+ smoke.style.opacity = '0';
459
+ setTimeout(() => {
460
+ if (cell.contains(smoke)) {
461
+ cell.removeChild(smoke);
462
+ }
463
+ }, 500);
464
+ }, 1000);
465
+ }, 10);
466
+ }
467
+ }
468
+ });
469
+
470
+ // Reset game state after animation
471
+ setTimeout(() => {
472
+ board = ['', '', '', '', '', '', '', '', ''];
473
+ currentPlayer = 'X';
474
+ gameActive = true;
475
+
476
+ // Remove all winning cell classes
477
+ document.querySelectorAll('.cell').forEach(cell => {
478
+ cell.className = 'cell w-20 h-20 md:w-24 md:h-24 flex items-center justify-center text-5xl glass-box cursor-pointer';
479
+ cell.textContent = '';
480
+ });
481
+
482
+ // Create a new board (for visual refresh)
483
+ createBoard();
484
+ }, 1000);
485
+ });
486
+ });
487
+ </script>
488
+ <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=miiann/tic-toc-toe" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
489
+ </html>