讨论

互动数独游戏构建器

来自 Wikiprompt,自由的提示词百科全书

Fatih Kadir Akın

2025年12月11日

互动数独游戏构建器 一个全面的提示,用于开发一款功能齐全的数独游戏,包含难度级别、提示、笔记、计时器、保存、统计、打印和无障碍功能。

提示词内容收藏

🌐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>♾️ Sudoku · interactive</title> <style> * { box-sizing: border-box; font-family: system-ui, 'Segoe UI', Roboto, sans-serif; } body { background: linear-gradient(145deg, #f5f7fb 0%, #e9edf5 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; margin: 0; padding: 16px; } .game-container { max-width: 1000px; width: 100%; background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(8px); border-radius: 40px; padding: 24px 28px; box-shadow: 0 20px 40px rgba(0, 10, 30, 0.2); border: 1px solid rgba(255, 255, 255, 0.6); } .header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; margin-bottom: 20px; gap: 12px; } .title { font-size: 2rem; font-weight: 700; letter-spacing: 2px; background: linear-gradient(135deg, #1e3c72, #2a5298); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin: 0; } .controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } button, select { background: white; border: 1px solid #b0c4de; border-radius: 40px; padding: 8px 16px; font-weight: 500; font-size: 0.9rem; cursor: pointer; transition: all 0.15s; box-shadow: 0 2px 4px rgba(0,0,0,0.02); display: inline-flex; align-items: center; gap: 6px; } button:hover, select:hover { background: #eef3fc; border-color: #2a5298; transform: scale(1.02); } button:active { transform: scale(0.98); } .difficulty-select { background: #f0f4fa; font-weight: 600; } .board-section { display: flex; flex-direction: row; flex-wrap: wrap; gap: 24px; justify-content: center; } .sudoku-board { display: grid; grid-template-columns: repeat(9, 1fr); background: #1e3c72; border: 3px solid #1e3c72; border-radius: 12px; width: min(70vw, 480px); aspect-ratio: 1/1; box-shadow: 0 8px 20px rgba(0,0,0,0.2); overflow: hidden; } .cell { background: white; border: 0.5px solid #a0b8d0; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; font-weight: 500; color: #0a1f44; cursor: default; position: relative; transition: background 0.1s; user-select: none; } .cell.given { background: #eaf0fa; font-weight: 700; color: #0a2a5e; } .cell.selected { background: #c7d9f0; box-shadow: inset 0 0 0 2px #2a5298; } .cell.related { background: #e2eaf8; } .cell.error { background: #ffe1e1; color: #b00020; } .cell.hint-highlight { background: #fdf3c0; } .cell.note-mode { font-size: 0.8rem; color: #2a5298; display: flex; flex-wrap: wrap; align-content: center; justify-content: center; gap: 2px; } .note-number { width: 8px; height: 8px; font-size: 0.65rem; display: inline-flex; align-items: center; justify-content: center; background: #f0f4ff; border-radius: 2px; margin: 1px; } .right-panel { flex: 1; min-width: 220px; display: flex; flex-direction: column; gap: 16px; } .timer-box { background: #ffffffd0; border-radius: 30px; padding: 12px 18px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 4px 8px rgba(0,0,0,0.05); border: 1px solid #c0d0e8; } .timer { font-size: 1.8rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 2px; background: #1e3c72; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .action-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .action-grid button { justify-content: center; } .stat-box { background: #ffffffd0; border-radius: 20px; padding: 12px 16px; border: 1px solid #c0d0e8; font-size: 0.9rem; } .stat-line { display: flex; justify-content: space-between; margin: 4px 0; } .save-slots { display: flex; gap: 6px; flex-wrap: wrap; } .slot-btn { background: #eef3fc; border-radius: 30px; padding: 6px 12px; font-size: 0.8rem; } .print-btn { background: #2a5298; color: white; border: none; } .print-btn:hover { background: #1e3c72; } .footer-note { margin-top: 12px; font-size: 0.8rem; color: #3a4a6a; text-align: center; } .key-hint { background: #eef3fc; border-radius: 20px; padding: 8px 12px; font-size: 0.8rem; color: #1e3c72; } @media (max-width: 700px) { .sudoku-board { width: 90vw; } } </style> </head> <body> <div class="game-container"> <div class="header"> <h1 class="title">♾️ SUDOKU</h1> <div class="controls"> <select id="difficultySelect" class="difficulty-select" aria-label="difficulty level"> <option value="easy">🌱 easy</option> <option value="medium" selected>🍂 medium</option> <option value="hard">🔥 hard</option> <option value="expert">💎 expert</option> </select> <button id="newGameBtn">✨ new</button> <button id="pauseBtn">⏸️ pause</button> <button id="hintBtn">💡 hint</button> <button id="noteToggleBtn" class="note-toggle">✏️ notes</button> </div> </div> <div class="board-section"> <div id="board" class="sudoku-board" role="grid" aria-label="sudoku board"></div> <div class="right-panel"> <div class="timer-box"> <span>⏱️</span> <span id="timerDisplay" class="timer">00:00</span> <button id="resetTimerBtn" title="reset timer">↺</button> </div> <div class="action-grid"> <button id="checkBtn">✔️ check</button> <button id="clearBtn">🧹 clear</button> <button id="saveBtn">💾 save</button> <button id="loadBtn">📂 load</button> <button id="printBtn" class="print-btn">🖨️ print</button> <button id="undoBtn">↩️ undo</button> </div> <div class="save-slots"> <button class="slot-btn" data-slot="1">slot 1</button> <button class="slot-btn" data-slot="2">slot 2</button> <button class="slot-btn" data-slot="3">slot 3</button> </div> <div class="stat-box"> <div class="stat-line"><span>🏆 wins</span><span id="winCount">0</span></div> <div class="stat-line"><span>⏱️ best time</span><span id="bestTime">--</span></div> <div class="stat-line"><span>📊 games</span><span id="gameCount">0</span></div> </div> <div class="key-hint"> ⌨️ 1-9 set · N notes · H hint · P pause · S save </div> </div> </div> <div class="footer-note">immediate error feedback · multi-level hints · notes · save/load</div> </div> <script> (function() { // ---------- core state ---------- let board = Array(9).fill().map(() => Array(9).fill(0)); let solution = Array(9).fill().map(() => Array(9).fill(0)); let givenMask = Array(9).fill().map(() => Array(9).fill(false)); let notes = Array(9).fill().map(() => Array(9).fill().map(() => [])); let selectedRow = -1, selectedCol = -1; let timerInterval = null; let seconds = 0; let paused = false; let noteMode = false; let difficulty = 'medium'; let gameOver = false; let history = []; // for undo (snapshot) let stats = { wins: 0, bestTime: null, games: 0 }; // DOM elements const boardEl = document.getElementById('board'); const timerDisplay = document.getElementById('timerDisplay'); const difficultySelect = document.getElementById('difficultySelect'); const winCountEl = document.getElementById('winCount'); const bestTimeEl = document.getElementById('bestTime'); const gameCountEl = document.getElementById('gameCount'); // ---------- helpers ---------- function formatTime(sec) { const m = Math.floor(sec / 60).toString().padStart(2, '0'); const s = (sec % 60).toString().padStart(2, '0'); return `${m}:${s}`; } function updateTimerDisplay() { timerDisplay.textContent = formatTime(seconds); } function startTimer() { if (timerInterval) clearInterval(timerInterval); timerInterval = setInterval(() => { if (!paused && !gameOver) { seconds++; updateTimerDisplay(); } }, 1000); } function stopTimer() { if (timerInterval) clearInterval(timerInterval); timerInterval = null; } // ---------- puzzle generation (solver + dig) ---------- function generateSolution() { const sol = Array(9).fill().map(() => Array(9).fill(0)); fillGrid(sol); return sol; } function fillGrid(grid) { const nums = [1,2,3,4,5,6,7,8,9]; for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (grid[r][c] === 0) { shuffle(nums); for (let n of nums) { if (isSafe(grid, r, c, n)) { grid[r][c] = n; if (isFull(grid) || fillGrid(grid)) return true; grid[r][c] = 0; } } return false; } } } return true; } function isSafe(grid, row, col, num) { for (let i = 0; i < 9; i++) { if (grid[row][i] === num || grid[i][col] === num) return false; } const br = Math.floor(row/3)*3, bc = Math.floor(col/3)*3; for (let r = br; r < br+3; r++) { for (let c = bc; c < bc+3; c++) { if (grid[r][c] === num) return false; } } return true; } function isFull(grid) { return grid.every(row => row.every(v => v !== 0)); } function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } } function generatePuzzle(diff) { const sol = generateSolution(); const puzzle = sol.map(row => [...row]); const cellsToRemove = { easy: 38, medium: 50, hard: 58, expert: 64 }[diff] || 50; let removed = 0; while (removed < cellsToRemove) { const r = Math.floor(Math.random() * 9); const c = Math.floor(Math.random() * 9); if (puzzle[r][c] !== 0) { puzzle[r][c] = 0; removed++; } } return { puzzle, solution: sol }; } // ---------- board rendering ---------- function renderBoard() { boardEl.innerHTML = ''; for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { const cell = document.createElement('div'); cell.className = 'cell'; if (givenMask[r][c]) cell.classList.add('given'); if (selectedRow === r && selectedCol === c) cell.classList.add('selected'); // related highlight if (selectedRow >= 0 && selectedCol >= 0 && (selectedRow === r || selectedCol === c || (Math.floor(selectedRow/3) === Math.floor(r/3) && Math.floor(selectedCol/3) === Math.floor(c/3)))) { if (!(selectedRow === r && selectedCol === c)) cell.classList.add('related'); } // error check (immediate feedback) if (board[r][c] !== 0 && !givenMask[r][c] && board[r][c] !== solution[r][c]) { cell.classList.add('error'); } // notes display if (board[r][c] === 0 && notes[r][c].length > 0) { cell.classList.add('note-mode'); notes[r][c].forEach(n => { const span = document.createElement('span'); span.className = 'note-number'; span.textContent = n; cell.appendChild(span); }); } else { cell.textContent = board[r][c] !== 0 ? board[r][c] : ''; } cell.dataset.row = r; cell.dataset.col = c; cell.addEventListener('click', () => { if (gameOver) return; selectedRow = r; selectedCol = c; renderBoard(); }); boardEl.appendChild(cell); } } } // ---------- game actions ---------- function newGame() { stopTimer(); seconds = 0; paused = false; gameOver = false; updateTimerDisplay(); difficulty = difficultySelect.value; const { puzzle, solution: sol } = generatePuzzle(difficulty); board = puzzle.map(row => [...row]); solution = sol.map(row => [...row]); givenMask = board.map(row => row.map(v => v !== 0)); notes = Array(9).fill().map(() => Array(9).fill().map(() => [])); selectedRow = -1; selectedCol = -1; history = []; stats.games++; gameCountEl.textContent = stats.games; renderBoard(); startTimer(); } function setCellValue(row, col, val) { if (gameOver || givenMask[row][col]) return; // snapshot for undo history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); if (history.length > 30) history.shift(); board[row][col] = val; if (val !== 0) notes[row][col] = []; // check win if (isBoardComplete()) { gameOver = true; stopTimer(); stats.wins++; winCountEl.textContent = stats.wins; if (stats.bestTime === null || seconds < stats.bestTime) { stats.bestTime = seconds; bestTimeEl.textContent = formatTime(seconds); } alert('🎉 You win!'); } renderBoard(); } function isBoardComplete() { for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (board[r][c] !== solution[r][c]) return false; } } return true; } // hint system (multi-level: fill cell, remove notes, highlight) function giveHint() { if (gameOver) return; // find first empty or wrong cell for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (board[r][c] !== solution[r][c]) { // if notes exist, remove wrong notes if (board[r][c] === 0 && notes[r][c].length > 0) { const correct = solution[r][c]; const filtered = notes[r][c].filter(n => n === correct); if (filtered.length === 0) { // set note to correct history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); notes[r][c] = [correct]; renderBoard(); return; } else { history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); notes[r][c] = [correct]; renderBoard(); return; } } else { // set value history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); board[r][c] = solution[r][c]; notes[r][c] = []; renderBoard(); return; } } } } } // undo function undo() { if (history.length === 0) return; const prev = history.pop(); board = prev.board; notes = prev.notes; renderBoard(); } // check errors (optional immediate feedback already on) function checkErrors() { renderBoard(); // just re-render to show errors } // clear user entries (not given) function clearUser() { history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (!givenMask[r][c]) { board[r][c] = 0; notes[r][c] = []; } } } renderBoard(); } // save/load slots function saveToSlot(slot) { const data = { board, solution, givenMask, notes, seconds, difficulty, stats }; localStorage.setItem(`sudoku_slot_${slot}`, JSON.stringify(data)); alert(`saved to slot ${slot}`); } function loadFromSlot(slot) { const raw = localStorage.getItem(`sudoku_slot_${slot}`); if (!raw) { alert('empty slot'); return; } const data = JSON.parse(raw); board = data.board; solution = data.solution; givenMask = data.givenMask; notes = data.notes; seconds = data.seconds; difficulty = data.difficulty; if (data.stats) stats = data.stats; gameOver = false; paused = false; stopTimer(); startTimer(); updateTimerDisplay(); winCountEl.textContent = stats.wins; bestTimeEl.textContent = stats.bestTime !== null ? formatTime(stats.bestTime) : '--'; gameCountEl.textContent = stats.games; renderBoard(); } // print (window.print) function printPuzzle() { window.print(); } // ---------- event listeners ---------- document.getElementById('newGameBtn').addEventListener('click', newGame); document.getElementById('pauseBtn').addEventListener('click', () => { paused = !paused; document.getElementById('pauseBtn').textContent = paused ? '▶️ resume' : '⏸️ pause'; }); document.getElementById('hintBtn').addEventListener('click', giveHint); document.getElementById('noteToggleBtn').addEventListener('click', () => { noteMode = !noteMode; document.getElementById('noteToggleBtn').style.background = noteMode ? '#c7d9f0' : 'white'; }); document.getElementById('checkBtn').addEventListener('click', checkErrors); document.getElementById('clearBtn').addEventListener('click', clearUser); document.getElementById('undoBtn').addEventListener('click', undo); document.getElementById('saveBtn').addEventListener('click', () => saveToSlot(1)); document.getElementById('loadBtn').addEventListener('click', () => loadFromSlot(1)); document.getElementById('printBtn').addEventListener('click', printPuzzle); document.getElementById('resetTimerBtn').addEventListener('click', () => { seconds = 0; updateTimerDisplay(); }); // slot buttons document.querySelectorAll('.slot-btn').forEach(btn => { btn.addEventListener('click', (e) => { const slot = e.target.dataset.slot; if (e.shiftKey) { // shift+click = save saveToSlot(slot); } else { loadFromSlot(slot); } }); }); // keyboard controls document.addEventListener('keydown', (e) => { if (e.key >= '1' && e.key <= '9') { const num = parseInt(e.key); if (selectedRow >= 0 && selectedCol >= 0 && !givenMask[selectedRow][selectedCol]) { if (noteMode) { history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); const idx = notes[selectedRow][selectedCol].indexOf(num); if (idx > -1) notes[selectedRow][selectedCol].splice(idx, 1); else notes[selectedRow][selectedCol].push(num); renderBoard(); } else { setCellValue(selectedRow, selectedCol, num); } } } else if (e.key === 'n' || e.key === 'N') { document.getElementById('noteToggleBtn').click(); } else if (e.key === 'h' || e.key === 'H') { giveHint(); } else if (e.key === 'p' || e.key === 'P') { document.getElementById('pauseBtn').click(); } else if (e.key === 's' || e.key === 'S') { saveToSlot(1); } else if (e.key === 'Backspace' || e.key === 'Delete') { if (selectedRow >= 0 && selectedCol >= 0 && !givenMask[selectedRow][selectedCol]) { history.push({ board: board.map(r => [...r]), notes: notes.map(r => r.map(n => [...n])) }); board[selectedRow][selectedCol] = 0; notes[selectedRow][selectedCol] = []; renderBoard(); } } }); // init newGame(); })(); </script> </body> </html>

登录以查看完整提示词

继续使用:

登录即表示你同意我们的 使用条款 和 隐私政策

用法

此提示词专为 coding 设计。复制上方内容并粘贴到你常用的 AI 工具中。

为获得最佳效果,可将占位符(方括号或大写字母标示)替换为你的具体需求。

参考资料

分类:coding| prompts.chat| sudoku| html5

讨论