mahen23 commited on
Commit
22ad172
·
verified ·
1 Parent(s): 9ba2ae1

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +540 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Tetris One
3
- emoji: 📉
4
- colorFrom: indigo
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: tetris-one
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
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,540 @@
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>Simple Tetris</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ .cell {
10
+ width: 30px;
11
+ height: 30px;
12
+ border: 1px solid #ccc;
13
+ }
14
+
15
+ .piece-I { background-color: #00f0f0; }
16
+ .piece-J { background-color: #0000f0; }
17
+ .piece-L { background-color: #f0a000; }
18
+ .piece-O { background-color: #f0f000; }
19
+ .piece-S { background-color: #00f000; }
20
+ .piece-T { background-color: #a000f0; }
21
+ .piece-Z { background-color: #f00000; }
22
+
23
+ #game-board {
24
+ display: grid;
25
+ grid-template-rows: repeat(20, 30px);
26
+ grid-template-columns: repeat(10, 30px);
27
+ gap: 1px;
28
+ background-color: #111;
29
+ }
30
+
31
+ #next-piece {
32
+ display: grid;
33
+ grid-template-rows: repeat(4, 30px);
34
+ grid-template-columns: repeat(4, 30px);
35
+ gap: 1px;
36
+ background-color: #111;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4">
41
+ <div class="text-center mb-4">
42
+ <h1 class="text-4xl font-bold mb-2">Tetris</h1>
43
+ <div class="flex justify-center gap-8">
44
+ <div>
45
+ <div class="text-xl font-semibold mb-2">Score: <span id="score">0</span></div>
46
+ <div class="text-xl font-semibold mb-2">Level: <span id="level">1</span></div>
47
+ <div class="text-xl font-semibold mb-2">Lines: <span id="lines">0</span></div>
48
+ </div>
49
+ <div>
50
+ <div class="text-xl font-semibold mb-2">High Score: <span id="high-score">0</span></div>
51
+ <div class="text-lg mb-2">Next:</div>
52
+ <div id="next-piece" class="mb-4"></div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <div class="flex gap-8 items-start">
58
+ <div id="game-board"></div>
59
+ </div>
60
+
61
+ <div class="mt-6 flex gap-4">
62
+ <button id="start-btn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
63
+ Start Game
64
+ </button>
65
+ <button id="pause-btn" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-2 px-4 rounded" disabled>
66
+ Pause
67
+ </button>
68
+ <button id="reset-btn" class="bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
69
+ Reset
70
+ </button>
71
+ </div>
72
+
73
+ <div class="mt-6 text-center">
74
+ <p class="mb-2">Controls:</p>
75
+ <p>← → : Move Left/Right</p>
76
+ <p>↑ : Rotate</p>
77
+ <p>↓ : Soft Drop</p>
78
+ <p>Space : Hard Drop</p>
79
+ <p>P : Pause</p>
80
+ </div>
81
+
82
+ <script>
83
+ // Game constants
84
+ const COLS = 10;
85
+ const ROWS = 20;
86
+ const BLOCK_SIZE = 30;
87
+ const EMPTY = 'empty';
88
+
89
+ // Tetromino shapes
90
+ const SHAPES = {
91
+ I: [
92
+ [0, 0, 0, 0],
93
+ [1, 1, 1, 1],
94
+ [0, 0, 0, 0],
95
+ [0, 0, 0, 0]
96
+ ],
97
+ J: [
98
+ [1, 0, 0],
99
+ [1, 1, 1],
100
+ [0, 0, 0]
101
+ ],
102
+ L: [
103
+ [0, 0, 1],
104
+ [1, 1, 1],
105
+ [0, 0, 0]
106
+ ],
107
+ O: [
108
+ [1, 1],
109
+ [1, 1]
110
+ ],
111
+ S: [
112
+ [0, 1, 1],
113
+ [1, 1, 0],
114
+ [0, 0, 0]
115
+ ],
116
+ T: [
117
+ [0, 1, 0],
118
+ [1, 1, 1],
119
+ [0, 0, 0]
120
+ ],
121
+ Z: [
122
+ [1, 1, 0],
123
+ [0, 1, 1],
124
+ [0, 0, 0]
125
+ ]
126
+ };
127
+
128
+ const COLORS = {
129
+ I: 'piece-I',
130
+ J: 'piece-J',
131
+ L: 'piece-L',
132
+ O: 'piece-O',
133
+ S: 'piece-S',
134
+ T: 'piece-T',
135
+ Z: 'piece-Z'
136
+ };
137
+
138
+ // Game variables
139
+ let board = Array(ROWS).fill().map(() => Array(COLS).fill(EMPTY));
140
+ let currentPiece = null;
141
+ let nextPiece = null;
142
+ let currentX = 0;
143
+ let currentY = 0;
144
+ let score = 0;
145
+ let level = 1;
146
+ let lines = 0;
147
+ let gameInterval = null;
148
+ let gameSpeed = 1000;
149
+ let isPaused = false;
150
+ let isGameOver = false;
151
+
152
+ // DOM elements
153
+ const gameBoard = document.getElementById('game-board');
154
+ const nextPieceDisplay = document.getElementById('next-piece');
155
+ const scoreDisplay = document.getElementById('score');
156
+ const levelDisplay = document.getElementById('level');
157
+ const linesDisplay = document.getElementById('lines');
158
+ const highScoreDisplay = document.getElementById('high-score');
159
+ const startBtn = document.getElementById('start-btn');
160
+ const pauseBtn = document.getElementById('pause-btn');
161
+ const resetBtn = document.getElementById('reset-btn');
162
+
163
+ // Initialize the game board
164
+ function initBoard() {
165
+ gameBoard.innerHTML = '';
166
+ for (let y = 0; y < ROWS; y++) {
167
+ for (let x = 0; x < COLS; x++) {
168
+ const cell = document.createElement('div');
169
+ cell.className = 'cell';
170
+ cell.id = `cell-${y}-${x}`;
171
+ gameBoard.appendChild(cell);
172
+ }
173
+ }
174
+ }
175
+
176
+ // Initialize the next piece display
177
+ function initNextPieceDisplay() {
178
+ nextPieceDisplay.innerHTML = '';
179
+ for (let y = 0; y < 4; y++) {
180
+ for (let x = 0; x < 4; x++) {
181
+ const cell = document.createElement('div');
182
+ cell.className = 'cell';
183
+ cell.id = `next-cell-${y}-${x}`;
184
+ nextPieceDisplay.appendChild(cell);
185
+ }
186
+ }
187
+ }
188
+
189
+ // Get a random tetromino
190
+ function getRandomPiece() {
191
+ const pieces = Object.keys(SHAPES);
192
+ const randomPiece = pieces[Math.floor(Math.random() * pieces.length)];
193
+ return {
194
+ shape: SHAPES[randomPiece],
195
+ color: COLORS[randomPiece],
196
+ type: randomPiece
197
+ };
198
+ }
199
+
200
+ // Draw the game board
201
+ function drawBoard() {
202
+ for (let y = 0; y < ROWS; y++) {
203
+ for (let x = 0; x < COLS; x++) {
204
+ const cell = document.getElementById(`cell-${y}-${x}`);
205
+ cell.className = 'cell';
206
+ if (board[y][x] !== EMPTY) {
207
+ cell.classList.add(board[y][x]);
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ // Draw the current piece
214
+ function drawPiece() {
215
+ if (!currentPiece) return;
216
+
217
+ for (let y = 0; y < currentPiece.shape.length; y++) {
218
+ for (let x = 0; x < currentPiece.shape[y].length; x++) {
219
+ if (currentPiece.shape[y][x]) {
220
+ const boardY = currentY + y;
221
+ const boardX = currentX + x;
222
+ if (boardY >= 0 && boardY < ROWS && boardX >= 0 && boardX < COLS) {
223
+ const cell = document.getElementById(`cell-${boardY}-${boardX}`);
224
+ cell.classList.add(currentPiece.color);
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ // Draw the next piece
232
+ function drawNextPiece() {
233
+ if (!nextPiece) return;
234
+
235
+ // Clear next piece display
236
+ for (let y = 0; y < 4; y++) {
237
+ for (let x = 0; x < 4; x++) {
238
+ const cell = document.getElementById(`next-cell-${y}-${x}`);
239
+ cell.className = 'cell';
240
+ }
241
+ }
242
+
243
+ // Draw the next piece centered
244
+ const offsetX = Math.floor((4 - nextPiece.shape[0].length) / 2);
245
+ const offsetY = Math.floor((4 - nextPiece.shape.length) / 2);
246
+
247
+ for (let y = 0; y < nextPiece.shape.length; y++) {
248
+ for (let x = 0; x < nextPiece.shape[y].length; x++) {
249
+ if (nextPiece.shape[y][x]) {
250
+ const displayY = y + offsetY;
251
+ const displayX = x + offsetX;
252
+ const cell = document.getElementById(`next-cell-${displayY}-${displayX}`);
253
+ cell.classList.add(nextPiece.color);
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ // Check for collisions
260
+ function collision(x, y, piece) {
261
+ for (let py = 0; py < piece.shape.length; py++) {
262
+ for (let px = 0; px < piece.shape[py].length; px++) {
263
+ if (!piece.shape[py][px]) continue;
264
+
265
+ const newX = x + px;
266
+ const newY = y + py;
267
+
268
+ if (newX < 0 || newX >= COLS || newY >= ROWS) {
269
+ return true;
270
+ }
271
+
272
+ if (newY >= 0 && board[newY][newX] !== EMPTY) {
273
+ return true;
274
+ }
275
+ }
276
+ }
277
+ return false;
278
+ }
279
+
280
+ // Rotate the current piece
281
+ function rotate() {
282
+ if (!currentPiece || isPaused || isGameOver) return;
283
+
284
+ const newShape = currentPiece.shape[0].map((_, i) =>
285
+ currentPiece.shape.map(row => row[i]).reverse()
286
+ );
287
+
288
+ const oldShape = currentPiece.shape;
289
+ currentPiece.shape = newShape;
290
+
291
+ if (collision(currentX, currentY, currentPiece)) {
292
+ currentPiece.shape = oldShape;
293
+ } else {
294
+ draw();
295
+ }
296
+ }
297
+
298
+ // Move the current piece
299
+ function move(direction) {
300
+ if (!currentPiece || isPaused || isGameOver) return;
301
+
302
+ let newX = currentX;
303
+ let newY = currentY;
304
+
305
+ switch (direction) {
306
+ case 'left':
307
+ newX--;
308
+ break;
309
+ case 'right':
310
+ newX++;
311
+ break;
312
+ case 'down':
313
+ newY++;
314
+ break;
315
+ }
316
+
317
+ if (!collision(newX, newY, currentPiece)) {
318
+ currentX = newX;
319
+ currentY = newY;
320
+ draw();
321
+ return true;
322
+ }
323
+
324
+ // If we couldn't move down, lock the piece
325
+ if (direction === 'down') {
326
+ lockPiece();
327
+ clearLines();
328
+ spawnPiece();
329
+
330
+ if (collision(currentX, currentY, currentPiece)) {
331
+ gameOver();
332
+ }
333
+ }
334
+
335
+ return false;
336
+ }
337
+
338
+ // Hard drop the current piece
339
+ function hardDrop() {
340
+ if (!currentPiece || isPaused || isGameOver) return;
341
+
342
+ while (move('down')) {
343
+ // Keep moving down until we can't anymore
344
+ }
345
+ }
346
+
347
+ // Lock the current piece to the board
348
+ function lockPiece() {
349
+ for (let y = 0; y < currentPiece.shape.length; y++) {
350
+ for (let x = 0; x < currentPiece.shape[y].length; x++) {
351
+ if (currentPiece.shape[y][x]) {
352
+ const boardY = currentY + y;
353
+ const boardX = currentX + x;
354
+ if (boardY >= 0 && boardX >= 0 && boardY < ROWS && boardX < COLS) {
355
+ board[boardY][boardX] = currentPiece.color;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // Clear completed lines
363
+ function clearLines() {
364
+ let linesCleared = 0;
365
+
366
+ for (let y = ROWS - 1; y >= 0; y--) {
367
+ if (board[y].every(cell => cell !== EMPTY)) {
368
+ // Remove the line
369
+ board.splice(y, 1);
370
+ // Add a new empty line at the top
371
+ board.unshift(Array(COLS).fill(EMPTY));
372
+ linesCleared++;
373
+ y++; // Check the same row again (now with new content)
374
+ }
375
+ }
376
+
377
+ if (linesCleared > 0) {
378
+ // Update score
379
+ const points = [0, 40, 100, 300, 1200][linesCleared] * level;
380
+ score += points;
381
+ lines += linesCleared;
382
+
383
+ // Update level every 10 lines
384
+ const newLevel = Math.floor(lines / 10) + 1;
385
+ if (newLevel > level) {
386
+ level = newLevel;
387
+ gameSpeed = Math.max(100, 1000 - (level - 1) * 100);
388
+ clearInterval(gameInterval);
389
+ gameInterval = setInterval(gameLoop, gameSpeed);
390
+ }
391
+
392
+ updateDisplay();
393
+ }
394
+ }
395
+
396
+ // Spawn a new piece
397
+ function spawnPiece() {
398
+ currentPiece = nextPiece || getRandomPiece();
399
+ nextPiece = getRandomPiece();
400
+
401
+ // Start position (centered at top)
402
+ currentX = Math.floor(COLS / 2) - Math.floor(currentPiece.shape[0].length / 2);
403
+ currentY = 0;
404
+
405
+ drawNextPiece();
406
+ }
407
+
408
+ // Game loop
409
+ function gameLoop() {
410
+ if (!isPaused && !isGameOver) {
411
+ move('down');
412
+ }
413
+ }
414
+
415
+ // Start the game
416
+ function startGame() {
417
+ if (gameInterval) {
418
+ clearInterval(gameInterval);
419
+ }
420
+
421
+ // Reset game state
422
+ board = Array(ROWS).fill().map(() => Array(COLS).fill(EMPTY));
423
+ score = 0;
424
+ level = 1;
425
+ lines = 0;
426
+ gameSpeed = 1000;
427
+ isPaused = false;
428
+ isGameOver = false;
429
+
430
+ // Get high score from local storage
431
+ const highScore = localStorage.getItem('tetrisHighScore') || 0;
432
+ highScoreDisplay.textContent = highScore;
433
+
434
+ // Initialize pieces
435
+ nextPiece = getRandomPiece();
436
+ spawnPiece();
437
+
438
+ // Start game loop
439
+ gameInterval = setInterval(gameLoop, gameSpeed);
440
+
441
+ // Update UI
442
+ updateDisplay();
443
+ startBtn.disabled = true;
444
+ pauseBtn.disabled = false;
445
+ pauseBtn.textContent = 'Pause';
446
+ }
447
+
448
+ // Pause the game
449
+ function togglePause() {
450
+ if (isGameOver) return;
451
+
452
+ isPaused = !isPaused;
453
+ pauseBtn.textContent = isPaused ? 'Resume' : 'Pause';
454
+ }
455
+
456
+ // Reset the game
457
+ function resetGame() {
458
+ clearInterval(gameInterval);
459
+ gameInterval = null;
460
+ isGameOver = true;
461
+
462
+ startBtn.disabled = false;
463
+ pauseBtn.disabled = true;
464
+
465
+ // Clear the board
466
+ board = Array(ROWS).fill().map(() => Array(COLS).fill(EMPTY));
467
+ draw();
468
+ }
469
+
470
+ // Game over
471
+ function gameOver() {
472
+ clearInterval(gameInterval);
473
+ isGameOver = true;
474
+
475
+ // Update high score if needed
476
+ const highScore = localStorage.getItem('tetrisHighScore') || 0;
477
+ if (score > highScore) {
478
+ localStorage.setItem('tetrisHighScore', score);
479
+ highScoreDisplay.textContent = score;
480
+ }
481
+
482
+ alert(`Game Over! Your score: ${score}`);
483
+ startBtn.disabled = false;
484
+ pauseBtn.disabled = true;
485
+ }
486
+
487
+ // Update the display
488
+ function updateDisplay() {
489
+ scoreDisplay.textContent = score;
490
+ levelDisplay.textContent = level;
491
+ linesDisplay.textContent = lines;
492
+ }
493
+
494
+ // Draw everything
495
+ function draw() {
496
+ drawBoard();
497
+ drawPiece();
498
+ }
499
+
500
+ // Event listeners
501
+ document.addEventListener('keydown', (e) => {
502
+ if (isGameOver) return;
503
+
504
+ switch (e.key) {
505
+ case 'ArrowLeft':
506
+ move('left');
507
+ break;
508
+ case 'ArrowRight':
509
+ move('right');
510
+ break;
511
+ case 'ArrowDown':
512
+ move('down');
513
+ break;
514
+ case 'ArrowUp':
515
+ rotate();
516
+ break;
517
+ case ' ':
518
+ hardDrop();
519
+ break;
520
+ case 'p':
521
+ case 'P':
522
+ togglePause();
523
+ break;
524
+ }
525
+ });
526
+
527
+ startBtn.addEventListener('click', startGame);
528
+ pauseBtn.addEventListener('click', togglePause);
529
+ resetBtn.addEventListener('click', resetGame);
530
+
531
+ // Initialize the game
532
+ initBoard();
533
+ initNextPieceDisplay();
534
+
535
+ // Load high score
536
+ const highScore = localStorage.getItem('tetrisHighScore') || 0;
537
+ highScoreDisplay.textContent = highScore;
538
+ </script>
539
+ <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=mahen23/tetris-one" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
540
+ </html>