簡單的回溯法生成數獨遊戲

2021-10-02 02:00:27 字數 4281 閱讀 4951

這是乙個課設的作業,對於理解回溯法很有用,所以把他碼住。好久沒敲這種**了,邊界居然調了半天,尷尬!

作業描述:寫個數獨遊戲,具有自動生成數獨的功能和人工設定初始盤的功能,並且具有ui介面。

作業分析:

任務一:對於自動生成數獨的功能,他的功能實現邏輯是:回溯生成乙個數獨,然後隨機性讓部分區域可視(對於玩家),當玩家選擇提交時,再判斷是否與生成的數獨一致。

**任務二:**對於人工設定初始盤的功能,他和上面的自動生成有一些不同,當玩家選擇手動生成數獨並提交給後台之後,後台通過回溯法對提交的陣列進行有解檢查,如果無解返回「設定失敗」,否則就找到所有的解,並儲存全部。當玩家提交answer時,匹配每一種解。

回溯邏輯:對於乙個用來儲存生成的陣列game,我們對其進行自上而下從左到右的填充,每次在當前位置(x,y)填充乙個數字時,對該數字進行合法判斷iscorrect(x,y),如果不合法,進行回溯;合法進行下一次填充。

注:回溯法一定注意迴圈的邏輯,以及對continue一定要有充分的了解,不清楚的建議改為break,單步除錯幾次。特別注意,j=j-2而不是j=j-1!!!

private static int game=new int [9][9];//儲存數獨		

private static int rannum= ;//隨機數生成陣列

private int generategame()

else

}//如果可以獲得數字,說明嘗試的次數並沒有用完

//對數字的合法性進行檢查

if(iscorrect(i,j))

else }}

return game;

}

1、自動生成隨機數函式getnum(int time)

對於乙個第一次,生成隨機數的情況來說(time=0),我們初始化陣列。

對於乙個進行第九次挑選隨機數的情況來說(time=9),我們已經沒有數可以供他使用,所以返回不存在。

當進行數字生成時,我們只要保證生成隨機數的下標是在max(未被使用的數字的下標),就可以實現,千萬別忘了把已經使用過的數字和末位交換。

注:這個自己一定要寫一下,我錯了好幾次!!

//生成隨機數獨

private

intgetnum

(int time)

}// 第10次填充,表明該位置已經卡住,則返回0,由主程式處理退回

if(time ==9)

// 不是第一次填充

// 生成隨機數字,該數字是陣列的下標,取陣列num中該下標對應的數字為隨機數字

// int rannum = (int) (math.random() * (9 - time));//j2se

int num=r.

nextint(9

- time)

;//j2me

// 把數字放置在陣列倒數第time個位置,

int temp = rannum[

8- time]

; rannum[

8- time]

= rannum[num]

; rannum[num]

= temp;

// 返回數字

return rannum[

8-time]

;}

2.合法性判斷(一定不要越界)

注:最好寫個邊界判斷函式,我寫**時候越界了,沒有輸出就狠煩。

private

boolean

iscorrect

(int i,

int j)

else

}//檢查3*3是否有重複

private

boolean

checkbox

(int i,

int j)

for(

int n=m+

1;n<

9;n++)}

}// todo auto-generated method stub

return

true;}

//檢查每行是否有重複

private

boolean

checkline

(int i)

}return

true;}

//檢查每列是否有重複

private

boolean

checkcol

(int j)

}return

true

;}

public

static

void

main

(string[

] args)

int[

] game=

newint[9

][9]

; game=sd.

generategame()

;for

(int i=

0;i<

9;i++

) system.out.

println()

;}}

更新:

package leetcode;

public

class

code36,,

,,,,

,,};

code36.

isvalidsudoku

(board);}

public

boolean

isvalidsudoku

(string[

] board)

else}}

//輸出map

system.out.

println

("map");

for(

int[

] ints : map)

system.out.

println()

;}//dfs搜尋,從0,0開始搜尋,並輸出結果陣列,count作為結束標註

findanswer

(map,result,count)

; system.out.

println

("是否能成功到達"

+isarrive)

;return

false;}

private

boolean

findanswer

(int

map,

int[

] result,

int count)

private

void

dfs(

int[

] map,

int[

] result,

int count,

int i,

int j)

} isarrive++

;return;}

if(result[i]

[j]==2)

else

}else

if(result[i]

[j]==0)

else

// result[i][j]=0;

// map[i][j]=0;}}

result[i]

[j]=0;

map[i]

[j]=0;

count++

;//如果所有的嘗試都嘗試完了,就沒有情況了,該種嘗試應該作廢

return;}

}private

boolean

checklegal

(int

map,

int i,

int j)

}//檢查列

for(

int k =

0; k < map.length; k++)}

//檢查3*3,計算3*3座標

int sx=i/3*

3;int sy=j/3*

3;for(

int m=

0;m<

8;m++

)for

(int n = m +

1; n <

9; n++)}

}return

true;}

}

之後,會盡快把任務二發上來,人機互動介面還不會,慘啊,swing咱也沒學過。

C 回溯法生成數獨

演算法思路 首先第一行肯定是1 9的一種排列,直接使用shuffle進行隨機。從第二行第乙個開始,嘗試填入數字,填入後依據數獨規則進行可行性判斷。如果可以填入該數字,則對下一格進行相同的判斷。如果某一格對於任何數字的填入都違反了數獨規則,則進行回溯,重新填上一格的數字。當獲得乙個可行結果時,演算法終...

回溯法的應用之 數獨遊戲

數獨我就不多說話了 沒玩過的可以自己玩玩,或者百科下 關鍵是回溯法。這次是巧妙的利用八皇后的基礎搞出來的 下面我就來好好講將回溯法。上面的話一大推,你會發現很多廢話,其實回溯就是倒著來,返回。我們來回顧下本演算法的回溯演算法 1 include 2 3using namespace std 45 d...

唯一解的數獨題目生成器 理解回溯法

在生成數獨題目時,流程是 生成乙個完整的數獨 隨機挖空 解題 如果只有乙個解,則生成該題目,如果有多個解,則重新挖空。數獨題目的生成涉及的乙個演算法是回溯法,這裡面的完整數獨的生成 求解都用到了回溯法。1.生成完整數獨 在生成部分,先生成所有宮的1,再生成所有宮的2,以此類推。主要有三個值 bool...