Rumah > Soal Jawab > teks badan
Saya telah berjaya menukar penjana Sudoku js kepada penjana ts untuk latihan Satu-satunya masalah ialah bagaimana untuk menjadikannya hanya mengeluarkan papan Sudoku yang lengkap. Kini, ia mengeluarkan tanpa mengira sama ada cakera itu lengkap atau tidak, dan saya perlu menyegarkan semula sehingga cakera yang betul muncul.
Saya tidak pasti cara menulis fungsi berikut supaya ia hanya mengeluarkan cakera lengkap:
function fillBoard(puzzleArray: number[][]): number[][] { if (nextEmptyCell(puzzleArray).colIndex === -1) return puzzleArray; let emptyCell = nextEmptyCell(puzzleArray); for (var num in shuffle(numArray)) { if (safeToPlace(puzzleArray, emptyCell, numArray[num])) { puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num]; fillBoard(puzzleArray); } } return puzzleArray; }
Ini semua kod saya:
import { Box } from "./Box"; export function Board() { let BLANK_BOARD = [ [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ]; let NEW_BOARD = [ [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ]; let counter: number = 0; let check: number[]; const numArray: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; function rowSafe( puzzleArray: number[][], emptyCell: { rowIndex: number; colIndex: number }, num: number ): boolean { return puzzleArray[emptyCell.rowIndex].indexOf(num) == -1; } function colSafe( puzzleArray: number[][], emptyCell: { rowIndex: number; colIndex: number }, num: number ): boolean { let test = puzzleArray.flat(); for (let i = emptyCell.colIndex; i < test.length; i += 9) { if (test[i] === num) { return false; } } return true; } function regionSafe( puzzleArray: number[][], emptyCell: { rowIndex: number; colIndex: number }, num: number ): boolean { const rowStart: number = emptyCell.rowIndex - (emptyCell.rowIndex % 3); const colStart: number = emptyCell.colIndex - (emptyCell.colIndex % 3); for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (puzzleArray[rowStart + i][colStart + j] === num) { return false; } } } return true; } console.log(rowSafe(BLANK_BOARD, { rowIndex: 4, colIndex: 6 }, 5)); console.log(colSafe(BLANK_BOARD, { rowIndex: 2, colIndex: 3 }, 4)); console.log(regionSafe(BLANK_BOARD, { rowIndex: 5, colIndex: 6 }, 5)); function safeToPlace( puzzleArray: number[][], emptyCell: { rowIndex: number; colIndex: number }, num: number ): boolean { return ( regionSafe(puzzleArray, emptyCell, num) && rowSafe(puzzleArray, emptyCell, num) && colSafe(puzzleArray, emptyCell, num) ); } console.log(safeToPlace(BLANK_BOARD, { rowIndex: 5, colIndex: 6 }, 5)); function nextEmptyCell(puzzleArray: number[][]): { colIndex: number; rowIndex: number; } { let emptyCell = { rowIndex: -1, colIndex: -1 }; for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { if (puzzleArray[i][j] === 0) { return { rowIndex: i, colIndex: j }; } } } return emptyCell; } function shuffle(array: number[]): number[] { // using Array sort and Math.random let shuffledArr = array.sort(() => 0.5 - Math.random()); return shuffledArr; } function fillBoard(puzzleArray: number[][]): number[][] { if (nextEmptyCell(puzzleArray).colIndex === -1) return puzzleArray; let emptyCell = nextEmptyCell(puzzleArray); for (var num in shuffle(numArray)) { if (safeToPlace(puzzleArray, emptyCell, numArray[num])) { puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num]; fillBoard(puzzleArray); } else { puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = 0; } } return puzzleArray; } console.log(nextEmptyCell(BLANK_BOARD)); NEW_BOARD = fillBoard(BLANK_BOARD); function fullBoard(puzzleArray: number[][]): boolean { return puzzleArray.every((row) => row.every((col) => col !== 0)); } return ( <div style={{ height: "450px", width: "450px", display: "inline-grid", gap: "10px", gridTemplateColumns: "repeat(9,50px)", gridTemplateRows: "repeat(9,50px)", position: "absolute", top: "30px", left: "0px", right: "0px", marginLeft: "auto", marginRight: "auto", }} > {NEW_BOARD.flat().map((item) => ( <Box i={item} /> ))} </div> ); }
P粉6383439952023-09-08 17:29:57
Apabila didapati nombor yang sah tidak boleh ditambah dalam sel kosong, fungsi ini akan mengembalikan papan Sudoku yang tidak lengkap.
Untuk menyelesaikan masalah ini, fungsi anda hendaklah:
puzzleArray
kerana tatasusunan diubah suai di tempatnya, jadi pemanggil boleh mengakses perubahan ini.
NEW_BOARD = fillBoard(BLANK_BOARD);
的副作用是NEW_BOARD
和BLANK_BOARD
merujuk papan Sudoku yang sama, dan ia tidak lagi kosong (jadi nama itu mengelirukan). Berikut ialah pelaksanaan yang diubah suai:
function fillBoard(puzzleArray: number[][]): boolean { if (nextEmptyCell(puzzleArray).colIndex === -1) return true; // 布尔值 let emptyCell = nextEmptyCell(puzzleArray); for (var num in shuffle(numArray)) { if (safeToPlace(puzzleArray, emptyCell, numArray[num])) { puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num]; if fillBoard(puzzleArray) return true; // 成功时退出 } } puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = 0; // 撤销 return false; // 布尔值 - 没有成功 }
Pemanggil harus menyemak nilai pulangan, tetapi jika anda bermula dengan batu tulis kosong, anda dijamin mendapat true
sebagai nilai pulangan. Jadi anda boleh melakukan ini:
const puzzleArray = BLANK_BOARD.map(row => [...row]); // 深拷贝 const success = fillBoard(puzzleArray); // 返回一个布尔值 // ... 对puzzleArray做一些操作 ...