版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
图表41系统模块图,实线连接的为用户可见模块,用户模块是用户可通过鼠标操作的模块;UI模块为呈现给用户的界面;虚线连接的为不可见模块(数据处理模块),即内部实现模块。模块内部关系说明模块内部关系说明模块之间的联系是通过内部数据实现的,下面介绍模块之间的联系。图表STYLEREF1\s4SEQ图表\*ARABIC\s12模块关系图REF_Ref261030776\h图表42模块关系图所示模块设计相对独立,各个模块都是通过内部数据进行联系的。游戏内核包括所有游戏信息,全部为类的成员数据,而它的各个模块则为类的方法(函数)用于相应用户的按键事件。绘图(UI)功能,向用户显示游戏的信息,包括数独游戏迷局、计时器、游戏菜单等,这些主要由XAML来实现。当用户按键时触发UI的绘图,同时后台的代码处理按键事件,从而使得绑定到前台的内部数据改变。AI功能负责内部数据的处理,是该游戏的核心,所有功能的实现几乎都与本模块有关,包括数独迷局游戏生成、数独填充完成的验证、数独的AI解题等。AI模块由很多松散的方法组成,各个函数实现单一的功能,便于修改和移植。数独的数据结构设计由于数独游戏的特殊性和模块设计的独立性,各个模块间的通信必须依靠全局变量来实现。在此,设计类用以封装所需要的字段和方法,这样就可以实现游戏的大部分功能。对于这个类中的函数(方法),类的成员数据相当于全局变量,这样各个函数的通信就不会成为问题。图表STYLEREF1\s4SEQ图表\*ARABIC\s13数独结构图通过观察一个典型的9×9数独如REF_Ref261030555\h图表43数独结构图,数独是由3×3个宫格组成,而每个宫格又可以由3×3个数格组成,在此将其棋盘抽象为最小的数格。棋盘预先放入的已知数应该是只读的,不可以修改,同时应该有用于标志数字是否合法的字段。主要数据表示方法:(1)棋盘的最小单位——数格用Cell类定义。定义字段valueValue存放数字,readOnlyValue标识数格是否为只读数据,possibleValuesValue存放可填入的数,isValidValue标识数数格是否成立。(2)宫格用Box类定义。动态数据集合Rows存放宫格里数格,isValidValue标识值是否成立。(3)数独棋盘用Board类定义。Board类及其类似Box类,只是字段动态数据集合Rows存放的是数独棋盘里的宫格,isValidValue标识填入的数是否成立,isFullValue标识棋盘是否填满。逻辑处理设计逻辑处理部分主要涉及到的是题目的生成方法,默认的题目生成方式采用随机生成的方法,速度较快,但生成的题目不一定有解。在玩家选择相应的解题器后,可以通过解题器产生有解的题目。快速随即生成数独题目一种创建数独迷局的方法是通过使用穷举法(BruteForce),通过这种方法可以快速生成大量不同的题目。在2005年,数学家贝米耳与罗思坦算出一共有6670903752021072936960种可能的数独谜题[11][11]BertramFelgenhauer&FrazerJarvis.Thereare6670903752021072936960Sudokugrids[EB/OL].http://www.afjarvis.staff.shef.ac.uk/sudoku/.好的数独题目要求要有唯一解而且已知数要越少越好。目前,对于9×9的数独只要18个数字就可以产生出唯一解的数独谜题。如果不要求对称,给定的数字是17个就可以产生有解的数独题目,通过使用17个已知数,数学家GordonRoyle发现了35396这样不同的难题[12]GordonRoyle.MinimumSudoku[EB/OL].[12]GordonRoyle.MinimumSudoku[EB/OL]..au/~gordon/sudokumin.php.本游戏采用的快速生成游戏的实现方法:随机生成一个数填充随机的还没有值的数格,并检测该数所在的行、列和宫格是否已经有此数。如果没有此数则赋值,否则跳出。接着,继续前面的步骤,直到填充到指定数目的数格。使用解题器生成数独题目严格的说,数独题目要求要有唯一解,通过快速法产生的游戏不一定有解,为此需要解题器的帮助以生成有唯一解的数独游戏。实现方法如下:首先在将一个随机数填入空白棋盘里随机的一个数格,然后让解题器填充上剩下的所有数格,接下来就是再挖空一定的数格。这种方法将花费比较长的时间,主要取决于解题器算法的效率。数独解题算法的实现本游戏开发使用了解题器插件,它可以提供多种的解题算法,玩家可以选择相应的解题器用于实现解题和生成题目。解题器默认使用的是成熟的算法——递归回溯实现的。虽然,理论上递归回溯算法需要多次的调用函数自己,需增加额外的系统堆栈,可能消耗大量空间,对执行效率有一定的影响。但由于处理的数独游戏数据量较小,同时现在计算机的高性能也减小了递归回溯对时间的影响。因此,默认采用了代码清晰简洁,可读性很强的递归算法实现解题。实践证明,成熟的递归回溯法解决数独问题,可以有着极快的效果。在递归之前,可以通过一点小小的预处理,可以使递归算法时间缩短,这个处理可以称为“有限递推”[13]雷蕾,沈富可.关于数独问题的算法的设计与实现[J].电脑知识与技术:481-482.[14]VictorGaudioso.FoundationExpressionBlend2BuildingApplicationsinWPFandSilverlight[M].USA.ApressandfriendsofED,2008.[15]LucasMagder.Coding4Fun[EB/OL]/coding4fun/.DevelopmentoftheSudokuGameBasedonWPF[13]雷蕾,沈富可.关于数独问题的算法的设计与实现[J].电脑知识与技术:481-482.[14]VictorGaudioso.FoundationExpressionBlend2BuildingApplicationsinWPFandSilverlight[M].USA.ApressandfriendsofED,2008.[15]LucasMagder.Coding4Fun[EB/OL]/coding4fun/.DevelopmentoftheSudokuGameBasedonWPFMathematicsandComputerScienceDepartmentMajor:ComputerScienceandTechnology118532006068CaiChunshengInstructor:LinWei-wei【Abstract】Sudoku,thenamesuggests-eachnumbercanonlyappearonce.Playersmustfillann×nmatrix,whichcontainssomegivenentries,sothateachrow,columns,andtheboxescontainseachinterger1throughnexactlyonce.Thisgameisfullychallengeplayer’sobservationandlogicability.Althoughgamesareplayedsimple,thefigureisever-changingarrangement.Therefore,manyeducatorsthinkthatSudokuisagreatwaytotrainthebrain.Therefore,somescientistsandresearchershavesuggestedthatthenumberofindependentgamesasapartofdailyactivities.Thegamewillbedevelopedunder.NETFramework3.5.ThemaintechnologyisWPF(WindowsPresentationFoundation),whichisMicrosoft'snext-generationgraphicssystems.BasedonDirectX9/10technology,WPFhasnotonlybroughtunprecedented3Dinterface,anditsvectorgraphicsrenderingengineisalsogreatlyimprovedthetraditional2Dinterface.ThroughtheWPF,.NETFramework3.5providesamorecompleteandconsistentsolutionforproblemsofuserinterface.WithWPF,programmerswillbemoreeffectiveworktodevelopcomparableMacprogram’scoolinterface.ThispaperfocusesonWPFtechnology,todevelopabeautifulWindowsgames-Sudoku.ThispaperdescribestheWPFtechnologyandstructuralanalysisofthisprogramandtherealizationofspecificfunctions.【Keywords】Sudoku;WPF;C#;XAML图表STYLEREF1\s4SEQ图表\*ARABIC\s14数独递归算法流程图算法主要如下:(1)建立一个数独棋盘结构的候选数列表里面包含了每个数格的候选数,对于已经有已知数的,列表里就只有一个已知数。对于待填数格,则将所有可能的候选数填入。(2)然后,“有限递推”预处理算法查询候选数列表每一行、列和宫格查找已知数和候选数有冲突的项,并将其从列表移走。执行一次就可能确定下一些原来没有确定的数字,那么此时,原始的候选数列表的值必然改变。再在次执行此过程修订列表,而修订之后若还有数据改变,那么就在执行此过程了,直到候选数列表的值不再变化。如此循环下去,就能最大限度地确定下题目本身含义与规则而确定下的内容。(3)接着,解题器查找包含有最少候选数的列表,并随机选取一个数作为正确的数进行猜想。(4)在每一次可能的猜测过程中,解题器通过深拷贝并实现递归回到步骤(2)。通过这种方式,若当前情况无解的时候回溯,直到所有的候选数列表有唯一候选数。(5)当所有的猜测都尝试之后如果没有解,则返回false。相反,如果棋盘都被填满之后,并且验证通过,则表示数独谜题有解。图表STYLEREF1\s4SEQ图表\*ARABIC\s15解题器类的UML图解题器的类如REF_Ref261030638\h图表45解题器类的UML图,该解题器类中包含了解题算法的入口点方法Solve(),外部可直接调用此公共方法进行解题。Solve()方法中则调用解题器类私有的递归解题方法RecursiveSolve(),在每次递归解题方法调用自己前,需要使用深度拷贝方法DeepCopy()将当前对象的所有字段进行执行逐位复制使其支持递归回溯。在把所有候选数都猜测完后,调用验证方法Validate()进行验证。UI界面设计游戏的用户交互界面主要在一个窗口中呈现,方便用户操作。标题游戏菜单游戏棋盘计时器解题器插件图表STYLEREF1\s4SEQ图表\*ARABIC\s16游戏界面布局如REF_Ref261030702\h图表46游戏界面布局顶端显示标题,左边是游戏菜单,右边是游戏计时信息,底部是解题器插件,中间是游戏棋盘。当然,这些面板都应该与分辨率无关,以适应不同用户的显示器。游戏棋盘设计位于中间的游戏棋盘是本游戏的重点。游戏棋盘默认绘制的是9×9的标准棋盘,同时还提供了4×4和16×6规格的棋盘。棋盘主要通过自定义控件SudokuBoard来实现。SudokuBoard是通过一系列的嵌套的ItemsControl控件来绘制展现棋盘。这样就可以设置游戏规格,选择不同数目的数格来实现生成。除了生成指定大小的棋盘,它至少应该具备以功能:(1)迷局生成时候,棋盘的已知数是只读的,亦不可以填入数字的;(2)在空白的数格上应该可以填入数字。(3)验证填入数字合法性,可以根据当前所填数字的合法性将文字设为不同的颜色,如果填入的数字有冲突,则将有冲突的数字颜色设为红色。游戏菜单设计游戏菜单放在主窗口的左边,其中包括了游戏主菜单和游戏室设置,它们都被放置在Expander控件内,类似于Windows操作系统中窗口左边的任务栏,可以展开和收缩。游戏主菜单中包含了新游戏按钮、读取游戏按钮、保存游戏按钮和退出按钮。游戏设置菜单中则包含了游戏随机生成方法,通过单选按钮玩家可以选择游戏的生成方式,一种是快速生成游戏,一种是使用解题器的,后者可以保证生成的数独谜语有答案,不过生成速度慢。下面是时间难度设置,玩家可以通过单选按钮选择不计时的方式或简单、中等和困难的时间难度。再来是,游戏规格菜单通过下拉框实现,默认选项是9×9的标准游戏规格。同时还有4×4的入门级规格和挑战型的16×16规格。计时器设计右边面板放置的计时器,以一个时钟的方式实现。在玩家选择有时间难度的游戏后,计时器将在新游戏开始时候自动倒计时。游戏过程中,当被再次点击之后颜色变暗可以暂停时间,当再次点击时可以恢复倒计时。同时这里也提供了数字的电子码表,计算精度可达60分之1秒。解题器插件设计解题器位于主窗口的底部,它也是被放置于Expander控件内,默认情况下是收缩的。在其里面,左部是一个ListBox列出了所有的解题器,用户可以选择相应的解题器用于生成题目和解题。当选择了相应的解题器后,将在右边出现解题器的相关信息。ListBox下有一个AI对战按钮,按下之后,将在独立线程解题,解题完成后会将结果以槽的形式显示在其右边。由于是采用独立线程解题,所以在解题期间,玩家还可以继续做题。其他界面设计由于生成题目可能需要较长时间,因此设计了一个友好的对话框,当选择新游戏时候,将在生成游戏期间,弹出一个对话框提示玩家。在游戏填充完成并且正确的情况下,将会弹出对话框,以告诉玩家填充正确。同时在指定时间内,如果玩家没有把题目解完,也将弹出时间结束的对话框以告诉玩家。为了不使游戏界面单调,采用动画的效果让游戏的背景脉动起来,拥有类似水波荡漾的效果。用户功能实现用户功能模块是用户可以直接使用的模块,主要通过鼠标进行点击按钮,调用相应的事件来处理,这些功能的实现相对简单。复杂一些的如读取游戏、保存游戏功能,需要使用系统的文件服务来实现。这些实现都需要使用具体的代码来描述,将在第五章详细描述。系统实现系统的实现主要是通过使用集成开发工具VisualStudio2008进行编码,结合ExpressionBlend进行用户界面的设计。编码工作主要包括了一些游戏的数据结构的编写、游戏的解题器算法的编写,还有用户功能的编写。通过XAML语言实现了游戏的UI界面。最后通过数据绑定和依赖属性把后台数据呈现在UI界面上。数独的数据结构实现数独棋盘的数据都存放Cell类中,而Box类的成员GridRows是一个动态集合里面放的是Cell,Board类的成员GridRows则放置Box。Cell类的实现,为了能让其数据成员实现与UI的数据绑定,在此声明属性以提供公共数据成员便利。通过使用set访问器为数据成员赋值,使用get访问器检索数据成员的值。通过让Cell类实现INotifyPropertyChanged接口,在更改属性值时引发PropertyChanged事件,这样只要数据有改变,即可告知监视者,通过实现INotifyPropertyChanged接口从而实现了观察者模式。下面是以属性Value为例:publicint?Value{get{returnvalueValue;}set{if(valueValue!=value){valueValue=value;if(PropertyChanged!=null)PropertyChanged(this,newPropertyChangedEventArgs("Value"));}}}宫格Box类也实现了INotifyPropertyChanged接口,定义两个动态数据集合ObservableCollection的容器,用于获取Cell的实例。第二个动态数据集合存放的是宫格里的每一行的成员,第一个动态数据集合表示宫格所包含的行,这样就可以表示一个宫格。为了能够让Box正确访问Cell,在Box类中添加了一个索引:publicCellthis[introw,intcol]{get{if(row<0||row>=Rows.Count)thrownewArgumentOutOfRangeException("row",row,"非法行索引");if(col<0||col>=Rows.Count)thrownewArgumentOutOfRangeException("col",col,"非法列索引");returnRows[row][col];}}Board类同理,只是动态数据集合ObservableCollection里面放的是Box的实例,这里不再介绍。逻辑处理模块实现快速随机生成数独题目实现快速随机生成数独题目的方法publicvoidGenerateGame(intgivens)放在Board类中,当调用这个方法时,需要传递一个参数givens,表示要生成的已知数个数。在生成棋盘迷局全,要先判断givens的合法性,避免要生成的已知数大于棋盘的数格总数。在判断玩合法性后,将棋盘的数格都置空。定义伪随机数生成器用于生成随机数,然后,在小于要生成已知数的个数的的情况下,随机选取单元格,放置一个随机生成的数。如果这个数是合法,则将数格设为只读:Randomrnd=newRandom();introw=rnd.Next(size);intcol=rnd.Next(size);cell=this[row,col];//随机单元格intbaseVal=rnd.Next(size)+1;//产生1-9的随机数if(this.IsValid){//如果这个数成立,则标识为只读cell.ReadOnly=true;givenFound=true;break;}使用解题器生成数独题目通过解题器生成游戏GenerateGameUsingSolver(ISudokuSolvers,intgivens)的方法开始也要检查生成的已知数数目的合法性。然后填入一个随机数到一个随机的数格,接下来调用解题器,通过ref关键字使参数按引用传递,然后将解题器填充完成的迷局挖空一定数目的数格出来:s.Solve(refa);intr=rnd.Next(size);intc=rnd.Next(size);Cellcell=this[r,c];if(!cell.Value.HasValue) //判断是否为空值continue;cell.Value=null; //将数格的值置空值解题器实现解题器默认采用的是递归的算法,其代码实现大致如下:(1)在Solve方法中建立一个矩阵结构的列表possible里面包含了每个数格的候选数,对于已经有已知数的,列表里就只有一个已知数。对于待填数格,则将所有可能的候选数填入:if(board[r,c].HasValue){b[r,c].Add(Math.Abs(board[r,c].Value));//如果数格已经有值,将其添加到列表}else{for(inti=1;i<=board.GetLength(0);i++){b[r,c].Add(i);}(2)然后,有限递推预处理,用changeMade来标识处理过程possible矩阵列表的值是否有变。处理过程中查询每一行、列和宫格查找已知数和候选数有冲突的项,并将其从列表移走,重复这一步骤,直到changeMade的值为false:do{changeMade=false;for(intr=0;r<size;r++){//遍历行,除去当前行已有的数字List<int>toRemove=newList<int>();//保存排除后的结果for(intc=0;c<size;c++){ //只剩一个数时,将其放到数组的首元素if(board[r,c].Count==1)toRemove.Add(board[r,c][0]);}for(intc=0;c<size;c++){if(board[r,c].Count>1){foreach(intiintoRemove){if(board[r,c].Remove(i))changeMade=true;}}}}……}while(changeMade);(3)接着,解题器查找包含有最少候选数的列表,进行猜测,随机选取里面一个数作为正确的数:for(intr=0;r<size;r++){for(intc=0;c<size;c++){if(board[r,c].Count==0){returnfalse;}elseif(board[r,c].Count>1&&board[r,c].Count<size){minr=r;minc=c;size=board[r,c].Count;}}}(4)在每一次可能的猜测过程中,解题器通过深拷贝DeepCopy并实现递归。通过这种方式,直到填满数格。if(RecursiveSolve(refc)){//递归调用board=c;returntrue;}(5)当所有的猜测都尝试之后如果没有解,则返回false。相反,如果棋盘都被填满之后,并且都只含有一个答案,则表示数独谜题有解。UI界面实现UI界面主要通过可扩展应用程序标记语言(XAML)编写。根据设计阶段的设计,游戏界面要与分辨率无关,而且能够动态调整大小。为此采用使用DockPanel,它可以用于沿布局容器的边缘定位子内容,这样当游戏窗口变大了,窗口中的面板布局也不会乱掉。通过DockPanel.Dock附加属性将不同控件定位在一个DockPanel内的不同位置:游戏菜单实现游戏主菜单被放置于一个Expander控件中,通过按钮可以收缩隐藏菜单包含有游戏菜单,如REF_Ref261031136\h图表51游戏菜单。图表STYLEREF1\s5SEQ图表\*ARABIC\s11游戏菜单游戏主菜单,包括新游戏、读取游戏、保存游戏、手动创建游戏、退出按钮选项,当点击后,将有相应的处理事件。游戏设置也是放置于一个Expander控件中,包含游戏生成方法,游戏计时难度选择,游戏规格的子设置模块。游戏设置菜单如REF_Ref261031098\h图表52游戏设置菜单:图表STYLEREF1\s5SEQ图表\*ARABIC\s12游戏设置菜单游戏的生成方法,通过单选按钮(RadioButton)来选择,选项有快速生成和使用解题器的生成方法:<RadioButtonIsChecked="True"x:Name="FastGenRadio">快速生成(可能解)</RadioButton><RadioButtonx:Name="SolverGenRadio">使用解题器</RadioButton>游戏的时间难度选择,通过单选按钮实现。可以选择没有计时器计时或有计时器倒计时的,难度从简单、中等到困难,默认选中选为简单。数独棋盘实现游戏棋盘默认绘制的是9×9的标准棋盘,当用户在游戏设置菜单选择不同的游戏规格后,在点击新游戏后,将产生不同大小规格的游戏棋盘。其实现是在MainBoard.xaml的头部加入“xmlns:clr="clr-namespace:SudokuWPF.UserControls"”从而可以使用自定义控件。然后在主游戏面板加入以下代码,便可绘制棋盘。<clr:SudokuBoardx:Name="Board"HorizontalAlignment="Stretch"Margin="5"/>在自定义控件SudokuBoard中,在每一个最小的单位数格中都有一个TextBlock用于显示数字,它里面的Text属性绑定了value的值,在鼠标右击点击单元格的时候,会相应的弹出一个ListBox,并显示了相应的候选数,当用户选择相应的数字可以填充数个。这主要是是通过以下代码通过绑定实现的:<ListBoxSelectedItem="{BindingPath=Value,Mode=TwoWay}"DataContext="{BindingRelativeSource}={RelativeSourceTemplatedParent},Path=DataContext}"ItemsSource="{BindingPath=PossibleValues}"/>其中ItemsSource绑定的为候选数的值,这样根据游戏规格的不同,ListBox中的选择项也会跟着不同。如REF_Ref261031172\h图表53游戏棋盘与填充菜单所示是9×9规格的标准棋盘,具有蓝色玻璃外观上的数字为已知数,通过鼠标右键点击待填空格,可以弹出候选数菜单用于向空的数格填入数字。图表STYLEREF1\s5SEQ图表\*ARABIC\s13游戏棋盘与填充菜单当玩家填充的数字是有冲突的,即所填数字的是IsVaild的值为false时候,颜色将变为红色。这主要是通过DataTrigger触发实现的,其主要代码如下:<DataTriggerBinding="{BindingIsValid}"Value="False"><SetterTargetName="TextBlock"Property="Foreground"Value="Red"/></DataTrigger>这个功能在一定程度上提醒了玩家所填数字的合法性,效果如REF_Ref261031201\h图表54填入数字非法的提示。图表STYLEREF1\s5SEQ图表\*ARABIC\s14填入数字非法的提示计时器实现图表STYLEREF1\s5SEQ图表\*ARABIC\s15计时器的三种状态、计时器的实现是通过使用自定义控件Stopwach来实现的。如REF_Ref261031229\h图表55计时器的三种状态,计时器拥有三种状态,当用户选用的是有计时器的状态,计时器颜色偏亮,其主要是通过外发光(OuterGlowBitmapEffect)来实现:<Rectangle.BitmapEffect><OuterGlowBitmapEffectGlowSize="10"GlowColor="LimeGreen"/></Rectangle.BitmapEffect>当暂停计时,颜色变暗,上方数字也停止变动。未启用计时器则是通过禁用计时器面板,并将计时器面板的Opacity属性设为0.25。计时器上的数字跳动,则是通过StoryBoard定义了一组动画,里面有时间变化:<!--计时器动画提供对象和属性目标信息的容器时间线--><Storyboardx:Key="TimerAnimation"><DoubleAnimationFrom="0"To="1"Storyboard.TargetName="StopWatchControl"Duration="0:2:0"Storyboard.TargetProperty="CurrentTime"/><Int32AnimationFrom="1"To="0"Storyboard.TargetName="MinNumber"Storyboard.TargetProperty="Tag"Duration="0:2:0"/><Int32AnimationFrom="59"To="0"RepeatBehavior="Forever"Storyboard.TargetName="SecNumber"Storyboard.TargetProperty="Tag"Duration="0:1:0"/><Int32AnimationFrom="59"To="0"RepeatBehavior="Forever"Storyboard.TargetName="SubSecNumber"Storyboard.TargetProperty="Tag"Duration="0:0:1"/></Storyboard>解题器实现解题器REF_Ref261031253\h图表56解题器,被放置于Expander控件内。在其里面,左边有一个ListBox列出了所有的解题器,用户可以选择相应的解题器用于生成题目和解题。当选择了相应的解题器后,将在右边出现解题器的相关信息。ListBox下有一个AI对战按钮,用于人机对战,按下之后,将在独立线程解题,解题完成后会将结果以槽的形式显示在其中间。图表STYLEREF1\s5SEQ图表\*ARABIC\s16解题器其他界面实现其他界面的设计主要目的,是为了让界面看起来更友好、美观,不至于那么单调,充分发挥了WPF的优势。游戏的背景类似水波荡漾的效果是通过触发器,在“Control.Loaded”时候触发一组动画。标题的倒影效果则是通过VisualBrush的渲染实现。程序的开始运行时标题的特效也是通过LinearDoubleKeyFram使用线性内插,在前一个关键帧和自己的Value之间进行动画处理来实现。游戏的其他界面如友好的对话框如,对话框显示“请稍后”,等提示玩家的界面相对简单,这里不再做介绍。用户功能模块实现新游戏实现当用花按下新游戏按钮的时候,将产生新的游戏。调用后台的NewGame_Click处理,其主要根据当前所选择游戏规格设置GameBoard大小,如果是快速生成方式,调用GenerateGame方法产生谜题。使用解题器的方式由于耗时较多,因此定义了一个BackgroundWorker使得生成谜题时候算法在单独的线程上执行操作,主要代码如下:ISudokuSolversol=SolverList.SelectedItemasISudokuSolver;//所使用算法为列表选项solverWorker=newBackgroundWorker();//初始化solverWorker.DoWork+=newDoWorkEventHandler(delegate(objectdwsender,DoWorkEventArgsdwe) //DoWorkEventHandler{b.GenerateGameUsingSolver(sol,givens); //调用使用解题器的生成游戏方法});solverWorker.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(delegate(objectrwcsender,RunWorkerCompletedEventArgsrwce){//当后台操作已完成时Board.GameBoard.PropertyChanged+=newSystem.ComponentModel.PropertyChangedEventHandler(GameBoard_PropertyChanged);//监视棋盘是否填满});保存游戏、读取游戏实现按下保存游戏按钮的时候,将弹出保存文件的对话框。当按下保存按钮的时候,将以二进制格式将对象系列化为流将其写入磁盘:if(sfd.ShowDialog(this)==true){Streams=newFileStream(sfd.SafeFileName,FileMode.Create);IFormatterf=newBinaryFormatter();//以二进制格式将对象序列化f.Serialize(s,Board.GameBoard.ToArray());//将对象棋盘对象序列化为所提供的流s.Close();}读取游戏过程也是相类似的,是保存游戏的逆过程。当选择打开后,若读取失败后通过消息框提示。否则将所读的流反序列化。游戏设定游戏的时间难度是在生成游戏的时候,通过判断单选按钮来设置的。当选择没计时器的时候,时间面板将被禁用,计时器也会被设为禁用。如果有选择时间难度,则根据所选项,进行时间的相应设置,将时间设置为不同的长度。计时功能实现在计时器上添加Checked="ResumeTimer"Unchecked="PauseTimer",当点击计时器的时候,将由PauseTimer事件来处理。通过将动画暂停,Pause使得时间停止走动,并把棋盘禁用掉,使得游戏不能进行。再次点击时候则调用ResumeTimer,将时间恢复,并将棋盘设为可用。解题器插件实现解题器里有一个ListBox列出了所有的解题器,用户可以选择相应的解题器用于生成题目和解题。当选择了相应的解题器后,将在右边出现解题器的相关信息。ListBox下有一个AI对战按钮,用于人机对战,按下之后,将在独立线程解题。在解题的同时,玩家还可以继续游戏。在题目解出后,会将时间以状态条的形式显示出来,状态条上绘制有相应的时间,如REF_Ref261031279\h图表57解题器绘制的状态条:图表STYLEREF1\s5SEQ图表\*ARABIC\s17解题器绘制的状态条测试打包的过程打包在使用VisualStudio完成代码的编码与调试后,生成WPF应用程序后,需要部署它们,在此采用WindowsInstaller进行部署。通过WindowsInstaller,将应用程序打包为独立的可执行程序,它们可以容易地分发到客户端并运行。而且,WindowsInstaller随Windows安装,从而能与桌面、“开始”菜单和“添加/删除程序”控制面板集成。在VisualStudio中,添加一个SudokuSetup的“安装”项目,它能将文件安装到目标计算机的文件系统中。在“文件系统”的“目标计算机上的文件系统”节点下选中“应用程序文件夹”,添加一个名为“Sudoku”的文件夹。接下来,该文件夹“添加项目输出对话框”在该对话框中的“项目”下拉列表框中选择要部署的应用程序SudokuWPF,然后选择要输出的类型。这里选择主输出,即可将项目输出文件添加到SudokuSetup安装项目中。为了使程序能够在客户端运行,需要添加依赖项。在“Sudoku”文件夹下选择要添加的内容文件,单击“打开”按钮即可将选中的内容文件添加到安装项目中,这里需要添加的是解题器Solvers的文件夹和自制的题库。创建主输出来之SudokuWPF(活动)的快捷方式,将其拖动到目标计算机上的文件系统的桌面目录。“安装”项目的文件系统的配置如REF_Ref261031322\h图表61SudokuSetup的“安装”项目的文件系统配置。图表STYLEREF1\s6SEQ图表\*ARABIC\s11SudokuSetup的“安装”项目的文件系统配置在添加数独游戏所需的项目输出文件、内容文件、快捷方式等内容后,在“解决方案资源管理器”中的SudokuSetup单击生成,即可生成的WindowsInstaller软件包,如REF_Ref261031376\h图表62SudokuSetup软件包。图表STYLEREF1\s6SEQ图表\*ARABIC\s12SudokuSetup软件包由于测试在编码调试过程中已经基本完成,所以本阶段的测试是在程序打包后,将游戏分发给不同玩家使用,以期望发现BUG。发现的BUG及解决情况几乎每一个程序都会有这样或那样的不足,尤其是未经过精心维护的非商业软件。即使是作为操作系统的Windows也时常会发生许多类型的错误和漏洞。本游戏当然或多或少也存在些bug,主要发现的BUG如下:编写的递归解法,可以实现大部分题目的解题。不过可能出现“死递归”,即一直递归下去。分析后,发现这主要是由于所采用的解题算法——递归对于求解个别复杂的题目时,效率不高,比如对于本游戏提供的题库的一道专杀暴力搜索程序的数独,此算法就需要花费40多分钟才能求解出答案,而其它的一般都是在一秒钟内就可以求解出答案。这里的AI的设计与实现需要大量的研究和广泛的试验,这并不是短时间能做到的。对此的BUG的暂时解决方案是在此期间友情提示玩家,当花费时间过长提示玩家重启程序。在后期,将考虑数独问题转换为精确覆盖的问题,采用Knuth的DancingLinks算法进行求解。另一个主要BUG是:在WindowsXP系统下,程序运行时候将占用100%的CPU问题,而在Windows7上测试却没有此现象。经查资料后,发现主要原因之一:操作系统版本的驱动模型影响。在WindowsVista以上版本的操作系统中,WPF可以充分利用新的WindowsVista显示驱动模型(WindowsVistaDisplayDriverModel,WDDM),相对于WindowsXP的显示驱动模型(WindowsXPDisplayDriverModel,XPDM),WDDM提供了几处非常重要的改进。WPF所用到的动画是使用了基于帧的动画技术,WPF每秒将会调用60次CompositionTarget.Rendering事件关联事件处理程序。在WDDN驱动模型下,WPF程序会根据显卡性能自动调节每秒的帧数,使其不会占用大量CPU。而在XP上则不存在自动调节帧数的问题。目前在XP下解决占用CPU100%的技巧是,重写Timeline.DesiredFrameRateProperty依赖项属性的PropertyMetadata,将DefaultValue设为较低的值:Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline),newFrameworkPropertyMetadata{DefaultValue=5});//设置每秒传输帧数5帧未完善的功能到目前为止,这已经是一个功能较为完善的数独游戏了。不过还可以做得更好,经过测试之后,发现本游戏可以完善的功能:添加更多的解题器插件,写一个更好的算法,使解题和生成题目的时间更短。将界面风格和逻辑分离得更清楚,实现皮肤定制和颜色风格的变更。添加更多的效果和动画使游戏更具美观。使游戏具有背景音乐和声音效果。结论游戏的总结和展望本游戏设计实现了.NETFramework3.5上WPF为平台的益智类游戏的数独的开发,游戏采用可以产生大量不同游戏的随机生成的方法,具有极高的耐玩性和益智性。经过了细心的调试和排错解决了绝大部分的问题。游戏开发所涉及到的WPF技术如数据绑定、动画和自定义控件只是冰山一角,后期开发可以尝试加入WPF技术中的3D图形,视频和多媒体应用,将WPF丰富绚丽的用户界面表现能力发挥到极致,使游戏更具可玩性。目前本游戏还是单机版游戏,后期可在原有XAML和C#代码的基础上移植到浏览器中,即开发出SilverLight版本是更多玩家能够跨平台享受本游戏的乐趣。感想本游戏作为我的毕业设计,是笔者目前做过的最有意义的程序。大学期间做过很多课程设计,大多是关于数据库方向的应用,开发游戏还是首次。游戏的设计过程中设计到数据结构的知识,需要将具体游戏抽象到数据结构,并要对算法进行优化。与此同时,不可避免的又要考虑到系统安全问题、线程等概念。而以前做过的学生管理系统、网上书城等简单的数据库管理系统的课程设计,大致都是数据库的增删改查,最终结果都离不开同一个模式。相比一些数据库软件,游戏的设计有很多人情色彩和艺术思想的发挥。学习WPF的困难远远超出了想象,由于WPF为一种刚出现仅几年的新技术,国内的参考资料非常少,仅有的资料一般也停留在简单的介绍阶段。在设计初期,需要翻译查看许多国外的电子书籍和开发人员的博客。LucasMagder的博客里一个关于WPF的入门系列教程实例给了很大的帮助。毕业设计是对大学所学知识的一次全面检验,通过本次毕业设计使我了解到自己在课本所学知识远远不够。在以后的人生道路上,要不断坚持学习,不断自我完善,使自己成为一名合格的IT人才。参考文献基于C8051F单片机直流电动机反馈控制系统的设计与研究基于单片机的嵌入式Web服务器的研究MOTOROLA单片机MC68HC(8)05PV8/A内嵌EEPROM的工艺和制程方法及对良率的影响研究基于模糊控制的电阻钎焊单片机温度控制系统的研制基于MCS-51系列单片机的通用控制模块的研究基于单片机实现的供暖系统最佳启停自校正(STR)调节器单片机控制的二级倒立摆系统的研究基于增强型51系列单片机的TCP/IP协议栈的实现基于单片机的蓄电池自动监测系统基于32位嵌入式单片机系统的图像采集与处理技术的研究基于单片机的作物营养诊断专家系统的研究基于单片机的交流伺服电机运动控制系统研究与开发基于单片机的泵管内壁硬度测试仪的研制基于单片机的自动找平控制系统研究基于C8051F040单片机的嵌入式系统开发基于单片机的液压动力系统状态监测仪开发模糊Smith智能控制方法的研究及其单片机实现一种基于单片机的轴快流CO〈,2〉激光器的手持控制面板的研制基于双单片机冲床数控系统的研究基于CYGNAL单片机的在线间歇式浊度仪的研制基于单片机的喷油泵试验台控制器的研制基于单片机的软起动器的研究和设计基于单片机控制的高速快走丝电火花线切割机床短循环走丝方式研究基于单片机的机电产品控制系统开发基于PIC单片机的智能手机充电器基于单片机的实时内核设计及其应用研究基于单片机的远程抄表系统的设计与研究基于单片机的烟气二氧化硫浓度检测仪的研制基于微型光谱仪的单片机系统单片机系统软件构件开发的技术研究基于单片机的液体点滴速度自动检测仪的研制基于单片机系统的多功能温度测量仪的研制基于PIC单片机的电能采集终端的设计和应用基于单片机的光纤光栅解调仪的研制气压式线性摩擦焊机单片机控制系统的研制基于单片机的数字磁通门传感器基于单片机的旋转变压器-数字转换器的研究基于单片机的光纤Bragg光栅解调系统的研究单片机控制的便携式多功能乳腺治疗仪的研制基于C8051F020单片机的多生理信号检测仪基于单片机的电机运动控制系统设计Pico专用单片机核的可测性设计研究基于MCS-51单片机的热量计基于双单片机的智能遥测微型气象站MCS-51单片机构建机器人的实践研究基于单片机的轮轨力检测基于单片机的GPS定位仪的研究与实现基于单片机的电液伺服控制系统用于单片机系统的MMC卡文件系统研制基于单片机的时控和计数系统性能优化的研究基于单片机和CPLD的粗光栅位移测量系统研究单片机控制的后备式方波UPS提升高职学生单片机应用能力的探究基于单片机控制的自动低频减载装置研究基于单片机控制的水下焊接电源的研究基于单片机的多通道数据采集系统基于uPSD3234单片机的氚表面污染测量仪的研制基于单片机的红外测油仪的研究96系列单片机仿真器研究与设计基于单片机的单晶金刚石刀具刃磨设备的数控改造基于单片机的温度智能控制系统的设计与实现基于MSP430单片机的电梯门机控制器的研制基于单片机的气体测漏仪的研究基于三菱M16C/6N系列单片机的CAN/USB协议转换器基于单片机和DSP的变压器油色谱在线监测技术研究基于单片机的膛壁温度报警系统设计基于AVR单片机的低压无功补偿控制器的设计基于单片机船舶电力推进电机监测系统基于单片机网络的振动信号的采集系统基于单片机的大容量数据存储技术的应用研究基于单片机的叠图机研究与教学方法实践基于单片机嵌入式Web服务器技术的研究及实现基于AT89S52单片机的通用数据采集系统基于单片机的多道脉冲幅度分析仪研究机器人旋转电弧传感角焊缝跟踪单片机控制系统基于单片机的控制系统在PLC虚拟教学实验中的应用研究基于单片机系统的网络通信研究与应用基于PIC16F877单片机的莫尔斯码自动译码系统设计与研究基于单片机的模糊控制器在工业电阻炉上的应用研究HYPERLIN
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- ATP的主要来源-细胞呼吸-3
- 异地订餐食品配送方案
- 化学新课程标准学习试题
- 2024年个人信贷服务合同
- 水利工程施工合同质量标准
- 2024年土地使用权转让合同(工业用地)
- 金属制品焊接质量提升方案
- 2024年UPS不间断电源采购合同
- 2024年城市供水项目特许经营与合作协议
- 2024年企业社会责任报告发布推广合同
- 烟花爆竹经营单位主要负责人与安全管理人员培训课件
- 煤气柜设计安全要求
- 广东省卫生正高评审答辩
- 公共关系学课件
- 2022车企私域运营白皮书
- 知识产权法电子文档
- 论文 小学英语学科育人教育的实践探索
- 《品人录》读书笔记思维导图PPT模板下载
- 医疗器械临床试验质量管理规范考核试题及答案
- 淀粉厂安全生产管理制度
- 家禽类完整版
评论
0/150
提交评论