commit 2e986138937b86f9b2eda7b236f1af8062dccd91
Author: root <root@hub.scroll.pub> Date: 2025-01-07 03:39:46 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..3548c2b --- /dev/null +++ b/body.html @@ -0,0 +1,26 @@ +<header> + <h1>Tetrix</h1> + <p>Classic Tetris in your browser</p> +</header> + +<main> + <div class="game-container"> + <div class="grid"></div> + <div class="sidebar"> + <div class="next-piece"> + <h2>Next</h2> + <div class="mini-grid"></div> + </div> + <div class="score-display"> + <h2>Score</h2> + <p class="score">0</p> + </div> + <button class="start-button">Start Game</button> + </div> + </div> +</main> + +<footer> + <p>Use arrow keys to move and rotate pieces</p> + <p>Space to drop instantly</p> +</footer> diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..98e318f --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://tetrix.scroll.pub +metaTags +editButton /edit.html +title Tetrix - Play Tetris Online +style.css +body.html +script.js diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..c00a8de --- /dev/null +++ b/prompt.json @@ -0,0 +1,25 @@ +{ + "id": "f34bdb72-d432-49af-9346-8e54733f5f24", + "object": "chat.completion", + "created": 1736221154, + "model": "deepseek-chat", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "---domain---\ntetrix.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://tetrix.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Tetrix - Play Tetris Online\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<header>\n <h1>Tetrix</h1>\n <p>Classic Tetris in your browser</p>\n</header>\n\n<main>\n <div class=\"game-container\">\n <div class=\"grid\"></div>\n <div class=\"sidebar\">\n <div class=\"next-piece\">\n <h2>Next</h2>\n <div class=\"mini-grid\"></div>\n </div>\n <div class=\"score-display\">\n <h2>Score</h2>\n <p class=\"score\">0</p>\n </div>\n <button class=\"start-button\">Start Game</button>\n </div>\n </div>\n</main>\n\n<footer>\n <p>Use arrow keys to move and rotate pieces</p>\n <p>Space to drop instantly</p>\n</footer>\n\n---style.css---\n:root {\n --primary: #2c3e50;\n --secondary: #34495e;\n --accent: #e74c3c;\n --text: #ecf0f1;\n --grid-color: #7f8c8d;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Arial', sans-serif;\n background: var(--primary);\n color: var(--text);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 2rem;\n}\n\nheader {\n text-align: center;\n margin-bottom: 2rem;\n}\n\nh1 {\n font-size: 3rem;\n color: var(--accent);\n text-shadow: 2px 2px 4px rgba(0,0,0,0.3);\n}\n\n.game-container {\n display: flex;\n gap: 2rem;\n background: var(--secondary);\n padding: 2rem;\n border-radius: 1rem;\n box-shadow: 0 0 20px rgba(0,0,0,0.3);\n}\n\n.grid, .mini-grid {\n display: grid;\n background: var(--primary);\n border: 2px solid var(--grid-color);\n}\n\n.grid {\n grid-template-rows: repeat(20, 1fr);\n grid-template-columns: repeat(10, 1fr);\n width: 300px;\n height: 600px;\n}\n\n.mini-grid {\n grid-template-rows: repeat(4, 1fr);\n grid-template-columns: repeat(4, 1fr);\n width: 120px;\n height: 120px;\n margin-top: 1rem;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 2rem;\n}\n\n.score-display {\n text-align: center;\n}\n\n.score {\n font-size: 2rem;\n font-weight: bold;\n color: var(--accent);\n}\n\n.start-button {\n padding: 1rem 2rem;\n background: var(--accent);\n color: var(--text);\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n font-size: 1.2rem;\n transition: all 0.3s ease;\n}\n\n.start-button:hover {\n transform: scale(1.05);\n box-shadow: 0 0 10px rgba(231, 76, 60, 0.5);\n}\n\nfooter {\n margin-top: 2rem;\n text-align: center;\n color: var(--grid-color);\n}\n\n@media (max-width: 768px) {\n .game-container {\n flex-direction: column;\n align-items: center;\n }\n \n .grid {\n width: 240px;\n height: 480px;\n }\n}\n\n---script.js---\nconst grid = document.querySelector('.grid');\nconst miniGrid = document.querySelector('.mini-grid');\nconst scoreDisplay = document.querySelector('.score');\nconst startButton = document.querySelector('.start-button');\nconst width = 10;\nlet squares = Array.from(grid.querySelectorAll('div'));\nlet miniSquares = Array.from(miniGrid.querySelectorAll('div'));\nlet currentPosition = 4;\nlet currentRotation = 0;\nlet score = 0;\nlet timerId;\nlet nextRandom = 0;\n\n// The Tetrominoes\nconst lTetromino = [\n [1, width+1, width*2+1, 2],\n [width, width+1, width+2, width*2+2],\n [1, width+1, width*2+1, width*2],\n [width, width*2, width*2+1, width*2+2]\n]\n\nconst zTetromino = [\n [0, width, width+1, width*2+1],\n [width+1, width+2, width*2, width*2+1],\n [0, width, width+1, width*2+1],\n [width+1, width+2, width*2, width*2+1]\n]\n\nconst tTetromino = [\n [1, width, width+1, width+2],\n [1, width+1, width+2, width*2+1],\n [width, width+1, width+2, width*2+1],\n [1, width, width+1, width*2+1]\n]\n\nconst oTetromino = [\n [0, 1, width, width+1],\n [0, 1, width, width+1],\n [0, 1, width, width+1],\n [0, 1, width, width+1]\n]\n\nconst iTetromino = [\n [1, width+1, width*2+1, width*3+1],\n [width, width+1, width+2, width+3],\n [1, width+1, width*2+1, width*3+1],\n [width, width+1, width+2, width+3]\n]\n\nconst theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino]\n\nlet random = Math.floor(Math.random()*theTetrominoes.length)\nlet current = theTetrominoes[random][currentRotation]\n\n// Draw the Tetromino\nfunction draw() {\n current.forEach(index => {\n squares[currentPosition + index].classList.add('tetromino')\n })\n}\n\n// Undraw the Tetromino\nfunction undraw() {\n current.forEach(index => {\n squares[currentPosition + index].classList.remove('tetromino')\n })\n}\n\n// Move down function\nfunction moveDown() {\n undraw()\n currentPosition += width\n draw()\n freeze()\n}\n\n// Freeze function\nfunction freeze() {\n if(current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) {\n current.forEach(index => squares[currentPosition + index].classList.add('taken'))\n // Start a new tetromino falling\n random = nextRandom\n nextRandom = Math.floor(Math.random() * theTetrominoes.length)\n current = theTetrominoes[random][currentRotation]\n currentPosition = 4\n draw()\n displayShape()\n addScore()\n gameOver()\n }\n}\n\n// Move the tetromino left, unless it's at the edge or there's a blockage\nfunction moveLeft() {\n undraw()\n const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0)\n\n if(!isAtLeftEdge) currentPosition -= 1\n\n if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {\n currentPosition += 1\n }\n\n draw()\n}\n\n// Move the tetromino right, unless it's at the edge or there's a blockage\nfunction moveRight() {\n undraw()\n const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1)\n\n if(!isAtRightEdge) currentPosition += 1\n\n if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {\n currentPosition -= 1\n }\n\n draw()\n}\n\n// Rotate the tetromino\nfunction rotate() {\n undraw()\n currentRotation++\n if(currentRotation === current.length) { // if the current rotation gets to 4, go back to 0\n currentRotation = 0\n }\n current = theTetrominoes[random][currentRotation]\n draw()\n}\n\n// Show up-next tetromino in mini-grid display\nfunction displayShape() {\n // Remove any trace of a tetromino from the entire grid\n miniSquares.forEach(square => {\n square.classList.remove('tetromino')\n square.style.backgroundColor = ''\n })\n // Display the shape\n theTetrominoes[nextRandom].forEach(index => {\n miniSquares[index].classList.add('tetromino')\n miniSquares[index].style.backgroundColor = colors[nextRandom]\n })\n}\n\n// Add score\nfunction addScore() {\n for(let i = 0; i < 199; i += width) {\n const row = [i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8, i+9]\n\n if(row.every(index => squares[index].classList.contains('taken'))) {\n score += 10\n scoreDisplay.innerHTML = score\n row.forEach(index => {\n squares[index].classList.remove('taken')\n squares[index].classList.remove('tetromino')\n squares[index].style.backgroundColor = ''\n })\n const squaresRemoved = squares.splice(i, width)\n squares = squaresRemoved.concat(squares)\n squares.forEach(cell => grid.appendChild(cell))\n }\n }\n}\n\n// Game over\nfunction gameOver() {\n if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {\n scoreDisplay.innerHTML = 'end'\n clearInterval(timerId)\n }\n}\n\n// Assign functions to keyCodes\nfunction control(e) {\n if(e.keyCode === 37) {\n moveLeft()\n } else if(e.keyCode === 38) {\n rotate()\n } else if(e.keyCode === 39) {\n moveRight()\n } else if(e.keyCode === 40) {\n moveDown()\n }\n}\ndocument.addEventListener('keydown', control)\n\n// Start the game\nstartButton.addEventListener('click', () => {\n if(timerId) {\n clearInterval(timerId)\n timerId = null\n } else {\n draw()\n timerId = setInterval(moveDown, 1000)\n nextRandom = Math.floor(Math.random() * theTetrominoes.length)\n displayShape()\n }\n})\n\n---end---" + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 243, + "completion_tokens": 2436, + "total_tokens": 2679, + "prompt_cache_hit_tokens": 0, + "prompt_cache_miss_tokens": 243 + }, + "system_fingerprint": "fp_3a5770e1b4" +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..a781519 --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# tetrix2.scroll.pub +Website generated by DeepSeek from prompt: Please help me make a Tetris game website \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..8706bcd --- /dev/null +++ b/script.js @@ -0,0 +1,199 @@ +const grid = document.querySelector('.grid'); +const miniGrid = document.querySelector('.mini-grid'); +const scoreDisplay = document.querySelector('.score'); +const startButton = document.querySelector('.start-button'); +const width = 10; +let squares = Array.from(grid.querySelectorAll('div')); +let miniSquares = Array.from(miniGrid.querySelectorAll('div')); +let currentPosition = 4; +let currentRotation = 0; +let score = 0; +let timerId; +let nextRandom = 0; + +// The Tetrominoes +const lTetromino = [ + [1, width+1, width*2+1, 2], + [width, width+1, width+2, width*2+2], + [1, width+1, width*2+1, width*2], + [width, width*2, width*2+1, width*2+2] +] + +const zTetromino = [ + [0, width, width+1, width*2+1], + [width+1, width+2, width*2, width*2+1], + [0, width, width+1, width*2+1], + [width+1, width+2, width*2, width*2+1] +] + +const tTetromino = [ + [1, width, width+1, width+2], + [1, width+1, width+2, width*2+1], + [width, width+1, width+2, width*2+1], + [1, width, width+1, width*2+1] +] + +const oTetromino = [ + [0, 1, width, width+1], + [0, 1, width, width+1], + [0, 1, width, width+1], + [0, 1, width, width+1] +] + +const iTetromino = [ + [1, width+1, width*2+1, width*3+1], + [width, width+1, width+2, width+3], + [1, width+1, width*2+1, width*3+1], + [width, width+1, width+2, width+3] +] + +const theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino] + +let random = Math.floor(Math.random()*theTetrominoes.length) +let current = theTetrominoes[random][currentRotation] + +// Draw the Tetromino +function draw() { + current.forEach(index => { + squares[currentPosition + index].classList.add('tetromino') + }) +} + +// Undraw the Tetromino +function undraw() { + current.forEach(index => { + squares[currentPosition + index].classList.remove('tetromino') + }) +} + +// Move down function +function moveDown() { + undraw() + currentPosition += width + draw() + freeze() +} + +// Freeze function +function freeze() { + if(current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) { + current.forEach(index => squares[currentPosition + index].classList.add('taken')) + // Start a new tetromino falling + random = nextRandom + nextRandom = Math.floor(Math.random() * theTetrominoes.length) + current = theTetrominoes[random][currentRotation] + currentPosition = 4 + draw() + displayShape() + addScore() + gameOver() + } +} + +// Move the tetromino left, unless it's at the edge or there's a blockage +function moveLeft() { + undraw() + const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0) + + if(!isAtLeftEdge) currentPosition -= 1 + + if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) { + currentPosition += 1 + } + + draw() +} + +// Move the tetromino right, unless it's at the edge or there's a blockage +function moveRight() { + undraw() + const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1) + + if(!isAtRightEdge) currentPosition += 1 + + if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) { + currentPosition -= 1 + } + + draw() +} + +// Rotate the tetromino +function rotate() { + undraw() + currentRotation++ + if(currentRotation === current.length) { // if the current rotation gets to 4, go back to 0 + currentRotation = 0 + } + current = theTetrominoes[random][currentRotation] + draw() +} + +// Show up-next tetromino in mini-grid display +function displayShape() { + // Remove any trace of a tetromino from the entire grid + miniSquares.forEach(square => { + square.classList.remove('tetromino') + square.style.backgroundColor = '' + }) + // Display the shape + theTetrominoes[nextRandom].forEach(index => { + miniSquares[index].classList.add('tetromino') + miniSquares[index].style.backgroundColor = colors[nextRandom] + }) +} + +// Add score +function addScore() { + for(let i = 0; i < 199; i += width) { + const row = [i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8, i+9] + + if(row.every(index => squares[index].classList.contains('taken'))) { + score += 10 + scoreDisplay.innerHTML = score + row.forEach(index => { + squares[index].classList.remove('taken') + squares[index].classList.remove('tetromino') + squares[index].style.backgroundColor = '' + }) + const squaresRemoved = squares.splice(i, width) + squares = squaresRemoved.concat(squares) + squares.forEach(cell => grid.appendChild(cell)) + } + } +} + +// Game over +function gameOver() { + if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) { + scoreDisplay.innerHTML = 'end' + clearInterval(timerId) + } +} + +// Assign functions to keyCodes +function control(e) { + if(e.keyCode === 37) { + moveLeft() + } else if(e.keyCode === 38) { + rotate() + } else if(e.keyCode === 39) { + moveRight() + } else if(e.keyCode === 40) { + moveDown() + } +} +document.addEventListener('keydown', control) + +// Start the game +startButton.addEventListener('click', () => { + if(timerId) { + clearInterval(timerId) + timerId = null + } else { + draw() + timerId = setInterval(moveDown, 1000) + nextRandom = Math.floor(Math.random() * theTetrominoes.length) + displayShape() + } +}) diff --git a/style.css b/style.css new file mode 100644 index 0000000..eb377ac --- /dev/null +++ b/style.css @@ -0,0 +1,115 @@ +:root { + --primary: #2c3e50; + --secondary: #34495e; + --accent: #e74c3c; + --text: #ecf0f1; + --grid-color: #7f8c8d; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Arial', sans-serif; + background: var(--primary); + color: var(--text); + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + padding: 2rem; +} + +header { + text-align: center; + margin-bottom: 2rem; +} + +h1 { + font-size: 3rem; + color: var(--accent); + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.game-container { + display: flex; + gap: 2rem; + background: var(--secondary); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 0 20px rgba(0,0,0,0.3); +} + +.grid, .mini-grid { + display: grid; + background: var(--primary); + border: 2px solid var(--grid-color); +} + +.grid { + grid-template-rows: repeat(20, 1fr); + grid-template-columns: repeat(10, 1fr); + width: 300px; + height: 600px; +} + +.mini-grid { + grid-template-rows: repeat(4, 1fr); + grid-template-columns: repeat(4, 1fr); + width: 120px; + height: 120px; + margin-top: 1rem; +} + +.sidebar { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.score-display { + text-align: center; +} + +.score { + font-size: 2rem; + font-weight: bold; + color: var(--accent); +} + +.start-button { + padding: 1rem 2rem; + background: var(--accent); + color: var(--text); + border: none; + border-radius: 0.5rem; + cursor: pointer; + font-size: 1.2rem; + transition: all 0.3s ease; +} + +.start-button:hover { + transform: scale(1.05); + box-shadow: 0 0 10px rgba(231, 76, 60, 0.5); +} + +footer { + margin-top: 2rem; + text-align: center; + color: var(--grid-color); +} + +@media (max-width: 768px) { + .game-container { + flex-direction: column; + align-items: center; + } + + .grid { + width: 240px; + height: 480px; + } +}