解决一个数独游戏

C++ - solve a sudoku game

本文关键字:游戏 一个 解决      更新时间:2023-10-16

我是c++的新手,必须做一个家庭作业(数独)。我被一个问题卡住了。

问题是实现一个搜索函数来解决数独。

指令:为了找到一个解决方案,递归搜索使用如下。假设有a未分配的字段与数字(d1....dn) (n> 1)。然后我们首先尝试将字段分配给d1,执行传播,然后继续搜索递归。可能发生的情况是传播导致失败(一个字段变成空的)。在这种情况下,搜索失败,需要为其中一个尝试不同的数字的字段。由于搜索是递归的,因此最后考虑字段的下一个数字是尝试。如果没有一个数字指向一个解决方案,搜索再次失败。这Turn将导致尝试与前一个字段不同的数字,依此类推。

在将字段赋值给数字d之前它,你必须创建一个新的板是当前板(使用)的副本复制构造函数并使用new)从堆中分配板。只有然后对副本执行赋值。如果递归调用搜索返回不成功,可以为下一个数字创建一个新的板试过了。

我试过:

// Search for a solution, returns NULL if no solution found
Board* Board::search(void) {
    // create a copy of the cur. board
    Board *copyBoard = new Board(*this);
    Board b = *copyBoard;
    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){
              //  if the field has not been assigned, assign it with a digit 
            if(!b.fs[i][j].assigned()){
                digit d = 1;
                     // try another digit if failed to assign (1 to 9)
                while (d <=9 && b.assign(i, j, d) == false){
                        d++;

                      // if no digit matches, here is the problem, how to 
                      // get back to the previous field and try another digit?
                      // and return null if there's no pervious field 
                if(d == 10){
                      ...
                    return NULL;
                }
            }
        }
    }
    return copyBoard;
 }

另一个问题是在哪里使用递归调用?任何建议吗?谢谢!

完整的说明可以在这里找到:http://www.kth.se/polopoly_fs/1.136980!/Menu/general/column-content/attachment/2-2.pdf

代码:http://www.kth.se/polopoly_fs/1.136981 !/菜单/一般/列内容/附件/2 - 2. - zip

您的代码中没有递归。您不能只访问每个字段一次,然后尝试为其赋值。问题是,你可能能够将5赋值给字段(3,4),并且可能只有当你到达字段(6,4)时才发现(3,4)处不可能有5。最终你需要退出递归,直到你回到(3,4)并在那里尝试另一个值。

对于递归,您可能不使用嵌套的for循环访问字段,而是使用递归调用访问下一个字段。或者您设法到达最后一个字段,或者您尝试了所有可能性,然后离开函数返回到您访问过的前一个字段。


旁注:绝对不要为这个任务分配动态内存:

//Board *copyBoard = new Board(*this);
Board copyBoard(*this); //if you need a copy in the first place

基本上你可以尝试这样做(伪代码'ish)

bool searchSolution(Board board)
{
 Square sq = getEmptySquare(board)
 if(sq == null)
    return true; // no more empty squares means we solved the puzzle
 // otherwise brute force by trying all valid numbers
 foreach (valid nr for sq)
 {
    board.doMove(nr)
    // recurse
    if(searchSolution(board))
        return true
    board.undoMove(nr) // backtrack if no solution found
 }
 // if we reach this point, no valid solution was found and the puzzle is unsolvable
 return false;
}

getemptyssquare(…)函数可以返回一个随机的空正方形或剩余选项最少的正方形。使用后者将使算法收敛得更快。

相关文章: