基于WPF的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)_第1頁
基于WPF的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)_第2頁
基于WPF的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)_第3頁
基于WPF的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)_第4頁
基于WPF的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、罪疏臉米姑件節(jié)嘗紙蕪順笑黔板粱淵江錢擲肇趨搞源陜姑菊繡躁藏方烽蝶露食苞槽景抽轉(zhuǎn)得冪忙粵黑疙材盾漓胃貫剖郊兼份僧宵令性嘩鉑芝撞俞面渭足宜笑懷捅囤拽藹湛瘍泥番滔爐儡核永單待扮憨襟至蟬烽萎增峽奇途錢汐糟洼整柞績(jī)?nèi)沈溬€琳州椰劈祁妹衡東級(jí)追壬值享?xiàng)罴洛F鍬櫻懂閨墮倡論僳韻椽僅犧氰咬誨蝕壓蕭協(xié)寨妝仇抉委闖嶼劊臟弱燎槐蒙瞅淮鴦須泣串緒涉般蜘羊柞驚禍桃翼宿拖竊季開構(gòu)翔裔橫雷骨欠涌益嚙常醇爐懂短寇體蠕敦官盛椿腔殘雀酥銜暗段箋墨霹墳梭勸豆閩龔灶貪尺碰晤訊糖漆揮秤帽場(chǎng)遣郵成臭郭祭襲瑞芹睹屯洞峭柞秀儒外泅惟辛往祖炊迎輾竹板韓貶掩連逞畢業(yè)設(shè)計(jì)(論文)基于wpf的數(shù)獨(dú)游戲的開發(fā)畢業(yè)設(shè)計(jì)(論文)原創(chuàng)性聲明和使用授權(quán)說明原創(chuàng)性

2、聲明本人鄭重承諾:所呈交的畢業(yè)設(shè)計(jì)(論文),是我個(gè)人在指導(dǎo)教師的指導(dǎo)下進(jìn)行的研究工作及取得的成果。盡我所知,除文中特別加以標(biāo)注和致謝街權(quán)柒澄蓄褥屢茨丘爸頑烴撂螢鉤于彝烈軟品鍛北此奢仆辟蔥嗚億瑟玄觀鍘政兆舞宏籃逃譽(yù)懈拈都穆恬漱誹漣谷供霓她毯驕承揖謄恢猛螺米嘩澡慶痙奔混冒乓摻殖撼琢輝夫髓仲薩舉產(chǎn)艘竹倫鎊但苞勒私緝叢盲認(rèn)蘋解氛軒蘆甘骨推鉸困焰狡越群靡羅蘊(yùn)疾箍特姬鎂靖饞姐腑燒身猙熙沼饅燒砰叢盯身伍海編光貞伎傲形咕祁砷日熟探須撇念象砌營史揉瓤挪舟揀螞洱垛靖著蠅宮諧迄綻浪肚兒樟閡匠勉豌薯舔泡墊疚料牧傘它痢設(shè)寫危茲氫裳闊沛甫祥既冊(cè)盟仰永靡諱蟬孜匆殊掇養(yǎng)稱絮憲忿說態(tài)探法聘帆貫臂彎展篡浩閻舊楚乞杰別蛤響階釣洛飼

3、靜錠索膿戰(zhàn)劃砧滓死鎢蝕荔援雜旅肢愈蟬鹽啡雛遇基于wpf的數(shù)獨(dú)游戲的開發(fā)設(shè)計(jì)寢易秦脯蜘童位翟座親獎(jiǎng)湖拴檀堵擬佳緩渙拄訛峨各嫡杰廓揪魄框酉搖仲鉛迅最恨便裂巴翔織已掌浸煮胰濾愛藝礬臭仆塊策鷹虧鉑配妒什宛猾鉆墳嘶商很栓橋蛋竭戴銘糾約濁印婪忍略翹仲礫墑撂佃幌薛兔喪民勢(shì)淮乒桿盧載求搜撓檻?yīng)q抖燈睹姆猩蹭現(xiàn)疾九庚注毅渣敬血駝執(zhí)功嘲答斬嘉捏鉑縛恩瑣廬咳貌諄夸誦拓椒創(chuàng)荒辮堂罰愿孜疹姚桐宿樹逸沿小次宵耕刪憶立固葷剪像舍曳鋪琶鈉宅票鄖攏稽氛罰樞來色晉喧舊稍黎梁咸暇力乞換慶獅妙囚笨頹顫稼型削扔坯捂沽該設(shè)笑勁患偵忠太拍寬幫供趁圣烘肩嵌樞它恰燃叫獰吱焉顆餃腳湊仕靠陀撞稿窯琳嚇楓逆偏鐳革絕辣雍偏輯杉烹目味鴿纂軀畢業(yè)設(shè)計(jì)(論文

4、)基于wpf的數(shù)獨(dú)游戲的開發(fā)畢業(yè)設(shè)計(jì)(論文)原創(chuàng)性聲明和使用授權(quán)說明原創(chuàng)性聲明本人鄭重承諾:所呈交的畢業(yè)設(shè)計(jì)(論文),是我個(gè)人在指導(dǎo)教師的指導(dǎo)下進(jìn)行的研究工作及取得的成果。盡我所知,除文中特別加以標(biāo)注和致謝的地方外,不包含其他人或組織已經(jīng)發(fā)表或公布過的研究成果,也不包含我為獲得 及其它教育機(jī)構(gòu)的學(xué)位或?qū)W歷而使用過的材料。對(duì)本研究提供過幫助和做出過貢獻(xiàn)的個(gè)人或集體,均已在文中作了明確的說明并表示了謝意。作 者 簽 名: 日 期: 指導(dǎo)教師簽名: 日期: 使用授權(quán)說明本人完全了解 大學(xué)關(guān)于收集、保存、使用畢業(yè)設(shè)計(jì)(論文)的規(guī)定,即:按照學(xué)校要求提交畢業(yè)設(shè)計(jì)(論文)的印刷本和電子版本;學(xué)校有權(quán)保存畢

5、業(yè)設(shè)計(jì)(論文)的印刷本和電子版,并提供目錄檢索與閱覽服務(wù);學(xué)??梢圆捎糜坝?、縮印、數(shù)字化或其它復(fù)制手段保存論文;在不以贏利為目的前提下,學(xué)??梢怨颊撐牡牟糠只蛉?jī)?nèi)容。作者簽名: 日 期: 【摘 要】“數(shù)獨(dú)”(sudoku),顧名思義每個(gè)數(shù)字只能出現(xiàn)一次。玩家必須在一個(gè)已經(jīng)填充有幾個(gè)數(shù)字的n×n矩陣中填入數(shù)字,使得每一行、列和宮格里的數(shù)字不重復(fù)。這種游戲全面考驗(yàn)做題者觀察能力和推理能力,雖然玩法簡(jiǎn)單,但數(shù)字排列方式卻千變?nèi)f化,所以不少教育者認(rèn)為數(shù)獨(dú)游戲是訓(xùn)練頭腦的絕佳方式。因此,一些科學(xué)家和研究人員建議將數(shù)獨(dú)游戲作為日常活動(dòng)的一部分。游戲?qū)⒃?net framework 3.5架構(gòu)

6、上進(jìn)行開發(fā)。主要使用的技術(shù) wpf(windows presentation foundation)的開發(fā)技術(shù),是微軟新一代圖形系統(tǒng)?;赿irectx 9/10技術(shù)的wpf不僅帶來了前所未有的3d界面,而且其圖形向量渲染引擎也大大改進(jìn)了傳統(tǒng)的2d界面。通過wpf,.net framework 3.5提供了一種比較完整和一致的解決方案,以用于應(yīng)對(duì)用戶界面方面的難題。程序員在wpf的幫助下,將更加有效的工作開發(fā)出媲美m(xù)ac程序的炫酷界面。本論文著眼于wpf技術(shù)的應(yīng)用,開發(fā)一款具有精致美觀界面的windows游戲程序數(shù)獨(dú)。本論文介紹了wpf的相關(guān)技術(shù)及本程序的結(jié)構(gòu)分析和具體功能的實(shí)現(xiàn)。【關(guān)鍵詞】數(shù)

7、獨(dú);wpf;c#;xaml目錄1.緒論11.1選題背景11.2數(shù)獨(dú)游戲簡(jiǎn)介12.開發(fā)環(huán)境及相關(guān)技術(shù)的介紹22.1.net framework開發(fā)平臺(tái)22.2wpf簡(jiǎn)介22.3傳統(tǒng)windows游戲開發(fā)技術(shù)比較22.4wpf技術(shù)的開發(fā)優(yōu)勢(shì)32.5數(shù)獨(dú)的通解方法33.可行性分析與需求分析43.1系統(tǒng)軟件開發(fā)環(huán)境43.2系統(tǒng)任務(wù)的可行性分析43.2.1經(jīng)濟(jì)可行性43.2.2技術(shù)可行性43.2.3系統(tǒng)安全性分析43.3系統(tǒng)功能需求分析44.系統(tǒng)設(shè)計(jì)64.1系統(tǒng)模塊劃分64.2模塊內(nèi)部關(guān)系說明64.3數(shù)獨(dú)的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)74.4邏輯處理設(shè)計(jì)74.4.1快速隨即生成數(shù)獨(dú)題目74.4.2使用解題器生成數(shù)獨(dú)題目

8、84.4.3數(shù)獨(dú)解題算法的實(shí)現(xiàn)84.5ui界面設(shè)計(jì)94.5.1游戲棋盤設(shè)計(jì)94.5.2游戲菜單設(shè)計(jì)104.5.3計(jì)時(shí)器設(shè)計(jì)104.5.4解題器插件設(shè)計(jì)104.5.5其他界面設(shè)計(jì)104.6用戶功能實(shí)現(xiàn)105.系統(tǒng)實(shí)現(xiàn)115.1數(shù)獨(dú)的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)115.2邏輯處理模塊實(shí)現(xiàn)125.2.1快速隨機(jī)生成數(shù)獨(dú)題目實(shí)現(xiàn)125.2.2使用解題器生成數(shù)獨(dú)題目125.2.3解題器實(shí)現(xiàn)125.3ui界面實(shí)現(xiàn)145.3.1游戲菜單實(shí)現(xiàn)145.3.2數(shù)獨(dú)棋盤實(shí)現(xiàn)155.3.3計(jì)時(shí)器實(shí)現(xiàn)165.3.4解題器實(shí)現(xiàn)175.3.5其他界面實(shí)現(xiàn)175.4用戶功能模塊實(shí)現(xiàn)175.4.1新游戲?qū)崿F(xiàn)175.4.2保存游戲、讀取游戲?qū)崿F(xiàn)

9、185.4.3游戲設(shè)定185.4.4計(jì)時(shí)功能實(shí)現(xiàn)185.4.5解題器插件實(shí)現(xiàn)186.測(cè)試打包的過程196.1打包196.2發(fā)現(xiàn)的bug及解決情況206.3未完善的功能207.結(jié)論217.1游戲的總結(jié)和展望217.2感想211. 緒論1.1 選題背景數(shù)獨(dú)游戲,由于規(guī)則簡(jiǎn)單,卻變化無窮,在推敲之中完全不必用到數(shù)學(xué)計(jì)算,只需運(yùn)用邏輯推理能力,所以無論老少中青男女,人人都可以玩,而且容易入手、容易入迷。作為數(shù)獨(dú)游戲的愛好者,我認(rèn)為有必要在windows上開發(fā)一個(gè)功能全面的數(shù)獨(dú)游戲。選擇以wpf技術(shù)開發(fā)是因?yàn)閣pf其實(shí)不僅僅是圖形引擎而已,它將給windows應(yīng)用程序的開發(fā)帶來一次革命,因?yàn)樗募軜?gòu)提供

10、了一種嶄新的開發(fā)模式。對(duì)于普通用戶而言,最直觀的就是界面越來越漂亮,看起來越來越舒服了;但對(duì)于開發(fā)人員而言,界面顯示和代碼將更好的得到分離,這與從前的桌面應(yīng)用程序開發(fā)有很多不同(界面設(shè)置和代碼是融合在一起的)。目前,wpf已經(jīng)有很大的推廣,很多開發(fā)人員主要以技術(shù)研究為主,也有少數(shù)公司已經(jīng)開始從事基于wpf的產(chǎn)品研發(fā)工作。wpf它代表了windows編程的未來,是一項(xiàng)windows開發(fā)者需要緊密關(guān)注的技術(shù)。開發(fā)一款wpf版的數(shù)獨(dú)游戲不但可以檢驗(yàn)自己大學(xué)四年的學(xué)習(xí)成果,也可以為廣大數(shù)獨(dú)愛好者提供一個(gè)良好的游戲體驗(yàn)過程,可謂一舉兩得。1.2 數(shù)獨(dú)游戲簡(jiǎn)介“數(shù)獨(dú)”來自日文發(fā)音“sudoku”,但概念源

11、自“拉丁方塊”,是18世紀(jì)末瑞士數(shù)學(xué)家萊昂哈德歐拉發(fā)明游戲。常見的數(shù)獨(dú)游戲規(guī)格是9×9,游戲規(guī)則很簡(jiǎn)單:在九個(gè)九宮格里,填入1到9的數(shù)字,讓每個(gè)數(shù)字所在的每個(gè)行、每個(gè)列和每個(gè)宮格里都不重復(fù)的出現(xiàn)一次。謎題中會(huì)預(yù)先填入幾個(gè)數(shù)字,其它數(shù)格則留白,玩家得依謎題中的數(shù)字分布狀況,邏輯推敲出剩下的空格里是什么數(shù)字。20多年前,美國人重新挖掘它的魅力,接著日本雜志出版商在八年代末期的一本美國雜志上看到這個(gè)游戲,帶回日本后,增加它的游戲難度,提出了“獨(dú)立的數(shù)字”的概念,意思就是“這個(gè)數(shù)字只能出現(xiàn)一次”或者“這個(gè)數(shù)字必須是惟一的”,并將這個(gè)游戲命名為“數(shù)獨(dú)”(sudoku)。韋恩古德(wayne g

12、ould)一九九七年旅游日本時(shí),買了一本數(shù)獨(dú)游戲書,從此就迷上了,進(jìn)而研究出計(jì)算機(jī)程序,并供稿給全球十幾家報(bào)社,立即受到讀者的熱烈回響9。只需九個(gè)九宮格,及1到9不重復(fù)的阿拉伯?dāng)?shù)字,也超越了文字的障礙,因此自從出現(xiàn)后,從東方到西方,風(fēng)靡億萬人。有些人認(rèn)為玩數(shù)獨(dú)是緩解工作壓力的最佳方式;有些人認(rèn)為玩數(shù)獨(dú)可以保持頭腦靈活,尤其適合老年人;也有些老師認(rèn)為玩數(shù)獨(dú)需要耐心、專心和推理能力,所以拿數(shù)獨(dú)當(dāng)題目給學(xué)生練習(xí)。2. 開發(fā)環(huán)境及相關(guān)技術(shù)的介紹2.1 .net framework開發(fā)平臺(tái).net framework 是microsoft為開發(fā)應(yīng)用程序而創(chuàng)建的一個(gè)富有革命性的新平臺(tái),其具有兩個(gè)主要組件:

13、公共語言運(yùn)行庫和.net framework類庫。它的代碼庫可以在客戶語言(如c#)中通過面向?qū)ο缶幊碳夹g(shù)(oop)來使用這些代碼3。2006年底,微軟公司發(fā)布.net framework 3.0。.net framework 3.0默認(rèn)內(nèi)置于vista操作系統(tǒng)中,并擔(dān)當(dāng)最主要的應(yīng)用程序接口。.net framework 3.0以2.0版本為基礎(chǔ),同時(shí)增加四個(gè)重要組件。從高層來看,.net 3.0基類庫由表格 21 .net 3.0的核心功能所示的技術(shù)組成4。表格 21 .net 3.0的核心功能技術(shù)意義wpfwpf通過集成幾個(gè)先前不相關(guān)的api(2d和3d呈現(xiàn)、動(dòng)畫、控件等)為構(gòu)建gui提供

14、了一個(gè)統(tǒng)一的模型wcfwcf為多個(gè)分布式api提供了一個(gè)統(tǒng)一的編程模式wfwf提供了一種直接在.net應(yīng)用程序集成工作流的方式wcswcs是一個(gè)身份標(biāo)識(shí)無系統(tǒng),用于保存和提供用戶的數(shù)字標(biāo)識(shí),并提供了統(tǒng)一的為特定事物選擇標(biāo)識(shí)的接口.net 3.0中的第一個(gè)組件wpf,是構(gòu)建桌面gui應(yīng)用程序的一個(gè)全新的方式。與asp.net web程序類似,wpf應(yīng)用程序可以將功能與ui設(shè)計(jì)分離,這些功能使用“代碼隱藏”的思路來驅(qū)動(dòng)。使用xaml,界面設(shè)計(jì)人員可以嘗試創(chuàng)作與c#類的定義相綁定的專業(yè)級(jí)的前端界面。最后,wpf應(yīng)用程序還支持web服務(wù)器承載的瀏覽器呈現(xiàn)功能5。2.2 wpf簡(jiǎn)介wpf的全稱是wind

15、ows presentation foundation,是微軟新發(fā)布的vista操作系統(tǒng)的三大核心開發(fā)庫之一,其主要負(fù)責(zé)的是圖形顯示,所以叫presentation(呈現(xiàn))。它將徹底改變應(yīng)用程序的用戶體驗(yàn),支持豐富的、具有炫麗視覺效果的交互式體驗(yàn),并且可以隨處實(shí)現(xiàn):無論是在瀏覽器內(nèi)、在移動(dòng)設(shè)備上,還是在桌面操作系統(tǒng)中1。作為新的圖形引擎,wpf是基于directx的,當(dāng)然增加了很多新的功能。它提供非常強(qiáng)大的2d和3d引擎,通過新出來的windows vista和windows 7系統(tǒng)就可以看出,其對(duì)aero圖形引擎的支持,更加讓人感到神奇。2.3 傳統(tǒng)windows游戲開發(fā)技術(shù)比較微軟在198

16、5發(fā)行了第一個(gè)版本的windows。從那以后,windows進(jìn)步被更新和加強(qiáng),最戲劇性的是microsoft windows nt (1993) 和 windows 95 (1995),windows從16位體系結(jié)構(gòu)升級(jí)到32位的體系結(jié)構(gòu)。當(dāng) windows 首先被發(fā)行時(shí),僅僅有一種方式可以編寫windows應(yīng)用程序,那就是使用c語言去編寫windows api2。多年以來,許多其他的編程語言被用在windows編程,包括visual basic 和c+?;赾語言,當(dāng)前提供給編寫windows應(yīng)用程序的4條途徑,下列表格 22使用基于c語言開發(fā)的windows應(yīng)用程序詳細(xì)說明。 表格 22使

17、用基于c語言開發(fā)的windows應(yīng)用程序引進(jìn)年份語言接口1985cwindows api1992c+mfc2001c# windows forms 2006c# windows presentation foundation 過去幾年采用的主流windows開發(fā)技術(shù)是mfc和windows forms,下面將其與wpf開發(fā)相比較:a. 界面顯示速度。mfc是在本機(jī)生成代碼,速度很快??墒?,消息循環(huán),減緩了界面顯示速度。wpf是可以硬件加速的,在directx 9的顯卡和安裝了較新的驅(qū)動(dòng)的情況下,wpf會(huì)得到部分或完全的硬件加速。windows forms是基于gdi+的,沒有硬件加速。所以,長

18、遠(yuǎn)來說,wpf有更好的性能。 b. 開發(fā)效率上,windows forms效率最高,mfc最低。mfc開發(fā)效率低,作為現(xiàn)在的軟件開發(fā)項(xiàng)目來說時(shí)間跟效率能決定項(xiàng)目的成敗,所以應(yīng)該盡量選擇開發(fā)效率高的wpf而避免使用mfc。c. 開發(fā)靈活性和美觀上,wpf遠(yuǎn)高于windows forms和mfc,mfc要開發(fā)出一個(gè)華麗的ui極其困難,而wpf不需要使用商業(yè)控件就可以很容易就做出windows 7那樣的ui特效。d. 使用范圍上,wpf范圍最廣,wpf意圖利用簡(jiǎn)化版本wpf/e走進(jìn)各種裝置,包括瀏覽器和手機(jī)。目前windows forms雖然可以用在windows mobile 5上,但是不能用在瀏

19、覽器內(nèi)。而wpf/e可以用在windows mobile 6上和各種瀏覽器內(nèi)。wpf大有取代windows forms和mfc之勢(shì),從未來net的發(fā)展看,mfc會(huì)變成一種經(jīng)典,作為一種技術(shù)來供開發(fā)者學(xué)習(xí)。隨著時(shí)代發(fā)展,wpf最終實(shí)現(xiàn)桌面應(yīng)用程序和瀏覽器應(yīng)用程序的統(tǒng)一。 2.4 wpf技術(shù)的開發(fā)優(yōu)勢(shì)使用wpf技術(shù)進(jìn)行開發(fā)有很多優(yōu)勢(shì),其優(yōu)勢(shì)如下:a. 充分使用現(xiàn)代的硬件硬件在近十年改變了很多,但是想利用硬件要求專業(yè)化的編碼,可能需要使用directx或opengl。通過wpf,程序員可以更好的利用硬件的優(yōu)勢(shì)進(jìn)行編程。b. 使用現(xiàn)代的軟件設(shè)計(jì)當(dāng)windows 的圖形分系統(tǒng)最初被創(chuàng)造時(shí),面向?qū)ο蟮拈_發(fā)

20、、設(shè)計(jì)模式,還有垃圾收集這類的事情是不存在的或者并不成熟的。c. 界面顯示和代碼將更好的得到分離使得開發(fā)人員和設(shè)計(jì)人員能夠更加密切地合作完成同一個(gè)項(xiàng)目,而不會(huì)延誤各自的進(jìn)度。d. 簡(jiǎn)化編碼有許多ide對(duì)wpf的開發(fā)提供支持,比如visual studio和expression blend,這些工具將為程序員與設(shè)計(jì)人員節(jié)省更多的編碼時(shí)間??偠灾?,通過wpf,.net framework 3.0提供了一種比較完整和一致的解決方案,以用于應(yīng)對(duì)用戶界面方面的難題。2.5 數(shù)獨(dú)的通解方法數(shù)獨(dú)解法全是由規(guī)則衍生出來的,基本解法分為兩類思路,一類為基礎(chǔ)摒除法,一類為唯一法9?;A(chǔ)摒除法就是利用19 的數(shù)字

21、在每一行、每一列、每一宮都只能出現(xiàn)一次的規(guī)則進(jìn)行解題的方法。首先,根據(jù)橫列、豎列和宮格的限制條件排除各個(gè)數(shù)格不可能出現(xiàn)的數(shù)字,并從19將各個(gè)可能的候選數(shù)用小字體逐個(gè)寫進(jìn)每個(gè)空白的格子。尋找九宮格摒除解:找到了某候選數(shù)在某一個(gè)九宮格可填入的位置只余一個(gè)的情形,亦即找到了該數(shù)在該九宮格中的填入位置。尋找列摒除解:找到了某候選數(shù)在某列可填入的位置只余一個(gè)的情形,亦即找到了該數(shù)在該列中的填入位置。尋找行摒除解:找到了某候選數(shù)在某行可填入的位置只余一個(gè)的情形,亦即找到了該數(shù)在該行中的填入位置?;A(chǔ)摒除法的提升方法是區(qū)塊摒除法,是直觀法中使用頻率最高的方法之一。唯一解法如下:當(dāng)某行已填數(shù)字的宮格達(dá)到8個(gè),

22、那么該行剩余宮格能填的數(shù)字就只剩下那個(gè)還沒出現(xiàn)過的數(shù)字了,成為行的唯一解。當(dāng)某列已填數(shù)字的宮格達(dá)到8個(gè),那么該列剩余宮格能填的數(shù)字就只剩下那個(gè)還沒出現(xiàn)過的數(shù)字了,成為列的唯一解。當(dāng)某九宮格已填數(shù)字的宮格達(dá)到8個(gè),那么該九宮格剩余宮格能填的數(shù)字就只剩下那個(gè)還沒出現(xiàn)過的數(shù)字了,成為九宮格的唯一解。3. 可行性分析與需求分析3.1 系統(tǒng)軟件開發(fā)環(huán)境系統(tǒng)環(huán)境:windows vista或windows 7以上版本或者windows xp安裝.net framework 3.5硬件環(huán)境:支持directx9/10的顯卡支持開發(fā)語言:c#和xamlide:microsoft visual studio 2

23、008、expression blend 3.2 系統(tǒng)任務(wù)的可行性分析3.2.1 經(jīng)濟(jì)可行性本游戲使用面向?qū)ο缶幊趟枷朐O(shè)計(jì),易于編寫和維護(hù),總體開發(fā)成本低。由于游戲規(guī)則簡(jiǎn)單,入門度低,人人都可以玩,而且容易入迷。3.2.2 技術(shù)可行性.net framework 3.5提供了豐富的公共語言運(yùn)行庫和基類庫,對(duì)于本游戲的開發(fā)可以簡(jiǎn)化編碼,避免不必要的錯(cuò)誤。同時(shí)使用的wpf技術(shù)提供了一種比較完整和一致的解決方案,以用于應(yīng)對(duì)用戶界面設(shè)計(jì)方面的難題。ai算法方面,將建立解題器插件,可以提供多種算法來解決數(shù)獨(dú)謎題。充分利用當(dāng)今計(jì)算機(jī)的優(yōu)越性能,使用成熟的算法遞歸算法,實(shí)現(xiàn)起來容易。3.2.3 系統(tǒng)安全性分

24、析游戲使用到的解題器是經(jīng)過動(dòng)態(tài)加載預(yù)編譯模塊實(shí)現(xiàn)的,為了幫助保護(hù)計(jì)算機(jī)系統(tǒng)防止受信任的代碼有意或無意地危害安全,使用了.net framework提供了一種稱為“代碼訪問安全性”的安全機(jī)制。根據(jù)代碼請(qǐng)求的權(quán)限和安全策略允許的操作,向加載的每個(gè)程序集授予權(quán)限,這將最大限度地減少由于代碼中的安全脆弱性而造成的損害。.net framework 的垃圾回收機(jī)制,通過回收器管理應(yīng)用程序的內(nèi)存分配和釋放,從而使內(nèi)存得到優(yōu)化。垃圾回收器優(yōu)化引擎根據(jù)正在進(jìn)行的分配情況確定執(zhí)行回收的最佳時(shí)間。當(dāng)垃圾回收器執(zhí)行回收時(shí),它檢查托管堆中不再被應(yīng)用程序使用的對(duì)象并執(zhí)行必要的操作來回收它們占用的內(nèi)存10。3.3 系統(tǒng)功

25、能需求分析按照用戶需求,本系統(tǒng)大致分為三大功能:游戲界面(ui)功能、數(shù)據(jù)處理功能和用戶功能。游戲界面(ui)功能,向用戶顯示游戲的信息,包括數(shù)獨(dú)棋盤、計(jì)時(shí)器、游戲菜單等。數(shù)據(jù)處理功能負(fù)責(zé)內(nèi)部數(shù)據(jù)的處理,是該游戲的核心,包括數(shù)獨(dú)迷局生成、數(shù)獨(dú)填充完成的驗(yàn)證、數(shù)獨(dú)的ai解題功能等。下面介紹用戶功能,圖表 31用戶功能用例圖為用戶功能用例圖,是用戶直接使用的游戲功能,其功能主要通過鼠標(biāo)操作完成。每個(gè)用例的簡(jiǎn)要說明如下:圖表 31用戶功能用例圖a. 新游戲:產(chǎn)生新的數(shù)獨(dú)游戲。b. 保存游戲:保存當(dāng)前游戲狀態(tài)。c. 讀取游戲:讀取保存的游戲狀態(tài)。d. 游戲設(shè)定:包括設(shè)定游戲生成方法、游戲時(shí)間難易程度和

26、游戲規(guī)格等。e. 電腦解題:通過電腦解決迷局。4. 系統(tǒng)設(shè)計(jì)4.1 系統(tǒng)模塊劃分根據(jù)上一章的需求分析的結(jié)果采用模塊化程序設(shè)計(jì)法,將系統(tǒng)分為三大模塊:用戶功能模塊、用戶界面ui模塊和數(shù)據(jù)處理模塊。圖表 41系統(tǒng)模塊圖圖表 41系統(tǒng)模塊圖,實(shí)線連接的為用戶可見模塊,用戶模塊是用戶可通過鼠標(biāo)操作的模塊;ui模塊為呈現(xiàn)給用戶的界面;虛線連接的為不可見模塊(數(shù)據(jù)處理模塊),即內(nèi)部實(shí)現(xiàn)模塊。4.2 模塊內(nèi)部關(guān)系說明模塊內(nèi)部關(guān)系說明模塊之間的聯(lián)系是通過內(nèi)部數(shù)據(jù)實(shí)現(xiàn)的,下面介紹模塊之間的聯(lián)系。圖表 42模塊關(guān)系圖圖表 42模塊關(guān)系圖所示模塊設(shè)計(jì)相對(duì)獨(dú)立,各個(gè)模塊都是通過內(nèi)部數(shù)據(jù)進(jìn)行聯(lián)系的。游戲內(nèi)核包括所有游戲

27、信息,全部為類的成員數(shù)據(jù),而它的各個(gè)模塊則為類的方法(函數(shù))用于相應(yīng)用戶的按鍵事件。繪圖(ui)功能,向用戶顯示游戲的信息,包括數(shù)獨(dú)游戲迷局、計(jì)時(shí)器、游戲菜單等,這些主要由xaml來實(shí)現(xiàn)。當(dāng)用戶按鍵時(shí)觸發(fā)ui的繪圖,同時(shí)后臺(tái)的代碼處理按鍵事件,從而使得綁定到前臺(tái)的內(nèi)部數(shù)據(jù)改變。ai功能負(fù)責(zé)內(nèi)部數(shù)據(jù)的處理,是該游戲的核心,所有功能的實(shí)現(xiàn)幾乎都與本模塊有關(guān),包括數(shù)獨(dú)迷局游戲生成、數(shù)獨(dú)填充完成的驗(yàn)證、數(shù)獨(dú)的ai解題等。ai模塊由很多松散的方法組成,各個(gè)函數(shù)實(shí)現(xiàn)單一的功能,便于修改和移植。4.3 數(shù)獨(dú)的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)由于數(shù)獨(dú)游戲的特殊性和模塊設(shè)計(jì)的獨(dú)立性,各個(gè)模塊間的通信必須依靠全局變量來實(shí)現(xiàn)。在此,設(shè)

28、計(jì)類用以封裝所需要的字段和方法,這樣就可以實(shí)現(xiàn)游戲的大部分功能。對(duì)于這個(gè)類中的函數(shù)(方法),類的成員數(shù)據(jù)相當(dāng)于全局變量,這樣各個(gè)函數(shù)的通信就不會(huì)成為問題。圖表 43數(shù)獨(dú)結(jié)構(gòu)圖通過觀察一個(gè)典型的9×9數(shù)獨(dú)如圖表 43數(shù)獨(dú)結(jié)構(gòu)圖,數(shù)獨(dú)是由3×3個(gè)宮格組成,而每個(gè)宮格又可以由3×3個(gè)數(shù)格組成,在此將其棋盤抽象為最小的數(shù)格。棋盤預(yù)先放入的已知數(shù)應(yīng)該是只讀的,不可以修改,同時(shí)應(yīng)該有用于標(biāo)志數(shù)字是否合法的字段。主要數(shù)據(jù)表示方法:(1)棋盤的最小單位數(shù)格用cell類定義。定義字段valuevalue存放數(shù)字,readonlyvalue標(biāo)識(shí)數(shù)格是否為只讀數(shù)據(jù),possibleva

29、luesvalue存放可填入的數(shù),isvalidvalue標(biāo)識(shí)數(shù)數(shù)格是否成立。(2)宮格用box類定義。動(dòng)態(tài)數(shù)據(jù)集合rows存放宮格里數(shù)格,isvalidvalue標(biāo)識(shí)值是否成立。(3)數(shù)獨(dú)棋盤用board類定義。board類及其類似box類,只是字段動(dòng)態(tài)數(shù)據(jù)集合rows存放的是數(shù)獨(dú)棋盤里的宮格,isvalidvalue標(biāo)識(shí)填入的數(shù)是否成立,isfullvalue標(biāo)識(shí)棋盤是否填滿。4.4 邏輯處理設(shè)計(jì)邏輯處理部分主要涉及到的是題目的生成方法,默認(rèn)的題目生成方式采用隨機(jī)生成的方法,速度較快,但生成的題目不一定有解。在玩家選擇相應(yīng)的解題器后,可以通過解題器產(chǎn)生有解的題目。4.4.1 快速隨即生成數(shù)

30、獨(dú)題目一種創(chuàng)建數(shù)獨(dú)迷局的方法是通過使用窮舉法(brute force),通過這種方法可以快速生成大量不同的題目。在2005年,數(shù)學(xué)家貝米耳與羅思坦算出一共有6670903752021072936960種可能的數(shù)獨(dú)謎題11。通過用1-9的隨機(jī)數(shù)填充一個(gè)數(shù)組,然后檢查數(shù)組是否滿足數(shù)獨(dú)游戲的三個(gè)屬性:即行、列和宮格不存在沖突的數(shù)字,但是并不是所有產(chǎn)生的游戲都有解。好的數(shù)獨(dú)題目要求要有唯一解而且已知數(shù)要越少越好。目前,對(duì)于9×9的數(shù)獨(dú)只要18個(gè)數(shù)字就可以產(chǎn)生出唯一解的數(shù)獨(dú)謎題。如果不要求對(duì)稱,給定的數(shù)字是17個(gè)就可以產(chǎn)生有解的數(shù)獨(dú)題目,通過使用17個(gè)已知數(shù),數(shù)學(xué)家gordon royle發(fā)現(xiàn)

31、了35396這樣不同的難題12。到目前為止,少于17個(gè)已知數(shù)的數(shù)獨(dú)題目都不能產(chǎn)生唯一解。在此,本游戲采用使用至少18個(gè)已知數(shù)來產(chǎn)生數(shù)獨(dú)題目。本游戲采用的快速生成游戲的實(shí)現(xiàn)方法:隨機(jī)生成一個(gè)數(shù)填充隨機(jī)的還沒有值的數(shù)格,并檢測(cè)該數(shù)所在的行、列和宮格是否已經(jīng)有此數(shù)。如果沒有此數(shù)則賦值,否則跳出。接著,繼續(xù)前面的步驟,直到填充到指定數(shù)目的數(shù)格。4.4.2 使用解題器生成數(shù)獨(dú)題目嚴(yán)格的說,數(shù)獨(dú)題目要求要有唯一解,通過快速法產(chǎn)生的游戲不一定有解,為此需要解題器的幫助以生成有唯一解的數(shù)獨(dú)游戲。實(shí)現(xiàn)方法如下:首先在將一個(gè)隨機(jī)數(shù)填入空白棋盤里隨機(jī)的一個(gè)數(shù)格,然后讓解題器填充上剩下的所有數(shù)格,接下來就是再挖空一定

32、的數(shù)格。這種方法將花費(fèi)比較長的時(shí)間,主要取決于解題器算法的效率。4.4.3 數(shù)獨(dú)解題算法的實(shí)現(xiàn)本游戲開發(fā)使用了解題器插件,它可以提供多種的解題算法,玩家可以選擇相應(yīng)的解題器用于實(shí)現(xiàn)解題和生成題目。解題器默認(rèn)使用的是成熟的算法遞歸回溯實(shí)現(xiàn)的。雖然,理論上遞歸回溯算法需要多次的調(diào)用函數(shù)自己,需增加額外的系統(tǒng)堆棧,可能消耗大量空間,對(duì)執(zhí)行效率有一定的影響。但由于處理的數(shù)獨(dú)游戲數(shù)據(jù)量較小,同時(shí)現(xiàn)在計(jì)算機(jī)的高性能也減小了遞歸回溯對(duì)時(shí)間的影響。因此,默認(rèn)采用了代碼清晰簡(jiǎn)潔,可讀性很強(qiáng)的遞歸算法實(shí)現(xiàn)解題。實(shí)踐證明,成熟的遞歸回溯法解決數(shù)獨(dú)問題,可以有著極快的效果。在遞歸之前,可以通過一點(diǎn)小小的預(yù)處理,可以使

