commit ba84a52791cf144eaf5d2b965165c80d4f668754
Author: root <root@hub.scroll.pub> Date: 2024-12-28 20:47:04 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..cfe4136 --- /dev/null +++ b/body.html @@ -0,0 +1,16 @@ +<header> + <h1>Classic 9-Grid Puzzle</h1> + <button id="reset-btn">Reset Puzzle</button> +</header> +<main> + <div id="puzzle-container"> + <!-- Puzzle tiles will be dynamically generated here --> + </div> + <div id="message" class="hidden"> + <h2>Congratulations! 🎉</h2> + <p>You solved the puzzle!</p> + </div> +</main> +<footer> + <p>Challenge your mind with this classic puzzle game.</p> +</footer> \ No newline at end of file diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..1bad901 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://puzzle9.scroll.pub +metaTags +editButton /edit.html +title Classic 9-Grid Puzzle Game +style.css +body.html +script.js \ No newline at end of file diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..778d316 --- /dev/null +++ b/prompt.json @@ -0,0 +1,25 @@ +{ + "id": "5fa30ba4-76a2-43a8-8c83-46bacf2460ff", + "object": "chat.completion", + "created": 1735418803, + "model": "deepseek-chat", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "---domain---\npuzzle9.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://puzzle9.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Classic 9-Grid Puzzle Game\nstyle.css\nbody.html\nscript.js\n---body.html---\n<header>\n <h1>Classic 9-Grid Puzzle</h1>\n <button id=\"reset-btn\">Reset Puzzle</button>\n</header>\n<main>\n <div id=\"puzzle-container\">\n <!-- Puzzle tiles will be dynamically generated here -->\n </div>\n <div id=\"message\" class=\"hidden\">\n <h2>Congratulations! 🎉</h2>\n <p>You solved the puzzle!</p>\n </div>\n</main>\n<footer>\n <p>Challenge your mind with this classic puzzle game.</p>\n</footer>\n---style.css---\n:root {\n --tile-size: 100px;\n --gap: 5px;\n --border-radius: 15px;\n --transition-speed: 0.3s;\n}\n\nbody {\n font-family: 'Segoe UI', system-ui, sans-serif;\n background: linear-gradient(135deg, #f5f7fa, #c3cfe2);\n color: #333;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 20px;\n}\n\nheader {\n text-align: center;\n margin-bottom: 2rem;\n}\n\nh1 {\n font-size: 2.5rem;\n margin: 0;\n color: #2c3e50;\n}\n\n#puzzle-container {\n display: grid;\n grid-template-columns: repeat(3, var(--tile-size));\n grid-template-rows: repeat(3, var(--tile-size));\n gap: var(--gap);\n background: #fff;\n padding: var(--gap);\n border-radius: var(--border-radius);\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n}\n\n.tile {\n background: #3498db;\n border-radius: calc(var(--border-radius) - 2px);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n font-weight: bold;\n color: white;\n cursor: pointer;\n transition: all var(--transition-speed) ease;\n user-select: none;\n}\n\n.tile.empty {\n background: transparent;\n cursor: default;\n}\n\n.tile:not(.empty):hover {\n transform: scale(1.05);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n}\n\n#reset-btn {\n background: #2ecc71;\n color: white;\n border: none;\n padding: 10px 20px;\n border-radius: 5px;\n cursor: pointer;\n font-size: 1rem;\n margin-top: 1rem;\n transition: background 0.3s ease;\n}\n\n#reset-btn:hover {\n background: #27ae60;\n}\n\n#message {\n text-align: center;\n margin-top: 2rem;\n opacity: 0;\n transition: opacity var(--transition-speed) ease;\n}\n\n#message.visible {\n opacity: 1;\n}\n\n@media (max-width: 480px) {\n :root {\n --tile-size: 80px;\n }\n \n h1 {\n font-size: 2rem;\n }\n}\n---script.js---\nconst puzzleContainer = document.getElementById('puzzle-container');\nconst resetBtn = document.getElementById('reset-btn');\nconst message = document.getElementById('message');\nlet tiles = [];\nlet emptyIndex = 8;\n\nfunction createTiles() {\n for (let i = 0; i < 8; i++) {\n const tile = document.createElement('div');\n tile.classList.add('tile');\n tile.textContent = i + 1;\n tile.dataset.index = i;\n tile.addEventListener('click', moveTile);\n tiles.push(tile);\n }\n const emptyTile = document.createElement('div');\n emptyTile.classList.add('tile', 'empty');\n emptyTile.dataset.index = 8;\n tiles.push(emptyTile);\n puzzleContainer.append(...tiles);\n}\n\nfunction shuffleTiles() {\n do {\n tiles.sort(() => Math.random() - 0.5);\n tiles.forEach((tile, index) => {\n tile.dataset.index = index;\n puzzleContainer.append(tile);\n });\n emptyIndex = tiles.findIndex(tile => tile.classList.contains('empty'));\n } while (!isSolvable());\n}\n\nfunction isSolvable() {\n let inversions = 0;\n const tileNumbers = tiles\n .filter(tile => !tile.classList.contains('empty'))\n .map(tile => Number(tile.textContent));\n\n for (let i = 0; i < tileNumbers.length; i++) {\n for (let j = i + 1; j < tileNumbers.length; j++) {\n if (tileNumbers[i] > tileNumbers[j]) inversions++;\n }\n }\n\n return inversions % 2 === 0;\n}\n\nfunction moveTile(e) {\n const clickedIndex = Number(e.target.dataset.index);\n if (isAdjacent(clickedIndex, emptyIndex)) {\n swapTiles(clickedIndex, emptyIndex);\n emptyIndex = clickedIndex;\n if (isSolved()) {\n showMessage();\n tiles.forEach(tile => tile.removeEventListener('click', moveTile));\n }\n }\n}\n\nfunction isAdjacent(index1, index2) {\n const row1 = Math.floor(index1 / 3);\n const col1 = index1 % 3;\n const row2 = Math.floor(index2 / 3);\n const col2 = index2 % 3;\n return Math.abs(row1 - row2) + Math.abs(col1 - col2) === 1;\n}\n\nfunction swapTiles(index1, index2) {\n [tiles[index1].dataset.index, tiles[index2].dataset.index] = [\n tiles[index2].dataset.index,\n tiles[index1].dataset.index\n ];\n puzzleContainer.insertBefore(tiles[index1], tiles[index2]);\n}\n\nfunction isSolved() {\n return tiles.every((tile, index) => {\n if (tile.classList.contains('empty')) return index === 8;\n return Number(tile.textContent) === index + 1;\n });\n}\n\nfunction showMessage() {\n message.classList.add('visible');\n}\n\nfunction resetGame() {\n tiles.forEach(tile => tile.addEventListener('click', moveTile));\n message.classList.remove('visible');\n shuffleTiles();\n}\n\nfunction init() {\n createTiles();\n shuffleTiles();\n resetBtn.addEventListener('click', resetGame);\n}\n\ninit();\n---end---" + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 530, + "completion_tokens": 1510, + "total_tokens": 2040, + "prompt_cache_hit_tokens": 0, + "prompt_cache_miss_tokens": 530 + }, + "system_fingerprint": "fp_f1afce2943" +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..1d6840d --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# puzzle9.scroll.pub +Website generated by DeepSeek from prompt: 设计一个经典的9格拼图游戏,使用HTML、CSS和JavaScript实现。游戏应包含以下功能: 1. **游戏界面**: - 使用CSS Grid布局创建一个3x3的拼图容器。 - 每个拼图块是一个带有背景颜色和前景数字的div元素。 - 拼图块应具有圆角,并且整个容器也应有圆角边框。 2. **游戏功能**: - **随机打乱拼图**: 游戏开始时,拼图块应随机打乱,留一个空位供移动。 - **块的移动逻辑**: 点击可移动的拼图块(与空位相邻的块)时,块应与空位交换位置。 - **胜利条件检测**: 当拼图块按顺序排列时,显示胜利提示信息。 - **重置游戏按钮**: 点击按钮时,重新随机打乱拼图。 3. **视觉增强**: - 使用HSL颜色值为拼图块生成渐变效果。 - 提供多种颜色主题,随机选择一种主题应用于每局游戏。 - 确保拼图块在移动时有平滑的过渡效果。 4. **用户体验**: - 确保拼图块不可被选中或拖动。 - 在胜利时,显示一个庆祝消息,并禁用块的进一步移动。 请生成完整的HTML代码,包括必要的CSS样式和JavaScript逻辑。 \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..a6df907 --- /dev/null +++ b/script.js @@ -0,0 +1,100 @@ +const puzzleContainer = document.getElementById('puzzle-container'); +const resetBtn = document.getElementById('reset-btn'); +const message = document.getElementById('message'); +let tiles = []; +let emptyIndex = 8; + +function createTiles() { + for (let i = 0; i < 8; i++) { + const tile = document.createElement('div'); + tile.classList.add('tile'); + tile.textContent = i + 1; + tile.dataset.index = i; + tile.addEventListener('click', moveTile); + tiles.push(tile); + } + const emptyTile = document.createElement('div'); + emptyTile.classList.add('tile', 'empty'); + emptyTile.dataset.index = 8; + tiles.push(emptyTile); + puzzleContainer.append(...tiles); +} + +function shuffleTiles() { + do { + tiles.sort(() => Math.random() - 0.5); + tiles.forEach((tile, index) => { + tile.dataset.index = index; + puzzleContainer.append(tile); + }); + emptyIndex = tiles.findIndex(tile => tile.classList.contains('empty')); + } while (!isSolvable()); +} + +function isSolvable() { + let inversions = 0; + const tileNumbers = tiles + .filter(tile => !tile.classList.contains('empty')) + .map(tile => Number(tile.textContent)); + + for (let i = 0; i < tileNumbers.length; i++) { + for (let j = i + 1; j < tileNumbers.length; j++) { + if (tileNumbers[i] > tileNumbers[j]) inversions++; + } + } + + return inversions % 2 === 0; +} + +function moveTile(e) { + const clickedIndex = Number(e.target.dataset.index); + if (isAdjacent(clickedIndex, emptyIndex)) { + swapTiles(clickedIndex, emptyIndex); + emptyIndex = clickedIndex; + if (isSolved()) { + showMessage(); + tiles.forEach(tile => tile.removeEventListener('click', moveTile)); + } + } +} + +function isAdjacent(index1, index2) { + const row1 = Math.floor(index1 / 3); + const col1 = index1 % 3; + const row2 = Math.floor(index2 / 3); + const col2 = index2 % 3; + return Math.abs(row1 - row2) + Math.abs(col1 - col2) === 1; +} + +function swapTiles(index1, index2) { + [tiles[index1].dataset.index, tiles[index2].dataset.index] = [ + tiles[index2].dataset.index, + tiles[index1].dataset.index + ]; + puzzleContainer.insertBefore(tiles[index1], tiles[index2]); +} + +function isSolved() { + return tiles.every((tile, index) => { + if (tile.classList.contains('empty')) return index === 8; + return Number(tile.textContent) === index + 1; + }); +} + +function showMessage() { + message.classList.add('visible'); +} + +function resetGame() { + tiles.forEach(tile => tile.addEventListener('click', moveTile)); + message.classList.remove('visible'); + shuffleTiles(); +} + +function init() { + createTiles(); + shuffleTiles(); + resetBtn.addEventListener('click', resetGame); +} + +init(); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..de5b71a --- /dev/null +++ b/style.css @@ -0,0 +1,102 @@ +:root { + --tile-size: 100px; + --gap: 5px; + --border-radius: 15px; + --transition-speed: 0.3s; +} + +body { + font-family: 'Segoe UI', system-ui, sans-serif; + background: linear-gradient(135deg, #f5f7fa, #c3cfe2); + color: #333; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin: 0; + padding: 20px; +} + +header { + text-align: center; + margin-bottom: 2rem; +} + +h1 { + font-size: 2.5rem; + margin: 0; + color: #2c3e50; +} + +#puzzle-container { + display: grid; + grid-template-columns: repeat(3, var(--tile-size)); + grid-template-rows: repeat(3, var(--tile-size)); + gap: var(--gap); + background: #fff; + padding: var(--gap); + border-radius: var(--border-radius); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); +} + +.tile { + background: #3498db; + border-radius: calc(var(--border-radius) - 2px); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + font-weight: bold; + color: white; + cursor: pointer; + transition: all var(--transition-speed) ease; + user-select: none; +} + +.tile.empty { + background: transparent; + cursor: default; +} + +.tile:not(.empty):hover { + transform: scale(1.05); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); +} + +#reset-btn { + background: #2ecc71; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 1rem; + margin-top: 1rem; + transition: background 0.3s ease; +} + +#reset-btn:hover { + background: #27ae60; +} + +#message { + text-align: center; + margin-top: 2rem; + opacity: 0; + transition: opacity var(--transition-speed) ease; +} + +#message.visible { + opacity: 1; +} + +@media (max-width: 480px) { + :root { + --tile-size: 80px; + } + + h1 { + font-size: 2rem; + } +} \ No newline at end of file