數獨遊戲的解法到App的實現

2021-09-27 07:49:25 字數 2099 閱讀 5383

在leetcode上偶然刷到乙個解數獨的題目:

編寫乙個程式,通過已填充的空格來解決數獨問題。

乙個數獨的解法需遵循如下規則:

note:

這個題目很是有趣,解決了數獨算不出來的難題。

首先想到的是暴力列舉了,也就是對每個空格進行列舉,回溯法。

public

void

solvesudoku

(char

board)}}

//開始回溯

bacttrack

(board, rows, cols, boxes,0,

0);}

private

boolean

bacttrack

(char

board,

boolean

rows,

boolean

cols,

boolean

boxes,

int i,

int j)

}//如果是 空 格

if(board[i]

[j]==

'.')

//如果下一步無解,回溯

board[i]

[j]=

'.';

rows[i]

[num]

=false

; cols[j]

[num]

=false

; boxes[boxindex]

[num]

=false;}

}}else

//前面都沒找到解

return

false

;}

以上的演算法便是根據給出的數獨得到數獨的解。

然後突然想試試這個演算法,但是沒有生成數獨的演算法,找到了數獨-- 乙個高效率生成數獨的演算法部落格裡的方法,也驗證了下,能達到隨機生成的效果(雖然都是偽隨機)

//seedarray是用來生成數獨的種子陣列

private

void

creatsudokuarray

(int

seedarray)

randomnum = random.

nextint(9

)+1;

}}/* 通過一維陣列和原陣列生成隨機的數獨矩陣

遍歷二維陣列裡的資料,在一維陣列找到當前值的位置,並把一維陣列

當前位置加一處位置的值賦到當前二維陣列中。目的就是將一維陣列為

依據,按照隨機產生的順序,將這個9個資料進行迴圈交換,生成乙個隨

機的數獨矩陣。

*/for(

int i =

0; i <

9; i++)}

//將生成的重新賦值給需要的,seedarray不做改變

board[i]

[j]= seedarray[i]

[j];}}

}

好了,有了生成數獨的演算法後,但是這只是個數獨終盤,還需要挖空,最後利用隨機數完成了不同等級的挖空

/**

* 給指定數獨終盤挖空,利用隨機數,隨機次數為level,也就是對每行挖level次空

* 難度對應easy--5, middle--7, hard--9

* 每次挖空後判斷是否有解,若無解重新挖空

* @param level 挖空等級

*/public

void

resetsudoku

(int level)

creatsudokuarray

(seedarray)

; random random =

newrandom()

;for

(int i =

0; i <

9; i++)}

if(!solvesudoku

(copies)

)}

好了,有了這一系列的演算法後,便可以自己寫乙個數獨遊戲了。

示意如下:

github:diyviewpracticedemo

數獨遊戲的AI解法

因為解的過程沒有全域性狀態這種概念,所以不方便使用著名的h d模板來解。其實因為格仔的數量很少,只要做簡章的優化就完全不存在問題。即使用窮舉法,也能很快算出答案。某人 不要小看窮舉法!下次準備考慮生成遊戲的演算法,難度應該較高。console工程的 sudoku.cpp 定義控制台應用程式的入口點。...

數獨解法 C 實現

include using namespace std 構造完成標誌 bool sign false 建立數獨矩陣 int num 9 9 函式宣告 void input void output bool check int n,int key int dfs int n 主函式 int main ...

數獨遊戲的深度優先遍歷解法

數獨簡介 數獨 是一種邏輯性的數字填充遊戲,玩家須以數字填進每一格,而每行 每列和每個宮 即3x3的大格 有齊1至9所有數字。遊戲設計者會提供一部份的數字,使謎題只有乙個答案。乙個已解答的數獨其實是一種多了宮的限制的拉丁方陣,因為同乙個數字不可能在同一行 列或宮中出現多於一次。深度優先遍歷演算法 學...