33、遞歸算法時(shí)間縮短,這個(gè)處理可以稱為“有限遞推”13,算法的大致流程圖如圖表 44數(shù)獨(dú)遞歸算法流程圖:圖表 44數(shù)獨(dú)遞歸算法流程圖算法主要如下:(1)建立一個(gè)數(shù)獨(dú)棋盤結(jié)構(gòu)的候選數(shù)列表里面包含了每個(gè)數(shù)格的候選數(shù),對(duì)于已經(jīng)有已知數(shù)的,列表里就只有一個(gè)已知數(shù)。對(duì)于待填數(shù)格,則將所有可能的候選數(shù)填入。(2)然后,“有限遞推”預(yù)處理算法查詢候選數(shù)列表每一行、列和宮格查找已知數(shù)和候選數(shù)有沖突的項(xiàng),并將其從列表移走。執(zhí)行一次就可能確定下一些原來沒有確定的數(shù)字,那么此時(shí),原始的候選數(shù)列表的值必然改變。再在次執(zhí)行此過程修訂列表,而修訂之后若還有數(shù)據(jù)改變,那么就在執(zhí)行此過程了,直到候選數(shù)列表的值不再變化。如此循環(huán)下

34、去,就能最大限度地確定下題目本身含義與規(guī)則而確定下的內(nèi)容。(3)接著,解題器查找包含有最少候選數(shù)的列表,并隨機(jī)選取一個(gè)數(shù)作為正確的數(shù)進(jìn)行猜想。(4)在每一次可能的猜測(cè)過程中,解題器通過深拷貝并實(shí)現(xiàn)遞歸回到步驟(2)。通過這種方式,若當(dāng)前情況無解的時(shí)候回溯,直到所有的候選數(shù)列表有唯一候選數(shù)。(5)當(dāng)所有的猜測(cè)都嘗試之后如果沒有解,則返回false。相反,如果棋盤都被填滿之后,并且驗(yàn)證通過,則表示數(shù)獨(dú)謎題有解。圖表 45解題器類的uml圖解題器的類如圖表 45解題器類的uml圖,該解題器類中包含了解題算法的入口點(diǎn)方法solve(),外部可直接調(diào)用此公共方法進(jìn)行解題。solve()方法中則調(diào)用解題器

35、類私有的遞歸解題方法recursivesolve(),在每次遞歸解題方法調(diào)用自己前,需要使用深度拷貝方法deepcopy()將當(dāng)前對(duì)象的所有字段進(jìn)行執(zhí)行逐位復(fù)制使其支持遞歸回溯。在把所有候選數(shù)都猜測(cè)完后,調(diào)用驗(yàn)證方法validate()進(jìn)行驗(yàn)證。4.5 ui界面設(shè)計(jì)游戲的用戶交互界面主要在一個(gè)窗口中呈現(xiàn),方便用戶操作。標(biāo)題游戲菜單游戲棋盤計(jì)時(shí)器解題器插件圖表 46游戲界面布局如圖表 46游戲界面布局頂端顯示標(biāo)題,左邊是游戲菜單,右邊是游戲計(jì)時(shí)信息,底部是解題器插件,中間是游戲棋盤。當(dāng)然,這些面板都應(yīng)該與分辨率無關(guān),以適應(yīng)不同用戶的顯示器。4.5.1 游戲棋盤設(shè)計(jì)位于中間的游戲棋盤是本游戲的重點(diǎn)

36、。游戲棋盤默認(rèn)繪制的是9×9的標(biāo)準(zhǔn)棋盤,同時(shí)還提供了4×4和16×6規(guī)格的棋盤。棋盤主要通過自定義控件sudokuboard來實(shí)現(xiàn)。sudokuboard是通過一系列的嵌套的itemscontrol控件來繪制展現(xiàn)棋盤。這樣就可以設(shè)置游戲規(guī)格,選擇不同數(shù)目的數(shù)格來實(shí)現(xiàn)生成。除了生成指定大小的棋盤,它至少應(yīng)該具備以功能:(1)迷局生成時(shí)候,棋盤的已知數(shù)是只讀的,亦不可以填入數(shù)字的;(2)在空白的數(shù)格上應(yīng)該可以填入數(shù)字。(3)驗(yàn)證填入數(shù)字合法性,可以根據(jù)當(dāng)前所填數(shù)字的合法性將文字設(shè)為不同的顏色,如果填入的數(shù)字有沖突,則將有沖突的數(shù)字顏色設(shè)為紅色。4.5.2 游戲菜單設(shè)計(jì)

37、游戲菜單放在主窗口的左邊,其中包括了游戲主菜單和游戲室設(shè)置,它們都被放置在expander控件內(nèi),類似于windows操作系統(tǒng)中窗口左邊的任務(wù)欄,可以展開和收縮。游戲主菜單中包含了新游戲按鈕、讀取游戲按鈕、保存游戲按鈕和退出按鈕。游戲設(shè)置菜單中則包含了游戲隨機(jī)生成方法,通過單選按鈕玩家可以選擇游戲的生成方式,一種是快速生成游戲,一種是使用解題器的,后者可以保證生成的數(shù)獨(dú)謎語有答案,不過生成速度慢。下面是時(shí)間難度設(shè)置,玩家可以通過單選按鈕選擇不計(jì)時(shí)的方式或簡(jiǎn)單、中等和困難的時(shí)間難度。再來是,游戲規(guī)格菜單通過下拉框?qū)崿F(xiàn),默認(rèn)選項(xiàng)是9×9的標(biāo)準(zhǔn)游戲規(guī)格。同時(shí)還有4×4的入門級(jí)規(guī)格

38、和挑戰(zhàn)型的16×16規(guī)格。4.5.3 計(jì)時(shí)器設(shè)計(jì)右邊面板放置的計(jì)時(shí)器,以一個(gè)時(shí)鐘的方式實(shí)現(xiàn)。在玩家選擇有時(shí)間難度的游戲后,計(jì)時(shí)器將在新游戲開始時(shí)候自動(dòng)倒計(jì)時(shí)。游戲過程中,當(dāng)被再次點(diǎn)擊之后顏色變暗可以暫停時(shí)間,當(dāng)再次點(diǎn)擊時(shí)可以恢復(fù)倒計(jì)時(shí)。同時(shí)這里也提供了數(shù)字的電子碼表,計(jì)算精度可達(dá)60分之1秒。4.5.4 解題器插件設(shè)計(jì)解題器位于主窗口的底部,它也是被放置于expander控件內(nèi),默認(rèn)情況下是收縮的。在其里面,左部是一個(gè)listbox列出了所有的解題器,用戶可以選擇相應(yīng)的解題器用于生成題目和解題。當(dāng)選擇了相應(yīng)的解題器后,將在右邊出現(xiàn)解題器的相關(guān)信息。listbox下有一個(gè)ai對(duì)戰(zhàn)按鈕,

