QT編寫的數獨遊戲及乙個準確高效生成演算法

2021-08-01 16:57:40 字數 4088 閱讀 3153

關於數獨的求解演算法和軟體可以參考本人另一篇部落格

根據該鏈結上的演算法和提供的軟體,可以檢查出來難度選擇部分的演算法不好,生成的數獨不只有唯一解。

本人已用qt寫好軟體,雖然介面不太美觀,但難度選擇、錯誤提示、獲得幫助、存/讀檔功能都已實現

見鏈結使用qt可直接編譯執行

也生成了exe檔案,見

規則很簡單,就是乙個9×9的矩陣。根據現有數字,推算出剩餘的所有數字,使每一行、每一列、以及每乙個3×3矩陣上都必須有1-9之間的每乙個數字。9×9矩陣剛好為9行、9列、9個互不交叉的3×3矩陣。

數獨是乙個矩陣,為了讓這個矩陣使用起來簡單方便,我們宣告乙個類,來進行封裝

typedef

std::vector

vint;//標頭檔案vector

typedef

std::vector

vvint;//二維陣列

class numbertable

關於數獨的生成,有乙個簡單一點的演算法,就是對乙個固定的9*9陣列進行「玩魔方」。

我們先手動寫乙個9*9矩陣

1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9

4 , 5 , 6 , 7 , 8 , 9 , 1 , 2 , 3

7 , 8 , 9 , 1 , 2 , 3 , 4 , 5 , 6

2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1

5 , 6 , 7 , 8 , 9 , 1 , 2 , 3 , 4

8 , 9 , 1 , 2 , 3 , 4 , 5 , 6 , 7

3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 , 2

6 , 7 , 8 , 9 , 1 , 2 , 3 , 4 , 5

9 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8

可以看到我們有了乙個很有規律的矩陣,我們現在開始玩魔方,把規律徹底打亂

void numbertable::change_value(int lhs,int rhs)

}

可以在初始化矩陣時在乙個迴圈中呼叫該函式

std::default_random_engine e(time(0));//c++11,標頭檔案random

std::uniform_int_distribution u(1,9);//c++11,隨機數生成

for(int a=0;a<15;++a)//15可以該為其它數字

void numbertable::swap_row(int lhs,int rhs)

void numbertable::swap_col(int lhs,int rhs)

}

可以在初始化矩陣時在乙個迴圈中呼叫該函式

std::default_random_engine e(time(0));//c++11,標頭檔案random

std::uniform_int_distributionul(0,2);

for(int a=0;a<10;++a )//10可以該為其它數字

void numbertable::swap_threecol(int lhs,int rhs)

void numbertable::swap_col(int lhs,int rhs)

}

同樣在初始化的時候呼叫

std::default_random_engine e(time(0));//c++11,標頭檔案random

std::uniform_int_distributionul(0,2);

for(int a=0;a<10;++a)//10可以該為其它數字

void numbertable::change_number()

std::uniform_int_distributionul(0,2);

//swap row and column

for(int a=0;a<10;++a)//10可以該為其它數字

至此矩陣生成完成,只需在建構函式中呼叫函式change_number()即可,建構函式需先講9×9矩陣設定為初始的矩陣

建構函式**如下

numbertable::numbertable():vvnum(,,,

,,,,

,})

數獨矩陣生成後,需要預設顯示一部分,其它的部分需要玩家來自己推算。可以用乙個bool表示矩陣中某個數字是顯示還是不顯示,此時需要乙個9×9的bool矩陣,也需要乙個函式,來生成出這個9×9的bool矩陣。

為了**的清晰和可擴充套件,我們再宣告出乙個類,專門用來設定顯示方式,顯示方式必須也是隨機的。我們可以提供多個函式來設定不同的顯示方式,不同函式的設定方式會設定出不同難度的數獨遊戲(如簡單難度會顯示出40個數字,困難難度只顯示出20個數字;當然難度也有其它依據,可以繼續擴充套件)。

新類如下:

typedef

vector

vbool;//不能把vector中的乙個bool的位址賦給乙個bool指標,詳見書籍<>

typedef

vector

vvbool;

class gamelevel

gamelevel::gamelevel(int a):level(a),

defaultshow(9, vbool(9,0)),

ways(9,0)

其中defaultshow(9, vbool(9,0))為把defaultshow初始化為9個vbool(9,0)vbool(9,0)是9個bool,每個都為0

* 難度函式,如果不需要可以只留乙個。不同函式生成的難度不一樣,簡單和中等只是個數不一樣,困難和地獄則在generate_map()中有了對稱,難度大增

static std:

:default_random_engine e(time(0));//宣告為static是因為多個函式都用到了

void gamelevel::setlevel()

void gamelevel::sayeasyways()

void gamelevel::saymediumways()

void gamelevel::sayhardways()

void gamelevel::sayhellways()

* 根據`ways`生成`defaultshow`的函式如下

void gamelevel::generate_map()

else

for(int a=5;a<9;++a)

}}

其需要的changerow函式如下,該函式沒有用到任何成員變數和成員函式,可放到類外

void gamelevel::changerow(vbool &a,int num)

else ++i;

}while(i!=a.end());

}

int hardclass;

hardclass=1;//此處讓玩家設定

gamelevel lev(hardclass);

for(int a=0;a<9;++a)

}

由於用到了gamelevel的操作符過載,需要在gamelevel中新增操作符過載函式,當然也可以其它方法

const vbool & operator(int a)const

此坑待填…功能都寫好了,但注釋比較少,原始碼可見部落格開頭的github鏈結

利用隨機數編寫的乙個數獨

include include include int a 9 b 9 int c 9 設計思想是從t位置開始,重新設計陣列,t 9儲存在乙個陣列的前面部分,1 t 1儲存在後面部分,這樣來構成乙個序列,並且只要首元素不重複,這個序列的每一位就不會跟上面的序列重複。t有兩種 一種是因為剛好當前行數 ...

編寫乙個移動的遊戲背景

教程目錄 1.小遊戲展示 3.創作乙個移動的背景 4.讓阿菌煽動翅膀 5.讓阿菌模擬重力下墜 6.讓阿菌可以摸魚 7.編寫遊戲開始與結束 8.編寫 boss 劇情 9.部署到伺服器,在手機玩耍 進入工程專案後就可以開始開發了,首先我們把遊戲所用到的等資源檔案放到assets目錄中 然後我們設定遊戲畫...

CRASH 乙個賭博小遊戲的編寫

初步實現了本人從面向過程到物件導向程式設計的轉變 程式功能 可以玩n回合 bout 每回合 bout 只要未分勝負就可以繼續玩下去,或中途退出。crashgame.h 乙個簡單的賭博遊戲,遊戲規則如下 玩家擲兩個骰子,點數為1到6,如果第一次點數和為7或11,則玩家勝,如果點數和為2 3或12,則玩...