C++五子棋人机对战游戏设计Word文档格式.docx

上传人:b****6 文档编号:21092579 上传时间:2023-01-27 格式:DOCX 页数:27 大小:514.50KB
下载 相关 举报
C++五子棋人机对战游戏设计Word文档格式.docx_第1页
第1页 / 共27页
C++五子棋人机对战游戏设计Word文档格式.docx_第2页
第2页 / 共27页
C++五子棋人机对战游戏设计Word文档格式.docx_第3页
第3页 / 共27页
C++五子棋人机对战游戏设计Word文档格式.docx_第4页
第4页 / 共27页
C++五子棋人机对战游戏设计Word文档格式.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

C++五子棋人机对战游戏设计Word文档格式.docx

《C++五子棋人机对战游戏设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《C++五子棋人机对战游戏设计Word文档格式.docx(27页珍藏版)》请在冰豆网上搜索。

C++五子棋人机对战游戏设计Word文档格式.docx

本文用visualc++来设计与实现简单的五子棋人机对战游戏的基本功能,玩家可以在游戏区域中适当的位置来放棋子,通过程序设计让电脑选择最佳的落棋点,来实现人机对战。

文中对该游戏的算法进行了详细的介绍,其中核心内容包括界面的设计、最佳落棋位置的判断以及游戏胜利判断功能的实现。

程序实现起来较简单,同时也比较实用。

关键词:

五子棋,vc,人机对战游戏

1.引言

1.1游戏介绍

五子棋是一种很受人们喜爱的智力游戏,它的规则简单,但玩法变化多端,富有趣味性,特别锻炼人的智力,适合人们消遣。

1.2目的

网络小游戏制作的目的是满足了人们休闲的需要,在紧张工作之余休闲类的小游戏能够给人带来最大程度的放松,也可以增进人们之间的交流,沟通,通过游戏还可以认识更多的朋友,也可以到达跨省、跨市,甚至跨国间人们互相娱乐的目的。

1.3主要问题

开始制作游戏时,主要要解决的问题有以下几个方面:

1.如何设置整个游戏的界面;

2判断是否可以放下棋子;

3.如何让电脑选择最佳位置;

4.判断是黑棋胜还是白棋胜。

2.需求分析

关于五子棋游戏的功能描述如下:

运行游戏并进行初始化工作,将整个游戏区域中纵线和横线相交的点坐标化,并且这些点是将来下棋的位置。

玩家可以在任意没有放棋子的点放下棋子,直到一方有五个棋子连成一条线为胜方。

游戏的整体运行效果如图1.1。

图1.1

3.功能模块的设计

3.1变量和函数

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

保存vscomputer时白棋位置CPointvspoint;

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_msgvoidOnCpmputer();

3.2.框架的搭建

新建工程,选择单文档,在Step4of6中先中WindowsSockets复选框

4.算法分析与设计

4.1游戏界面的设计

由于游戏的棋盘大小是一定的,不能改变大小的,是应该符合要求的。

用如下函数设置窗口大小:

BOOLCMainFrame:

:

PreCreateWindow(CREATESTRUCT&

cs)

{

if(!

CFrameWnd:

PreCreateWindow(cs))

returnFALSE;

//TODO:

ModifytheWindowclassorstylesherebymodifying

//theCREATESTRUCTcs

cs.dwExStyle=cs.dwExStyle|WS_EX_TOPMOST;

//

cs.style=WS_SYSMENU|WS_OVERLAPPED|WS_MINIMIZEBOX;

//;

//设置窗口大小:

400*340

cs.cx=450;

cs.cy=500;

returnTRUE;

}

画棋盘:

在OnDraw(CDC*pDC)函数中画棋盘,由于在游戏过程中有可能重画棋盘,而那时棋盘上面有棋子,所以,我们在这个函数里面必须有画棋子的语句。

在此用数组的做为1表示白棋,-1表示黑棋。

voidCMy3_1View:

OnDraw(CDC*pDC)

CMy3_1Doc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//画背景

CBrushmybrush1;