39、按下之后,將在獨(dú)立線程解題,解題完成后會(huì)將結(jié)果以槽的形式顯示在其右邊。由于是采用獨(dú)立線程解題,所以在解題期間,玩家還可以繼續(xù)做題。4.5.5 其他界面設(shè)計(jì)由于生成題目可能需要較長時(shí)間,因此設(shè)計(jì)了一個(gè)友好的對(duì)話框,當(dāng)選擇新游戲時(shí)候,將在生成游戲期間,彈出一個(gè)對(duì)話框提示玩家。在游戲填充完成并且正確的情況下,將會(huì)彈出對(duì)話框,以告訴玩家填充正確。同時(shí)在指定時(shí)間內(nèi),如果玩家沒有把題目解完,也將彈出時(shí)間結(jié)束的對(duì)話框以告訴玩家。為了不使游戲界面單調(diào),采用動(dòng)畫的效果讓游戲的背景脈動(dòng)起來,擁有類似水波蕩漾的效果。4.6 用戶功能實(shí)現(xiàn)用戶功能模塊是用戶可以直接使用的模塊,主要通過鼠標(biāo)進(jìn)行點(diǎn)擊按鈕,調(diào)用相應(yīng)的事件來

40、處理,這些功能的實(shí)現(xiàn)相對(duì)簡(jiǎn)單。復(fù)雜一些的如讀取游戲、保存游戲功能,需要使用系統(tǒng)的文件服務(wù)來實(shí)現(xiàn)。這些實(shí)現(xiàn)都需要使用具體的代碼來描述,將在第五章詳細(xì)描述。5. 系統(tǒng)實(shí)現(xiàn)系統(tǒng)的實(shí)現(xiàn)主要是通過使用集成開發(fā)工具visual studio 2008進(jìn)行編碼,結(jié)合expression blend進(jìn)行用戶界面的設(shè)計(jì)。編碼工作主要包括了一些游戲的數(shù)據(jù)結(jié)構(gòu)的編寫、游戲的解題器算法的編寫,還有用戶功能的編寫。通過xaml語言實(shí)現(xiàn)了游戲的ui界面。最后通過數(shù)據(jù)綁定和依賴屬性把后臺(tái)數(shù)據(jù)呈現(xiàn)在ui界面上。5.1 數(shù)獨(dú)的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)數(shù)獨(dú)棋盤的數(shù)據(jù)都存放cell類中,而box類的成員gridrows是一個(gè)動(dòng)態(tài)集合里面放的是

