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