mybrush1.CreateSolidBrush(RGB(192,192,192));

CRectmyrect1(0,0,1200,800);

pDC->

FillRect(myrect1,&

mybrush1);

//画棋盘框线

CPenmypen;

CPen*myoldPen;

mypen.CreatePen(PS_SOLID,1,RGB(0,0,0));

myoldPen=pDC->

SelectObject(&

mypen);

for(inti=0;

i<

19;

i++)

{

MoveTo(40,40+i*20);

LineTo(400,40+i*20);

MoveTo(40+i*20,40);

LineTo(40+i*20,400);

}

//重画时显示存在的棋子

CDCDc;

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

AfxMessageBox("

Can'

tcreateDC"

);

for(intn=0;

n<

n++)

for(intm=0;

m<

m++)

if(wzq[n][m]==1)

{

//显示白棋

Dc.SelectObject(m_bmwhite);

BitBlt(n*20+32,m*20+32,160,160,&

Dc,0,0,SRCCOPY);

elseif(wzq[n][m]==-1)

//显示黑棋

Dc.SelectObject(m_bmblack);

棋盘的效果如图

4.2核心算法

在完成界面设计后,就开始展开游戏核心的设计,该部分主要包括计算机搜索最佳落棋位置,游戏胜利判断的实现。

5.1搜索最佳落棋位置

计算机是怎样下棋?

这就是定位的问题了。

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

我们实现的方法是:

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

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

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

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

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

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

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

bpointcan1;

并在搜索之前都赋值为(-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(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);

放下黑棋voidputdown(CPointpoint);

现在,对上面两个空函数进行定义

在指定位置下棋:

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

//黑棋下

putdown(CPointpoint)

CDC*pDC=GetDC();

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;

搜索最佳落棋点:

现在还有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]"

\"

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表示方向

voidsearchcandown1(inti,intj,intn);

voidsearchcandown2(inti,intj,intn);

voidsearchcandown3(inti,intj,intn);

voidsearchcandown4(inti,intj,intn);

CPointmaxnum(inta,intb,intc,intd);

最大值函数的实现:

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

CPointCMy3_1View:

maxnum(inta,intb,intc,intd)

//point.x为方向值

//point.y为最大值

CPointpoint;

if(a>

=b)

point.x=0;

point.y=a;

point.x=1;

point.y=b;

if(c>

point.y)

point.x=2;

point.y=c;

if(d>

point.x=3;

point.y=d;

returnpoint;

而另外的四个函数,有其相似性,分别介绍如下:

voidsearchcandown4(inti,intj,intn)函数:

如果最大值是四,它必然有一个空位置;

可以这样计算,如果第一个是空,那我们把它赋值给相应变量;

否则,先找那个空位置,然后判断第一个棋子的颜色,并赋相应的值。

//由于相似,下面代码只解释第一个方向

//有四个同色棋

searchcandown4(inti,intj,intn)

intk;

/////////////////////////////num[0]"

--"

if(n==0)

//如果第一个是空

if(wzq[i][j]==0)

//如果下面有白棋

if(wzq[i+1][j]==1)

//下面位置可以下棋,已经有四个白棋

wpointcan4.x=i;

wpointcan4.y=j;

break;

//下面位置可以下棋,已经有四个黑棋

bpointcan4.x=i;

bpointcan4.y=j;

//如果找到下棋位置,一定能找到!

elseif(wzq[i+k][j]==0)

//如果第一个是白棋

if(wzq[j][j]==1)

wpointcan4.x=i+k;

//否则第一个是黑棋

bpointcan4.x=i+k;

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

if(n==1)

if(wzq[i][j+1]==1)

elseif(wzq[i][j+k]==0)

if(wzq[i][j]==1)

wpointcan4.y=j+k;

bpointcan4.y=j+k;

}

if(n==2)

if(wzq[i+1][j+1]==1)

elseif(wzq[i+k][j+k]==0)

if(n==3)

if(wzq[i-1][j+1]==1)

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

当前位置:首页 > 高中教育 > 英语

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

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