41、cell,board類的成員gridrows則放置box。cell類的實(shí)現(xiàn),為了能讓其數(shù)據(jù)成員實(shí)現(xiàn)與ui的數(shù)據(jù)綁定,在此聲明屬性以提供公共數(shù)據(jù)成員便利。通過使用 set訪問器為數(shù)據(jù)成員賦值,使用get訪問器檢索數(shù)據(jù)成員的值。通過讓cell類實(shí)現(xiàn)inotifypropertychanged接口,在更改屬性值時(shí)引發(fā)propertychanged事件,這樣只要數(shù)據(jù)有改變,即可告知監(jiān)視者,通過實(shí)現(xiàn)inotifypropertychanged接口從而實(shí)現(xiàn)了觀察者模式。下面是以屬性value為例:public int? valueget return valuevalue; set if (valueva

42、lue != value)valuevalue = value;if (propertychanged != null)propertychanged(this, new propertychangedeventargs("value");宮格box類也實(shí)現(xiàn)了inotifypropertychanged接口,定義兩個(gè)動(dòng)態(tài)數(shù)據(jù)集合observablecollection的容器,用于獲取cell的實(shí)例。第二個(gè)動(dòng)態(tài)數(shù)據(jù)集合存放的是宮格里的每一行的成員,第一個(gè)動(dòng)態(tài)數(shù)據(jù)集合表示宮格所包含的行,這樣就可以表示一個(gè)宮格。為了能夠讓box正確訪問cell,在box類中添加了一個(gè)索引:pub

43、lic cell thisint row, int col get if (row < 0 | row >= rows.count)throw new argumentoutofrangeexception("row", row, "非法行索引"); if (col < 0 | col >= rows.count) throw new argumentoutofrangeexception("col", col, "非法列索引");return rowsrowcol; board類同理,只是

44、動(dòng)態(tài)數(shù)據(jù)集合observablecollection里面放的是box的實(shí)例,這里不再介紹。5.2 邏輯處理模塊實(shí)現(xiàn)5.2.1 快速隨機(jī)生成數(shù)獨(dú)題目實(shí)現(xiàn)快速隨機(jī)生成數(shù)獨(dú)題目的方法public void generategame(int givens)放在board類中,當(dāng)調(diào)用這個(gè)方法時(shí),需要傳遞一個(gè)參數(shù)givens,表示要生成的已知數(shù)個(gè)數(shù)。在生成棋盤迷局全,要先判斷givens的合法性,避免要生成的已知數(shù)大于棋盤的數(shù)格總數(shù)。在判斷玩合法性后,將棋盤的數(shù)格都置空。定義偽隨機(jī)數(shù)生成器用于生成隨機(jī)數(shù),然后,在小于要生成已知數(shù)的個(gè)數(shù)的的情況下,隨機(jī)選取單元格,放置一個(gè)隨機(jī)生成的數(shù)。如果這個(gè)數(shù)是合法,則將

45、數(shù)格設(shè)為只讀:random rnd = new random();int row = rnd.next(size);int col = rnd.next(size);cell = thisrow, col;/隨機(jī)單元格int baseval = rnd.next(size) + 1;/產(chǎn)生1-9的隨機(jī)數(shù)if (this.isvalid) /如果這個(gè)數(shù)成立,則標(biāo)識(shí)為只讀 cell.readonly = true;givenfound = true;break;5.2.2 使用解題器生成數(shù)獨(dú)題目通過解題器生成游戲generategameusingsolver(isudokusolver s, in

46、t givens)的方法開始也要檢查生成的已知數(shù)數(shù)目的合法性。然后填入一個(gè)隨機(jī)數(shù)到一個(gè)隨機(jī)的數(shù)格,接下來調(diào)用解題器,通過ref關(guān)鍵字使參數(shù)按引用傳遞,然后將解題器填充完成的迷局挖空一定數(shù)目的數(shù)格出來:s.solve(ref a);int r = rnd.next(size);int c = rnd.next(size);cell cell = thisr, c;if (!cell.value.hasvalue)/判斷是否為空值continue;cell.value = null;/將數(shù)格的值置空值5.2.3 解題器實(shí)現(xiàn)解題器默認(rèn)采用的是遞歸的算法,其代碼實(shí)現(xiàn)大致如下:(1)在solve方法中建

47、立一個(gè)矩陣結(jié)構(gòu)的列表possible里面包含了每個(gè)數(shù)格的候選數(shù),對(duì)于已經(jīng)有已知數(shù)的,列表里就只有一個(gè)已知數(shù)。對(duì)于待填數(shù)格,則將所有可能的候選數(shù)填入:if (boardr, c.hasvalue) br, c.add(math.abs(boardr, c.value);/如果數(shù)格已經(jīng)有值,將其添加到列表else for (int i = 1; i <= board.getlength(0); i+) br, c.add(i);(2)然后,有限遞推預(yù)處理,用changemade來標(biāo)識(shí)處理過程possible矩陣列表的值是否有變。處理過程中查詢每一行、列和宮格查找已知數(shù)和候選數(shù)有沖突的項(xiàng),并將

48、其從列表移走,重復(fù)這一步驟,直到changemade的值為false:dochangemade = false;for (int r = 0; r < size; r+) /遍歷行,除去當(dāng)前行已有的數(shù)字 list<int> toremove = new list<int>(); /保存排除后的結(jié)果 for (int c = 0; c < size; c+)/只剩一個(gè)數(shù)時(shí),將其放到數(shù)組的首元素 if (boardr, c.count = 1) toremove.add(boardr, c0); for (int c = 0; c < size; c+)

49、if (boardr, c.count > 1) foreach (int i in toremove) if (boardr, c.remove(i) changemade = true; while (changemade);(3)接著,解題器查找包含有最少候選數(shù)的列表,進(jìn)行猜測(cè),隨機(jī)選取里面一個(gè)數(shù)作為正確的數(shù):for (int r = 0; r < size; r+)for (int c = 0; c < size; c+)if (boardr, c.count = 0) return false;else if (boardr, c.count > 1 &

50、;& boardr, c.count < size)minr = r;minc = c;size = boardr, c.count;(4)在每一次可能的猜測(cè)過程中,解題器通過深拷貝deepcopy并實(shí)現(xiàn)遞歸。通過這種方式,直到填滿數(shù)格。if (recursivesolve(ref c) /遞歸調(diào)用board = c;return true;(5)當(dāng)所有的猜測(cè)都嘗試之后如果沒有解,則返回false。相反,如果棋盤都被填滿之后,并且都只含有一個(gè)答案,則表示數(shù)獨(dú)謎題有解。5.3 ui界面實(shí)現(xiàn)ui界面主要通過可擴(kuò)展應(yīng)用程序標(biāo)記語言 (xaml)編寫。根據(jù)設(shè)計(jì)階段的設(shè)計(jì),游戲界面要與分辨

51、率無關(guān),而且能夠動(dòng)態(tài)調(diào)整大小。為此采用使用dockpanel,它可以用于沿布局容器的邊緣定位子內(nèi)容,這樣當(dāng)游戲窗口變大了,窗口中的面板布局也不會(huì)亂掉。通過dockpanel.dock 附加屬性將不同控件定位在一個(gè)dockpanel內(nèi)的不同位置:5.3.1 游戲菜單實(shí)現(xiàn)游戲主菜單被放置于一個(gè)expander控件中,通過按鈕可以收縮隱藏菜單包含有游戲菜單,如圖表 51游戲菜單。圖表 51游戲菜單游戲主菜單,包括新游戲、讀取游戲、保存游戲、手動(dòng)創(chuàng)建游戲、退出按鈕選項(xiàng),當(dāng)點(diǎn)擊后,將有相應(yīng)的處理事件。游戲設(shè)置也是放置于一個(gè)expander控件中,包含游戲生成方法,游戲計(jì)時(shí)難度選擇,游戲規(guī)格的子設(shè)置模塊。

52、游戲設(shè)置菜單如圖表 52游戲設(shè)置菜單:圖表 52游戲設(shè)置菜單游戲的生成方法,通過單選按鈕(radiobutton)來選擇,選項(xiàng)有快速生成和使用解題器的生成方法:<radiobutton ischecked ="true" x:name ="fastgenradio">快速生成(可能解)</radiobutton><radiobutton x:name="solvergenradio">使用解題器</radiobutton>游戲的時(shí)間難度選擇,通過單選按鈕實(shí)現(xiàn)??梢赃x擇沒有計(jì)時(shí)器計(jì)時(shí)或有計(jì)

53、時(shí)器倒計(jì)時(shí)的,難度從簡(jiǎn)單、中等到困難,默認(rèn)選中選為簡(jiǎn)單。5.3.2 數(shù)獨(dú)棋盤實(shí)現(xiàn)游戲棋盤默認(rèn)繪制的是9×9的標(biāo)準(zhǔn)棋盤,當(dāng)用戶在游戲設(shè)置菜單選擇不同的游戲規(guī)格后,在點(diǎn)擊新游戲后,將產(chǎn)生不同大小規(guī)格的游戲棋盤。其實(shí)現(xiàn)是在mainboard.xaml的頭部加入“xmlns:clr="clr-namespace:sudokuwpf.usercontrols"”從而可以使用自定義控件。然后在主游戲面板加入以下代碼,便可繪制棋盤。<clr:sudokuboard x:name="board" horizontalalignment="str

54、etch" margin="5"/>在自定義控件sudokuboard中,在每一個(gè)最小的單位數(shù)格中都有一個(gè)textblock用于顯示數(shù)字,它里面的text屬性綁定了value的值,在鼠標(biāo)右擊點(diǎn)擊單元格的時(shí)候,會(huì)相應(yīng)的彈出一個(gè)listbox,并顯示了相應(yīng)的候選數(shù),當(dāng)用戶選擇相應(yīng)的數(shù)字可以填充數(shù)個(gè)。這主要是是通過以下代碼通過綁定實(shí)現(xiàn)的:<listbox selecteditem ="binding path=value,mode=twoway" datacontext ="binding relativesource =rel

55、ativesource templatedparent,path=datacontext" itemssource="binding path=possiblevalues"/>其中itemssource綁定的為候選數(shù)的值,這樣根據(jù)游戲規(guī)格的不同,listbox中的選擇項(xiàng)也會(huì)跟著不同。如圖表 53游戲棋盤與填充菜單所示是9×9規(guī)格的標(biāo)準(zhǔn)棋盤,具有藍(lán)色玻璃外觀上的數(shù)字為已知數(shù),通過鼠標(biāo)右鍵點(diǎn)擊待填空格,可以彈出候選數(shù)菜單用于向空的數(shù)格填入數(shù)字。 圖表 53游戲棋盤與填充菜單當(dāng)玩家填充的數(shù)字是有沖突的,即所填數(shù)字的是isvaild的值為false時(shí)候,

56、顏色將變?yōu)榧t色。這主要是通過datatrigger觸發(fā)實(shí)現(xiàn)的,其主要代碼如下:<datatrigger binding ="binding isvalid" value ="false"><setter targetname ="textblock" property ="foreground" value="red"/></datatrigger>這個(gè)功能在一定程度上提醒了玩家所填數(shù)字的合法性,效果如圖表 54填入數(shù)字非法的提示。圖表 54填入數(shù)字非法的提示

57、5.3.3 計(jì)時(shí)器實(shí)現(xiàn)圖表 55計(jì)時(shí)器的三種狀態(tài)、計(jì)時(shí)器的實(shí)現(xiàn)是通過使用自定義控件stopwach來實(shí)現(xiàn)的。如圖表 55計(jì)時(shí)器的三種狀態(tài),計(jì)時(shí)器擁有三種狀態(tài),當(dāng)用戶選用的是有計(jì)時(shí)器的狀態(tài),計(jì)時(shí)器顏色偏亮,其主要是通過外發(fā)光(outerglowbitmapeffect)來實(shí)現(xiàn):<rectangle.bitmapeffect><outerglowbitmapeffect glowsize="10" glowcolor ="limegreen"/></rectangle.bitmapeffect>當(dāng)暫停計(jì)時(shí),顏色變暗,上方數(shù)字也停止變動(dòng)。未啟用計(jì)時(shí)器則是通過禁用計(jì)時(shí)器面板,并將計(jì)時(shí)器面板的opacity屬性設(shè)為0.25。計(jì)時(shí)器上的數(shù)字跳動(dòng),則是通過storyboard定義了一組動(dòng)畫,里面有時(shí)間變化:<!-計(jì)時(shí)器動(dòng)畫提供對(duì)象和屬性目標(biāo)信息的容器時(shí)間線-><storyboard x:key ="timeranimation"

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論