在上海乘坐地鐵的朋友都知道,上海地鐵站免費(fèi)贈(zèng)閱的時(shí)代報(bào)上,經(jīng)常會(huì)刊登有數(shù)獨(dú)這個(gè)益智游戲。如果用紙和筆人工去算的話(huà),恐怕你要花上老半天功夫了,有時(shí)候還不一定能解出來(lái),心中一定很郁悶吧?網(wǎng)上也有一些數(shù)獨(dú)游戲的求解計(jì)算器,不過(guò)我想與其直接拿來(lái)主義,還不如自己研究編一個(gè)呢!所以,花了大概有一個(gè)多月的時(shí)間來(lái)編寫(xiě)了這樣一個(gè)數(shù)獨(dú)求解軟件。由于不是利用所謂的窮舉算法,所以如果數(shù)獨(dú)游戲非解的話(huà),它就只提供最先找到的那個(gè)解。不過(guò),請(qǐng)放心,肯定是正確的!下面我就來(lái)詳述一下這個(gè)算法的精要。
1、定義一個(gè)類(lèi),代表數(shù)獨(dú)游戲中的每一個(gè)數(shù)。它有如下屬性: #region 屬性
///
/// 數(shù)值
///
public int Num
{
set
{
if (UnFilled)
{
_num = value;
_unfilled = false;
Choices.Clear();
SetNumEvent(this);
}
}
get { return _num; }
}
///
/// 行坐標(biāo)
///
public int Xpos
{
set { _x = value; }
get { return _x; }
}
///
/// 列坐標(biāo)
///
public int Ypos
{
set { _y = value; }
get { return _y; }
}
///
/// 是否已填充的標(biāo)記
///
public bool UnFilled
{
get { return _unfilled; }
}
///
/// 候選數(shù)列表
///
public List Choices
{
set { _choices = value; }
get { return _choices; }
}
#endregion
2、在求解的主類(lèi)里,根據(jù)游戲的規(guī)則,設(shè)計(jì)這樣一套算法。當(dāng)某一個(gè)數(shù)值被設(shè)定以后,與它同行或同列的以及在同一個(gè)九宮里的數(shù)的候選數(shù)列里都要去掉這個(gè)數(shù)本身。數(shù)獨(dú)游戲中出現(xiàn)的數(shù)為已知數(shù),需要我們填補(bǔ)的則是未知數(shù)。未知數(shù)需要我們?nèi)ピ嚱?,不過(guò)在試解之前先要備份初始化以后的數(shù)組矩陣,以備在前一次試解失敗以后進(jìn)行恢復(fù)再進(jìn)行下一次試解,直到試解成功為止。
3、算法本身看上去不是太復(fù)雜,但是涉及到一個(gè)遍歷和回滾的問(wèn)題。所以,在編程的時(shí)候還是要注意一下的。
下面我就來(lái)簡(jiǎn)單介紹一下這個(gè)數(shù)獨(dú)求解軟件的操作和使用方法:
軟件總體來(lái)說(shuō)還是操作比較簡(jiǎn)單的,但是由于當(dāng)時(shí)編寫(xiě)的時(shí)候只是想給自己用的,所以并沒(méi)有設(shè)計(jì)菜單和幫助文檔。用戶(hù)在輸入初始數(shù)據(jù)的時(shí)候可以用上下左右方向鍵或者ASDF來(lái)進(jìn)行跳格。如果數(shù)錯(cuò)了,在按確定按鈕以前可以按Back Space或Delete鍵進(jìn)行修改;一旦按了確定按鈕,就只得按F5清空后重新輸入了。
軟件下載地址:http://download.csdn.net/source/512093
源碼下載地址:http://download.csdn.net/source/512102
1、定義一個(gè)類(lèi),代表數(shù)獨(dú)游戲中的每一個(gè)數(shù)。它有如下屬性: #region 屬性
///
/// 數(shù)值
///
public int Num
{
set
{
if (UnFilled)
{
_num = value;
_unfilled = false;
Choices.Clear();
SetNumEvent(this);
}
}
get { return _num; }
}
///
/// 行坐標(biāo)
///
public int Xpos
{
set { _x = value; }
get { return _x; }
}
///
/// 列坐標(biāo)
///
public int Ypos
{
set { _y = value; }
get { return _y; }
}
///
/// 是否已填充的標(biāo)記
///
public bool UnFilled
{
get { return _unfilled; }
}
///
/// 候選數(shù)列表
///
public List Choices
{
set { _choices = value; }
get { return _choices; }
}
#endregion
2、在求解的主類(lèi)里,根據(jù)游戲的規(guī)則,設(shè)計(jì)這樣一套算法。當(dāng)某一個(gè)數(shù)值被設(shè)定以后,與它同行或同列的以及在同一個(gè)九宮里的數(shù)的候選數(shù)列里都要去掉這個(gè)數(shù)本身。數(shù)獨(dú)游戲中出現(xiàn)的數(shù)為已知數(shù),需要我們填補(bǔ)的則是未知數(shù)。未知數(shù)需要我們?nèi)ピ嚱?,不過(guò)在試解之前先要備份初始化以后的數(shù)組矩陣,以備在前一次試解失敗以后進(jìn)行恢復(fù)再進(jìn)行下一次試解,直到試解成功為止。
3、算法本身看上去不是太復(fù)雜,但是涉及到一個(gè)遍歷和回滾的問(wèn)題。所以,在編程的時(shí)候還是要注意一下的。
下面我就來(lái)簡(jiǎn)單介紹一下這個(gè)數(shù)獨(dú)求解軟件的操作和使用方法:
軟件總體來(lái)說(shuō)還是操作比較簡(jiǎn)單的,但是由于當(dāng)時(shí)編寫(xiě)的時(shí)候只是想給自己用的,所以并沒(méi)有設(shè)計(jì)菜單和幫助文檔。用戶(hù)在輸入初始數(shù)據(jù)的時(shí)候可以用上下左右方向鍵或者ASDF來(lái)進(jìn)行跳格。如果數(shù)錯(cuò)了,在按確定按鈕以前可以按Back Space或Delete鍵進(jìn)行修改;一旦按了確定按鈕,就只得按F5清空后重新輸入了。
軟件下載地址:http://download.csdn.net/source/512093
源碼下載地址:http://download.csdn.net/source/512102

