五子棋设计方案Word格式.docx

上传人:b****5 文档编号:17367021 上传时间:2022-12-01 格式:DOCX 页数:35 大小:59.51KB
下载 相关 举报
五子棋设计方案Word格式.docx_第1页
第1页 / 共35页
五子棋设计方案Word格式.docx_第2页
第2页 / 共35页
五子棋设计方案Word格式.docx_第3页
第3页 / 共35页
五子棋设计方案Word格式.docx_第4页
第4页 / 共35页
五子棋设计方案Word格式.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

五子棋设计方案Word格式.docx

《五子棋设计方案Word格式.docx》由会员分享,可在线阅读,更多相关《五子棋设计方案Word格式.docx(35页珍藏版)》请在冰豆网上搜索。

五子棋设计方案Word格式.docx

第三章五子棋人机对战程序设计6

3-1主菜单设置6

3-2关键模块介绍7

第四章测试运行情况22

第五章总结23

参考文献24

第一章概述

1-1系统要求简述

本系统主要为游戏者提供了娱乐,有益于为人们的日常生活带来快乐,为人们适当的减压,另外还可以提高游戏者的反应能力,和动手能力。

1-2应用语言概述

自从计算机问世以来,程序设计有了很大的进展。

进入20世纪80年代,出现了一种新的程序设计方法——面向对象的程序设计(ObjectOrientedProgamming),简称OOP。

面向对象的程序设计的特性,为程序设计人员提供了分析和解决问题的一种全新的方法。

C++语言是70年代出现的一种非常卓越的程度设计语言,是由贝尔实验室的DennisRitchie设计的一个通用的面向对象的程序设计语言。

C++语言具有丰富的数据类型和结构化设计所需要的语句。

C++语言的特点是效率高、功能强、简洁灵活。

C++语言所具有的地址操作和位操作,是它在一定程度上具有了低级语言的特性,因而可以在相当大的程度上,代替设计难度较大的汇编语言。

目前国际上广泛流行的计算机高级语言,既可用来写系统软件,也可用来写应用软件。

1-3开发工具

本项目所用的开发工具如表1-1所示

表1-1开发工具表

开发语言

C++

开发环境

Windowsxppro+MicrosoftVisualStudio2006

开发工具

MicrosoftVisualStudio2006

第二章功能与设计思想

2-1人机对战程序功能

五子棋是一个经典的小游戏,游戏者打开游戏后将会看到一张棋盘,这时游戏者可选择人对战或者人机对战,本程序主要功能来实现人机对战,游戏者通过鼠标的移动来移动棋子,通过单击鼠标来确定棋子的最终位置,先将棋子排成五子一线者为最终获胜者。

游戏结束

2-2人机对战设计思想

图2-1游戏的实现

先看上图,玩过五子棋的人一眼就能看出这才是一场真正的战斗!

