cari

Rumah  >  Soal Jawab  >  teks badan

Masalah sudoku skrip taip menunjukkan papan yang terisi separa

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粉135799949P粉135799949444 hari yang lalu500

membalas semua(1)saya akan balas

  • P粉638343995

    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:

    • Mencapai pengunduran yang betul, iaitu membatalkan langkah yang tidak berjaya
    • Menyebabkan fungsi mengembalikan nilai Boolean (menunjukkan kejayaan/kegagalan) - tidak perlu kembali puzzleArray kerana tatasusunan diubah suai di tempatnya, jadi pemanggil boleh mengakses perubahan ini.
      • Ini juga bermakna NEW_BOARD = fillBoard(BLANK_BOARD);的副作用是NEW_BOARDBLANK_BOARDmerujuk papan Sudoku yang sama, dan ia tidak lagi kosong (jadi nama itu mengelirukan).
    • Pecah/kembali ke gelung pada kejayaan.

    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做一些操作 ...

    balas
    0
  • Batalbalas