(至少它不允许你随便下棋。

那么,我们该如何实现?

其实,只是在原来的基础上,把其中一个人用计算机代替而已。

也就是说,我们只要在原来的基础上,加上计算机的下棋算法就好了。

而计算机下棋的算法,正是一个程序的重点和难点。

这里先介绍一下:

计算机是没有头脑的,但是,计算机必须下棋。

那么,它该怎么办呢?

我们必须自己编程序,“教”计算机下棋。

然而,我们是否只是让计算机随便在棋盘上面放一颗棋子呢?

事情并不是这么简单。

计算机要下的那个位置,必定是它认为最好的!

当然,这里的最好是程序员给予计算机的,是计算机算法的体现。

最好的位置,人都难以保证!

但是,计算机可以。

这正是计算机能够在我们这个社会迅速发展的一个重要原因。

当然,计算机的可以是建立在人的程序的基础上的。

计算机的会是依赖于它的速度,人所不能及的速度。

上面说过,为什么要把数组的值赋值为1和-1,而不是0,1或者其它的数字呢?

这里就涉及到数字的妙用。

前面说了,五个连续棋子的值相加,如果绝对值是五,则不是五个棋子同色,应该结束游戏。

那么,如果绝对值不是五呢?

它就没有意义了吗?

不是!

不但不是,而是它有着更重要的意义。

它关系到我们这个程序的几乎全部的算法。

下面细说(数字是表示绝对值的):

4:

表示五个棋子中有一个空位置和四个同色的棋子。

3:

表示五个棋子中有两个空位置和三个同色的棋子;

也表示五个棋子中有四个同色棋子和一个异色棋子。

注意:

此时没有空位置,可以不考虑。

2:

表示五个棋子中有三个空位置和两个同色棋子;

也表示五个棋子中一个空位置和三个同色棋子和一个异色棋子;

1、0:

由于出现1和0的机会太少(除了开始的时候),我们不必多加考虑。

但是,因为刚才对方下棋的对方必定有一定的危险,我们只需要在刚刚下棋的附近找一个空位置下棋就可以了。

第三章五子棋人机对战程序设计

3-1主菜单设置

对菜单进行设置,游戏中分别添加开始,打开,退出和保存,其中开始中又包括人对人和人对机两项,并且对他们分别关联和做相应的消息映射。

图3-1游戏菜单

从上面图中,我们可以看到,工具栏变了。

因此我们也可以想到菜单也应该变了。

它们的修改如下:

修改菜单:

删除菜单项开始:

ID_START

添加菜单项人对人游戏:

ID_PLAYER

人对机游戏:

ID_CPMPUTER

修改工具栏:

删除原来的按扭对应ID:

添加两个新按扭对应ID:

ID_PLAYERID_CPMPUTER

3-2关键模块介绍

3-2-1 

变量和函数

在view类中添加变量函数如下:

//保存vscomputer时白棋位置

CPointvspoint;

//是人与人游戏?

是人与机游戏?

intvscomputer;

CPointbpointcan4,//这个位置空,它旁边有四个黑棋

wpointcan4,//这个位置空,它旁边有四个白棋

bpointcan3,//这个位置空,它的旁边有三个黑棋

wpointcan3,//这个位置空,它的旁边有三个白棋

bpointcan2,//这个位置空,它的旁边有两个黑棋

wpointcan2,//这个位置空,它的旁边有两个白棋

bpointcan1;

//不是以上情况,这个位置空

//在得到最大值和方向上寻找落棋点(具体见后面介绍)

//其中i、j表示搜索起点,n表示方向

voidsearchcandown1(inti,intj,intn);

voidsearchcandown2(inti,intj,intn);

voidsearchcandown3(inti,intj,intn);

voidsearchcandown4(inti,intj,intn);

//计算最大值及方向

CPointmaxnum(inta,intb,intc,intd);

//最好落棋点

voidbestputdown(inti,intj);

//计算机下棋

voidcomputerdown();

//在位置point放下棋子

voidputdown(CPointpoint);

//人对人菜单

afx_msgvoidOnPlayer();

//人对机菜单

afx_msgvoidOnCpmputer();

3-2-2菜单函数

添加了菜单项,我们必须添加一个变量vscomputer,赋值为1,并约定:

//vscomputer:

2表示人对人,1表示人对机

voidCMyView:

:

OnPlayer()

{

//TODO:

Addyourcommandhandlercodehere

vscomputer=2;

OnStart();

}

OnCpmputer()

vscomputer=1;

其中,我们只是添加一个变量,而仍然利用原来的开始函数。

虽然我们的菜单项已经删除了,但它的函数还在,我们应该加以利用。

3-2-3人变成计算机

下面,我们就必须把游戏双方中的一方改为计算机。

我们把黑棋改为计算机,因为一般情况计算机比人强,应让人先下。

当然,要是人赢了,就必须让计算机先下了,在将在以后的算法中体现。

由于下棋只是在OnLButtonUp(UINTnFlags,CPointpoint)函数中,我们把它改为如下:

OnLButtonUp(UINTnFlags,CPointpoint)

Addyourmessagehandlercodehereand/orcalldefault

CDC*pDC=GetDC();

CDCDc;

if(Dc.CreateCompatibleDC(pDC)==FALSE)

AfxMessageBox("

Can'

tcreateDC"

);

//显示棋子

/////////////////////人对机

if(vscomputer==1)

{

if(point.x>

30&

&

point.x<

410&

point.y>

point.y<

410)

{

intpx=(point.x-30)/20;

intpy=(point.y-30)/20;

if(colorwhite&

wzq[px][py]==0)

{

Dc.SelectObject(m_bmwhite);

pDC->

BitBlt(px*20+32,py*20+32,160,160,&

Dc,0,0,SRCCOPY);

wzq[px][py]=1;

over(point);

colorwhite=false;

//保存白棋位置

vspoint=point;

//计算机下棋

computerdown();

}

}

}

//人对人

if(vscomputer==2)

{

elseif(wzq[px][py]==0)

{

Dc.SelectObject(m_bmblack);

wzq[px][py]=-1;

colorwhite=true;

}

CView:

OnLButtonUp(nFlags,point);

由上面可知,我们对人对机游戏的方法是采用:

人下完了之后,检查是否胜利,是则结束游戏,重新开始,并改为黑棋(即计算机)先下;

如果人没有胜利,也改为计算机下。

而对于计算机怎么下棋,我们只是用了一个函数computerdown()表示。

但是现在我们并不能运行程序,因为有一个没有定义的函数,怎么办呢?

仔细看程序的话,你还会发现一个变量Cpointvspoint,这是后来添加的它的用处是保存刚才白棋下的位置,有利于黑棋下棋时的定位。

接着,我们的主要问题就是实现computerdown()函数,让计算机能够自动下棋!

3-2-4计算机下棋

计算机是怎样下棋?

这就是定位的问题了。

即搜索棋盘,找出一个最佳点,放下黑棋。

我们实现的方法是:

全盘搜索,并把搜索到的位置,保存在变量。

由于有多种情况,我们定义变量如下:

CPointbpointcan4,//这个位置空,它旁边有四个黑棋

wpointcan4,//这个位置空,它旁边有四个白棋

bpointcan3,//这个位置空,它的旁边有三个黑棋

wpointcan3,//这个位置空,它的旁边有三个白棋

bpointcan2,//这个位置空,它的旁边有两个黑棋

wpointcan2,//这个位置空,它的旁边有两个白棋

//不是以上情况,这个位置空

并在搜索之前都赋值为(-1,-1),然后,进行搜索,并把相应的值保存在相应变量里面,而如果前面已经对变量赋值,我们依然赋值,用新值代替旧值。

我们只保存最后一个值,这样的一个好处是,避免了每次都从左上角开始,并且它的随机性比随机函数还随机。

全盘搜索完之后,由于上面的变量中至少有一个已经被赋值,即不是(-1,-1),我们可以采用多数优先的方法,让已经有多个同色棋子的位置先下棋。

其原理是,如果已经有四个黑棋,计算机再下一个黑棋就赢了;

否则,如果人已经有四个白棋,那么计算机就必须放下一个黑棋,阻止白棋下一步赢;

如果已经有三个黑棋,再下一个黑棋,变成四个;

否则,如果已经有三个白棋,下一个黑棋,破坏它;

两个棋子的同理;

否则,在刚才白棋下的地方,顺便找一个位置,下棋。

computerdown()函数如下:

//轮到计算机下棋

computerdown()

//把各种情形赋值为如下

bpointcan4=(-1,-1);

wpointcan4=(-1,-1);

bpointcan3=(-1,-1);

wpointcan3=(-1,-1);

bpointcan2=(-1,-1);

wpointcan2=(-1,-1);

bpointcan1=(-1,-1);

//搜索最好的落棋点

for(inti=0;

i<

19;

i++)

for(intj=0;

j<

j++)

bestputdown(i,j);

//判断放在哪里

//棋多的位置优先

//黑白一样多时黑先

//不是-1就表示已经被赋值!

if(bpointcan4.x!

=-1)

putdown(bpointcan4);

return;

elseif(wpointcan4.x!

putdown(wpointcan4);

elseif(bpointcan3.x!

putdown(bpointcan3);

elseif(wpointcan3.x!

putdown(wpointcan3);

elseif(bpointcan2.x!

putdown(bpointcan2);

elseif(wpointcan2.x!

putdown(wpointcan2);

else

putdown(bpointcan1);

上面又有两个新函数,分别定义为空函数,如下:

//搜索最佳位置

voidbestputdown(inti,intj);

//放下黑棋

现在,我们就必须对上面两个空函数进行定义了。

3-2-5在指定位置下棋

由于putdown(CPointpoint)函数的原理非常简单,我们先说明如下:

//黑棋下

putdown(CPointpoint)

Dc.SelectObject(m_bmblack);

pDC->

BitBlt(point.x*20+32,point.y*20+32,160,160,&

wzq[point.x][point.y]=-1;

//由于原来我们检查是否结束时用的是鼠标点下的坐标,而现在

//putdown(CPointpoint)函数用的是数组棋盘的坐标,所以必须转换

CPointoverpoint;

overpoint.x=point.x*20+30;

overpoint.y=point.y*20+30;

over(overpoint);

colorwhite=true;

3-2-6搜索最佳落棋点

现在就剩下voidbestputdown(inti,intj)函数没有定义了(虽然前面的变量函数已经说明了,当时我们这里是用程序扩展的思路进行的,故如此说明)。

它的实现原理是:

在四个方向上,各自计算那个方向上棋子的状态,我们的思路是利用原来定义的白棋为1,黑棋为-1,的思想,让同个方向上的五个棋子的值相加,取绝对值并赋值给为这个方向定义的局部变量num[i]。

为什么要用五个棋子的值相加呢?

因为,如果几个棋子是同色的,无论黑白,它的绝对值必然大,而对于几个棋子中有黑棋和白棋的,其值必然相加而抵消变小。

所以我们可以利用这种方法来寻找旁边有多个同色棋子的空位置(前面已经具体说明)。

在每一个棋盘位置,计算以它为起点的四个方向(横、竖、撇、捺),再比较这四个方向中哪个值最大,然后在这个方向上寻找落棋点。

我们添加函数如下:

//检查四个方向,各算出五个棋子的和并赋值

bestputdown(inti,intj)

//四个方向的值

intnum[4];

inta,k;

///////////////////////////////num[0]-->

a=0;

if(i<

15)

for(k=0;

k<

5;

k++)

a=a+wzq[i+k][j];

num[0]=abs(a);

//////////////////////////////num[1]"

|"

if(j<

a=a+wzq[i][j+k];

num[1]=abs(a);

///////////////////////////////num[2]"

\"

if(i<

15&

a=a+wzq[i+k][j+k];

num[2]=abs(a);

//////////////////////////////num[3]"

/"

if((i>

4)&

(j<

15))

a=a+wzq[i-k][j+k];

num[3]=abs(a);

//比较哪个方向同色棋最多

//由于我们搜索落棋点时用到最大值和方向,我们可以定义一个Cpoint类变量,//让它返回两个值。

可以说,这也是一种巧妙的想法,因为这样你就不用去写//内联函数了

CPointnumbig;

//numbig.x表示方向

//numbig.y表示最大值

numbig=maxnum(num[0],num[1],num[2],num[3]);

//在得到最大值和方向上寻找落棋点

switch(numbig.y)

case4:

searchcandown4(i,j,numbig.x);

break;

case3:

searchcandown3(i,j,numbig.x);

case2:

searchcandown2(i,j,numbig.x);

default:

searchcandown1(i,j,numbig.x);

同样的方法,我们必须为上面还没有定义的函数添加空函数。

//其中i、j表示搜索起点,n表示方向

3-2-7最大值函数的实现

现在先介绍CPointmaxnum(inta,intb,intc,intd)函数,它只是四个整数的比较:

CPointCMyView:

maxnum(inta,intb,intc,intd)

//point.x为方向值

//point.y为最大值

CPointpoint;

if(a>

=b)

point.x=0;

point.y=a;

else

point.x=1;

point.y=b;

if(c>

point.y)

point.x=2;

point.y=c;

if(d>

point.x=3;

point.y=d;

r

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 法语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1