用C语言在linux下编写一个五子棋程序!

用C语言在linux下编写一个五子棋程序!,第1张

五子棋的核心算法

五子棋是一种受大众广泛喜爱的游戏,其规则简单,变化多端,非常富有趣味性和消遣性。这里设计和实现了一个人机对下的五子棋程序,采用了博弈树的方法,应用了剪枝和最大最小树原理进行搜索发现最好的下子位置。介绍五子棋程序的数据结构、评分规则、胜负判断方法和搜索算法过程。

一、相关的数据结构

关于盘面情况的表示,以链表形式表示当前盘面的情况,目的是可以允许用户进行悔棋、回退等 *** 作。

CList StepList

其中Step结构的表示为:

struct Step

{

int m//m,n表示两个坐标值

int n

char side//side表示下子方

}

以数组形式保存当前盘面的情况,

目的是为了在显示当前盘面情况时使用:

char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE]

其中FIVE_MAX_LINE表示盘面最大的行数。

同时由于需要在递归搜索的过程中考虑时间和空间有效性,只找出就当前情况来说相对比较好的几个盘面,而不是对所有的可下子的位置都进行搜索,这里用变量CountList来表示当前搜索中可以选择的所有新的盘面情况对象的集合:

CList CountList

其中类CBoardSituiton为:

class CBoardSituation

{

CList StepList//每一步的列表

char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE]

struct Step machineStep //机器所下的那一步

double value//该种盘面状态所得到的分数

}

二、评分规则

对于下子的重要性评分,需要从六个位置来考虑当前棋局的情况,分别为:-,¦,/,\,//,\\

实际上需要考虑在这六个位置上某一方所形成的子的布局的情况,对于在还没有子的地方落子以后的当前局面的评分,主要是为了说明在这个地方下子的重要性程度,设定了一个简单的规则来表示当前棋面对机器方的分数。

基本的规则如下:

判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予-100000 分;

判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予-10000分;

判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予-5000 分;

判断是否成死3活3,如果是机器方的话给予1000分,如果是人方的话给予-1000 分;

判断是否能成死4,如果是机器方的话给予500分,如果是人方的话给予-500分;

判断是否能成单活3,如果是机器方的话给予200分,如果是人方的话给予-200分;

判断是否已成双活2,如果是机器方的话给予100分,如果是人方的话给予-100分;

判断是否能成死3,如果是机器方的话给予50分,如果是人方的话给予-50分;

判断是否能成双活2,如果是机器方的话给予10分,如果是人方的话给予-10分;

判断是否能成活2,如果是机器方的话给予5分,如果是人方的话给予-5分;

判断是否能成死2,如果是机器方的话给予3分,如果是人方的话给予-3分。

实际上对当前的局面按照上面的规则的顺序进行比较,如果满足某一条规则的话,就给该局面打分并保存,然后退出规则的匹配。注意这里的规则是根据一般的下棋规律的一个总结,在实际运行的时候,用户可以添加规则和对评分机制加以修正。

三、胜负判断

实际上,是根据当前最后一个落子的情况来判断胜负的。实际上需要从四个位置判断,以该子为出发点的水平,竖直和两条分别为 45度角和135度角的线,目的是看在这四个方向是否最后落子的一方构成连续五个的棋子,如果是的话,就表示该盘棋局已经分出胜负。具体见下面的图示:

四、搜索算法实现描述

注意下面的核心的算法中的变量currentBoardSituation,表示当前机器最新的盘面情况, CountList表示第一层子节点可以选择的较好的盘面的集合。核心的算法如下:

void MainDealFunction()

{

value=-MAXINT//对初始根节点的value赋值

CalSeveralGoodPlace(currentBoardSituation,CountList)

//该函数是根据当前的盘面情况来比较得到比较好的可以考虑的几个盘面的情况,可以根据实际的得分情况选取分数比较高的几个盘面,也就是说在第一层节点选择的时候采用贪婪算法,直接找出相对分数比较高的几个形成第一层节点,目的是为了提高搜索速度和防止堆栈溢出。

pos=CountList.GetHeadPosition()

CBoardSituation* pBoard

for(i=0ivalue=Search(pBoard,min,value,0)

Value=Select(value,pBoard->value,max)

//取value和pBoard->value中大的赋给根节点

}

for(i=0ivalue)

//找出那一个得到最高分的盘面

{

currentBoardSituation=pBoard

PlayerMode=min//当前下子方改为人

Break

}

}

其中对于Search函数的表示如下:实际上核心的算法是一个剪枝过程,其中在这个搜索过程中相关的四个参数为:(1)当前棋局情况;(2)当前的下子方,可以是机器(max)或者是人(min);(3)父节点的值oldValue;(4)当前的搜索深度depth。

double Search(CBoardSituation&

board,int mode,double oldvalue,int depth)

{

CList m_DeepList

if(deptholdvalue))== TRUE)

{

if(mode==max)

value=select(value,search(successor

Board,min,value,depth+1),max)

else

value=select(value,search(successor

Board,max,value,depth+1),min)

}

return value

}

else

{

if ( goal(board)<>0)

//这里goal(board)<>0表示已经可以分出胜负

return goal(board)

else

return evlation(board)

}

}

注意这里的goal(board)函数是用来判断当前盘面是否可以分出胜负,而evlation(board)是对当前的盘面从机器的角度进行打分。

下面是Select函数的介绍,这个函数的主要目的是根据 PlayerMode情况,即是机器还是用户来返回节点的应有的值。

double Select(double a,double b,int mode)

{

if(a>b && mode==max)¦¦ (a<b && mode==min)

return a

else

return b

}

五、小结

在Windows *** 作系统下,用VC++实现了这个人机对战的五子棋程序。和国内许多只是采用规则或者只是采用简单递归而没有剪枝的那些程序相比,在智力上和时间有效性上都要好于这些程序。同时所讨论的方法和设计过程为用户设计其他的游戏(如象棋和围棋等)提供了一个参考。

参考资料:http://www.3800hk.com/Article/cxsj/vc/jdsfvc/2005-08-06/Article_33695.html

#include <stdio.h>

#include <bios.h>

#include <ctype.h>

#include <conio.h>

#include <dos.h>

#define CROSSRU     0xbf   /*右上角点*/

#define CROSSLU     0xda   /*左上角点*/

#define CROSSLD     0xc0   /*左下角点*/

#define CROSSRD     0xd9   /*右下角点*/

#define CROSSL       0xc3   /*左边*/

#define CROSSR       0xb4   /*右边*/

#define CROSSU       0xc2   /*上边*/

#define CROSSD       0xc1   /*下边*/

#define CROSS       0xc5   /*十字交叉点*/

/*定义棋盘左上角点在屏幕上的位置*/

#define MAPXOFT     5

#define MAPYOFT     2

/*定义1号玩家的 *** 作键键码*/

#define PLAY1UP     0x1157/*上移--'W'*/

#define PLAY1DOWN   0x1f53/*下移--'S'*/

#define PLAY1LEFT   0x1e41/*左移--'A'*/

#define PLAY1RIGHT   0x2044/*右移--'D'*/

#define PLAY1DO     0x3920/*落子--空格键*/

/*定义2号玩家的 *** 作键键码*/

#define PLAY2UP     0x4800/*上移--方向键up*/

#define PLAY2DOWN   0x5000/*下移--方向键down*/

#define PLAY2LEFT   0x4b00/*左移--方向键left*/

#define PLAY2RIGHT   0x4d00/*右移--方向键right*/

#define PLAY2DO     0x1c0d/*落子--回车键Enter*/

/*若想在游戏中途退出, 可按 Esc 键*/

#define ESCAPE       0x011b

/*定义棋盘上交叉点的状态, 即该点有无棋子 */

/*若有棋子, 还应能指出是哪个玩家的棋子   */

#define CHESSNULL   0   /*没有棋子*/

#define CHESS1       'O'/*一号玩家的棋子*/

#define CHESS2       'X'/*二号玩家的棋子*/

/*定义按键类别*/

#define KEYEX99v         0/*退出键*/

#define KEYFALLCHESS   1/*落子键*/

#define KEYMOVECURSOR   2/*光标移动键*/

#define KEYINVALID     3/*无效键*/

/*定义符号常量: 真, 假 --- 真为1, 假为0 */

#define TRUE         1

#define FALSE       0

/**********************************************************/

/* 定义数据结构                                           */

/*棋盘交叉点坐标的数据结构*/

struct point

{

int x,y

}

或者下面这个:

#include <graphics.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#define N 15

#define B 7

#define STOP -10000

#define OK 1

#define NO 0

#define UP 328

#define DOWN 336

#define LEFT 331

#define RIGHT 333

int a[N+1][N+1]

int zx,zy

int write=1,biaoji=0

struct zn{

long sum

int y

int x

}w[N+1][N+1],max,max1

void cbar(int i,int x,int y,int r)

void map(int a[][])

int getkey()

int key()

void zuobiao(int x,int y,int i)

int tu(int a[][],int write)

int wtu(int a[][],int write)

int zhineng(int a[][])

int zh5(int y,int x,int a[][])

long zzh5(int b[][],int i)

main()

{

int i,j

int gdriver=DETECT

int gmode

initgraph(&gdriver,&gmode,"")

zx=(N+1)/2

zy=(N+1)/2

for(i=1i<=Ni++)

for(j=1j<=Nj++)

a[i][j]=0

map(a)

i=1

while(i)

{

int k,n

k=wtu(a,write)

if(k==STOP) goto end

map(a)

n=zhineng(a)

if(n==STOP) goto end

map(a)

}

end:

}

int zhineng(int a[N+1][N+1])

{

int i,j

int k

max.sum=-1

for(i=0i<=Ni++)

for(j=0j<+Nj++)

{

w[i][j].sum=0

w[i][j].x=i

w[i][j].y=j

}

for(i=1i<=N-4i++)

for(j=1j<=N-4j++)

{

k=zh5(i,j,a)

if(k==STOP) return (STOP)

}

for(i=1i<=Ni++)

for(j=1j<=Nj++)

{

if(max.sum<w[i][j].sum)

{

max.sum=w[i][j].sum

max.y=i

max.x=j

}

else if(max.sum==w[i][j].sum)

{

if(((max.y-zy)*(max.y-zy)+(max.x-zx)*(max.x-zx))>((i-zy)*(i-zy)+(j-zx)*(j-zx)))

max.sum=w[i][j].sum

max.y=i

max.x=j

}

}

if(a[max.y][max.x]==0)

{

a[max.y][max.x]=-1

zy=max.y

zx=max.x

}

}

int zh5(int y,int x,int a[N+1][N+1])

{

int i,j

int b[6][6]

long c[13]

long d[6][6]

long temp

for(i=yi<=y+4i++)

for(j=xj<=x+4j++)

b[i+1-y][j+1-x]=a[i][j]

c[1]=b[1][1]+b[1][2]+b[1][3]+b[1][4]+b[1][5]

c[2]=b[2][1]+b[2][2]+b[2][3]+b[2][4]+b[2][5]

c[3]=b[3][1]+b[3][2]+b[3][3]+b[3][4]+b[3][5]

c[4]=b[4][1]+b[4][2]+b[4][3]+b[4][4]+b[4][5]

c[5]=b[5][1]+b[5][2]+b[5][3]+b[5][4]+b[5][5]

c[6]=b[1][1]+b[2][1]+b[3][1]+b[4][1]+b[5][1]

c[7]=b[1][2]+b[2][2]+b[3][2]+b[4][2]+b[5][2]

c[8]=b[1][3]+b[2][3]+b[3][3]+b[4][3]+b[5][3]

c[9]=b[1][4]+b[2][4]+b[3][4]+b[4][4]+b[5][4]

c[10]=b[1][5]+b[2][5]+b[3][5]+b[4][5]+b[5][5]

c[11]=b[1][1]+b[2][2]+b[3][3]+b[4][4]+b[5][5]

c[12]=b[1][5]+b[2][4]+b[3][3]+b[4][2]+b[5][1]

for(i=1i<=12i++)

{

switch(c[i])

{

case 5:biaoji=1return(STOP)

case -5:biaoji=-1return(STOP)

case -4:c[i]=100000break

case 4:c[i]=100000break

case -3:c[i]=150break

case 3:c[i]=150break

case -2:c[i]=120break

case 2:c[i]=100break

case -1:c[i]=1break

case 1:c[i]=1break

default: c[i]=0

}

}

for(i=1i<=12i++)

{

if(c[i]==150)

c[i]+=zzh5(b,i)

}

for(i=1i<=5i++)

for(j=1j<=5j++)

d[i][j]=0

for(i=1i<=5i++)

for(j=1j<=5j++)

{

if(i==j) d[i][j]+=c[11]

if((i+j)==6) d[i][j]+=c[12]

d[i][j]+=c[i]+c[j+5]

}

for(i=1i<=5i++)

for(j=1j<=5j++)

{

if(b[i][j]!=0)

d[i][j]=-2

}

max1.sum=-1

max1.y=0

max1.x=0

for(i=1i<=5i++)

for(j=1j<=5j++)

{

if(max1.sum<d[i][j])

{

max1.sum=d[i][j]

max1.y=i

max1.x=j

w[i+y-1][j+x-1].sum+=max1.sum

}

else if(max1.sum==d[i][j])

{

if(((i+y-1-zy)*(i+y-1-zy)+(j+x-1-zx)*(j+x-1-zx))>((max1.y+y-1-zy)*(max1.y+y-1-zy)+(max1.x+x-1-zx)*(max1.x+x-1-zx)))

{

max1.sum=d[i][j]

max1.y=i

max1.x=j

}

}

}

}

long zzh5(int b[6][6],int n)

{

int i,j,k,l,m

switch(n)

{

case 1:i=b[1][1]j=b[1][2]k=b[1][3]l=b[1][4]m=b[1][5]break

case 2:i=b[2][1]j=b[2][2]k=b[2][3]l=b[2][4]m=b[2][5]break

case 3:i=b[3][1]j=b[3][2]k=b[3][3]l=b[3][4]m=b[3][5]break

case 4:i=b[4][1]j=b[4][2]k=b[4][3]l=b[4][4]m=b[4][5]break

case 5:i=b[5][1]j=b[5][2]k=b[5][3]l=b[5][4]m=b[5][5]break

case 6:i=b[1][1]j=b[2][1]k=b[3][1]l=b[4][1]m=b[5][1]break

case 7:i=b[1][2]j=b[2][2]k=b[3][2]l=b[4][2]m=b[5][2]break

case 8:i=b[1][3]j=b[2][3]k=b[3][3]l=b[4][3]m=b[5][3]break

case 9:i=b[1][4]j=b[2][4]k=b[3][4]l=b[4][4]m=b[5][4]break

case 10:i=b[1][5]j=b[2][5]k=b[3][5]l=b[4][5]m=b[5][5]break

case 11:i=b[1][1]j=b[2][2]k=b[3][3]l=b[4][4]m=b[5][5]break

case 12:i=b[1][5]j=b[2][4]k=b[3][3]l=b[4][2]m=b[5][1]break

}

if((i==0&&j==1&&k==1&&l==1&&m==0))

return (900)

if((i==0&&j==-1&&k==-1&&l==-1&&m==0))

return(1000)

if((i==0&&j==0&&k==1&&l==1&&m==1)||(i==1&&j==1&&k==1&&l==0&&m==0))

return(20)

if((i==0&&j==0&&k==-1&&l==-1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==0&&m==0))

return(20)

if((i==-1&&j==1&&k==1&&l==1&&m==1)||(i==1&&j==-1&&k==1&&l==1&&m==1)||(i==1&&j==1&&k==-1&&l==1&&m==1)||(i==1&&j==1&&k==1&&l==-1&&m==1)||(i==1&&j==1&&k==1&&l==1&&m==-1))

return(-60)

if((i==1&&j==-1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==1&&k==-1&&l==-1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==1&&m==-1)||(i==-1&&j==-1&&k==-1&&l==-1&&m==1))

return(-60)

}

int wtu(int a[N+1][N+1],int write)

{

int i=1

map(a)

zuobiao(zx,zy,1)

while(i)

{

int k

k=tu(a,write)

if(k==OK) i=0

if(k==STOP) return (STOP)

}

}

int getkey()

{

int key,lo,hi

key=bioskey(0)

lo=key&0x00ff

hi=(key&0xff00)>>8

return((lo==0) ? hi+256:lo)

}

int key()

{

int k

k=getkey()

switch(k)

{

case 27: return (STOP)

case 13:

case ' ': return (OK)

case 328: return (UP)

case 336: return (DOWN)

case 331: return (LEFT)

case 333: return (RIGHT)

default: return (NO)

}

}

void zuobiao(int x,int y,int i)

{

int r

if(i!=0)

{

setcolor(GREEN)

for(r=1r<=5r++)

circle(75+25*x,25+25*y,r)

}

else

{

if(a[zy][zx]==1)

{

setcolor(8)

for(r=1r<=5r++)

circle(75+25*x,25+25*y,r)

}

else if(a[zy][zx]==-1)

{

setcolor(WHITE)

for(r=1r<=5r++)

circle(75+25*x,25+25*y,r)

}

else

{

setcolor(B)

for(r=1r<=5r++)

circle(75+25*x,25+25*y,r)

setcolor(RED) line(75+25*zx-5,25+25*zy,75+25*x+5,25+25*zy)

line(75+25*zx,25+25*zy-5,75+25*zx,25+25*zy+5)

}

}

}

int tu(int a[N+1][N+1],int write)

{

int k

re:

k=key()

if(k==OK)

{

if(a[zy][zx]==0)

{

a[zy][zx]=write

}

else

goto re

}

if(k==STOP) return(STOP)

if(k==NO) goto re

if(k==UP)

{

int i,j

if(zy==1) j=zy

else j=zy-1

zuobiao(zx,zy,0)

zuobiao(zx,j,1)

zy=j

goto re

}

if(k==DOWN)

{

int i,j

if(zy==N) j=zy

else j=zy+1

zuobiao(zx,zy,0)

zuobiao(zx,j,1)

zy=j

goto re

}

if(k==LEFT)

{

int i,j

if(zx==1) i=zx

else i=zx-1

zuobiao(zx,zy,0)

zuobiao(i,zy,1)

zx=i

goto re

}

if(k==RIGHT)

{

int i,j

if(zx==N) i=zx

else i=zx+1

zuobiao(zx,zy,0)

zuobiao(i,zy,1)

zx=i

goto re

}

}

void cbar(int i,int x,int y,int r)

{

if(i!=0)

{

if(i==1)

setcolor(8)

else if(i==-1)

setcolor(WHITE)

for(i=1i<=ri++)

{

circle(x,y,i)

}

}

}

void map(int a[N+1][N+1])

{

int i,j

cleardevice()

setbkcolor(B)

setcolor(RED)

for(i=0i<Ni++)

{

line(100,50+25*i,75+N*25,50+25*i)

line(100+25*i,50,100+25*i,25+N*25)

}

for(i=1i<=Ni++)

for(j=1j<=Nj++)

cbar(a[i][j],75+25*j,25+25*i,10)

}

http://tieba.baidu.com/f?ct=335675392&tn=baiduPostBrowser&sc=4335990148&z=430611008&pn=0&rn=30&lm=0&word=c%2B%2B#4335990148

百度贴吧里面的,我试过可以运行,有人机对战功能~

#include <iostream.h>

#include <process.h>

#include <conio.h>

class five

{

int x

int y

int m

int n

int num_xy

int num_mn

char qipan[20][20]

public:

five(int X = 0,int Y =0,int M = 0,int N = 0,int Num_xy = 0,int Num_mn = 0)

{

x = X

y = Y

m = M

n = N

num_xy = Num_xy

num_mn = Num_mn

for(int i = 0 i <20 i ++)

{

for(int j = 0 j <20 j ++)

qipan[i][j] = '.'

}

}

int getm()

{

return m

}

int getn()

{

return n

}

void getpointxy()

void getpointmn()

void machinemn()

void showqipan()

void print()

bool IsxyWin()

bool IsmnWin()

int dangerlevel(int a,int b)

void attack()

}

void five::getpointxy()

{

cout<<"请分别输入第"<<num_xy+1<<"步白棋('o')的横坐标和纵坐标:"

cin >>x >>y

if(x <= 0 || y <= 0 || x >20 || y >20 )

{

cout <<"出界,请重新输入:"<<endl

getpointxy()

}

else if(qipan[y-1][x-1] != '.' )

{

cout <<"请所下的位置已经有棋子,请重新输入:" <<endl

getpointxy()

}

else if(num_xy+num_mn >= 400)

{

cout <<"棋盘已满,平局!" <<endl

exit(0)

}

else

{

qipan[y-1][x-1] = 'o'

num_xy++

}

}

void five::getpointmn()

{

cout<<"请分别输入第"<<num_mn+1<<"步黑棋('x')的横坐标和纵坐标:"

cin >>m >>n

if(m <= 0 || n <= 0 || m >20 || n >20 )

{

cout <<"出界,请重新输入:"<<endl

getpointmn()

}

else if(qipan[n-1][m-1]!='.')

{

cout <<"请所下的位置已经有棋子,请重新输入:" <<endl

getpointmn()

}

else if(num_xy+num_mn >= 400)

{

cout <<"棋盘已满,平局!" <<endl

exit(0)

}

else

{

qipan[n-1][m-1] = 'x'

num_mn++

}

}

int five::dangerlevel(int a, int b)

{

int level = 0

for(int i = 1 a+i<=19i ++)

{

if(qipan[a+i][b] == '.' &&a + i <= 19)

{

i = i+1

break

}

if(qipan[a +i][b] == 'x' &&a + i <= 19)

break

}

level += (i-1)

for(i = 1 a-i>=0i ++)

{

if(qipan[a-i][b] == '.' &&(a-i) >= 0)

{

i = i+1

break

}

if(qipan[a-i][b] == 'x' &&(a-i) >= 0)

break

}

level += (i-1)

for(i = 1 b+i<=19 i ++)

{

if(qipan[a][b + i] == '.' &&b + i <= 19)

{

i = i+1

break

}

if(qipan[a][b + i] == 'x' &&b + i <= 19)

break

}

level += (i-1)

for( i = 1 b-i>=0 i ++)

{

if(qipan[a][b - i] == '.' &&(b-i) >= 0)

{

i = i+1

break

}

if(qipan[a][b - i] == 'x' &&(b-i) >= 0)

break

}

for( i = 1 a+i<=19&&b+i<=19i ++)

{

if(qipan[a + i][b + i] == '.' &&b+i <= 19 &&a+i <= 19)

{

i = i+1

break

}

if(qipan[a + i][b + i] == 'x' &&b+i <= 19 &&a+i <= 19)

break

}

level += (i-1)

for( i = 1 a-i>= 0 &&b-i >= 0i ++)

{

if(qipan[a - i][b - i] == '.' &&a-i>= 0 &&b-i >= 0)

{

i = i+1

break

}

if(qipan[a - i][b - i] == 'x' &&a-i>= 0 &&b-i >= 0)

break

}

level += (i-1)

for( i = 1 a-i>= 0 &&b+i <= 19 i ++)

{

if(qipan[a - i][b + i] == '.' &&a-i>= 0 && b+i <= 19)

{

i = i+1

break

}

if(qipan[a - i][b + i] == 'x' &&a-i>= 0 && b+i <= 19)

break

}

level += (i-1)

for( i = 1 a + i<= 19 &&b-i >= 0 i ++)

{

if(qipan[a + i][b - i] == '.' &&a + i<= 19 && b-i >= 0)

{

i = i+1

break

}

if(qipan[a + i][b - i] == 'x' &&a + i<= 19 && b-i >= 0)

break

}

level += (i-1)

return level

}

void five::attack()

{

int num1=1,num2=1,num3=1,num4=1

int A = 20 , B = 20 ,max = 0

for(int a = 0 a <19 a ++)

{

for(int b = 0 b <19 b ++)

{

if(qipan[a][b] == '.')

{

int level = 0

for(int i = 1 a+i<=19i ++)

{

if(qipan[a+i][b] == '.' &&a + i <= 19)

{

i = i+1

break

}

if(qipan[a +i][b] == 'o' &&a + i <= 19)

break

}

level += (i-1)

for(i = 1 a-i>=0i ++)

{

if(qipan[a-i][b] == '.' &&(a-i) >= 0)

{

i = i+1

break

}

if(qipan[a-i][b] == 'o' &&(a-i) >= 0)

break

}

level += (i-1)

for(i = 1 b+i<=19 i ++)

{

if(qipan[a][b + i] == '.' &&b + i <= 19)

{

i = i+1

break

}

if(qipan[a][b + i] == 'o' &&b + i <= 19)

break

}

level += (i-1)

for( i = 1 b-i>=0 i ++)

{

if(qipan[a][b - i] == '.' &&(b-i) >= 0)

{

i = i+1

break

}

if(qipan[a][b - i] == 'o' &&(b-i) >= 0)

break

}

for( i = 1 a+i<=19&&b+i<=19i ++)

{

if(qipan[a + i][b + i] == '.' &&b+i <= 19 &&a+i <= 19)

{

i = i+1

break

}

if(qipan[a + i][b + i] == 'o' &&b+i <= 19 &&a+i <= 19)

break

}

level += (i-1)

for( i = 1 a-i>= 0 &&b-i >= 0i ++)

{

if(qipan[a - i][b - i] == '.' &&a-i>= 0 &&b-i >= 0)

{

i = i+1

break

}

if(qipan[a - i][b - i] == 'o' &&a-i>= 0 &&b-i >= 0)

break

}

level += (i-1)

for( i = 1 a-i>= 0 &&b+i <= 19 i ++)

{

if(qipan[a - i][b + i] == '.' &&a-i>= 0 && b+i <= 19)

{

i = i+1

break

}

if(qipan[a - i][b + i] == 'o' &&a-i>= 0 && b+i <= 19)

break

}

level += (i-1)

for( i = 1 a + i<= 19 &&b-i >= 0 i ++)

{

if(qipan[a + i][b - i] == '.' &&a + i<= 19 && b-i >= 0)

{

i = i+1

break

}

if(qipan[a + i][b - i] == 'o' &&a + i<= 19 && b-i >= 0)

break

}

level += (i-1)

if(level >= max)

{

n = a + 1

m = b + 1

max = level

}

}

else

continue

}

}

qipan[n-1][m-1] = 'x'

}

void five::machinemn()

{

int Num1=1,Num2=1,Num3=1,Num4=1,A11 = 21,A12 = 21,A21 = 21,A22 = 21,A31 = 21,A32 = 21,A41 = 21,A42 = 21

for(int i = x i <x+5&&x+5<20 i ++)

{

if(qipan[y-1][i] == '.')

{

A11=i

break

}

if(qipan[y-1][i] == 'x')

break

if(qipan[y-1][i] == 'o')

Num1++

}

for(i = x-2i >= 0 i --)

{

if(qipan[y-1][i] == '.')

{

A12 = i

break

}

if(qipan[y-1][i] == 'x')

{

break

}

if(qipan[y-1][i] == 'o')

Num1++

}

////

for( i = y i <y+5 &&y+5 <20 i ++)

{

if(qipan[i][x-1] == '.')

{

A21 = i

break

}

if(qipan[i][x-1] == 'x')

{

break

}

if(qipan[i][x-1] == 'o')

Num2++

}

for(i = y-2i >= 0 i --)

{

if(qipan[i][x-1] == '.')

{

A22 = i

break

}

if(qipan[i][x-1] == 'x')

{

break

}

if(qipan[i][x-1] == 'o')

Num2++

}

////

for(i = 0 i <5 &&x+i<20 &&y+i<20i++ )

{

if(qipan[y+i][x+i] == '.')

{

A31 = i

break

}

if(qipan[y+i][x+i] == 'x')

{

break

}

if(qipan[y+i][x+i] =='o')

Num3++

}

for(i = 0 x - i -2>=0 &&y-i-2>=0 &&i <5i++ )

{

if(qipan[y-i-2][x-i-2] == '.')

{

A32 = i

break

}

if(qipan[y-i-2][x-i-2] == 'x')

break

if(qipan[y-i-2][x-i-2] == 'o')

Num3++

}

////

for(i = 0 x + i <20 &&y - i - 2 >= 0 &&i <5i ++)

{

if(qipan[y-i-2][x+i] == '.')

{

A41 = i

break

}

if(qipan[y-i-2][x+i] == 'x')

{

break

}

if(qipan[y-i-2][x+i] == 'o')

Num4++

}

for(i = 0 y + i <20 &&x - i - 2 >= 0 &&i <5i ++)

{

if(qipan[y+i][x-i-2] == '.')

{

A42 = i

break

}

if(qipan[y+i][x-i-2] == 'x')

{

break

}

if(qipan[y+i][x-i-2] == 'o')

Num4++

}

////

if(num_xy == 0 &&num_xy == 0)

{

m = n = 10

qipan[m-1][n-1] = 'x'

}

else if(num_xy == 1)

attack()

else if(num_xy == 1)

{

m = x+1

n = x+1

qipan[m-1][n-1] = 'x'

}

else if(Num1 == 4 &&A11 == 21 &&A12 != 21) //一排四个右边一头堵住

{

n =1 + y-1

m = 1 + A12

qipan[y-1][A12] = 'x'

}

else if(Num1 == 4 &&A12 == 21 &&A11 != 21) //一排四个左边边一头堵住

{

n =1 + y-1

m = 1 + A11

qipan[y-1][A11] = 'x'

}

else if(Num2 == 4 &&A21 == 21 &&A22 != 21) //一列四个下边一头堵住

{

n =1 + A22

m = 1 + x-1

qipan[A22][x-1] = 'x'

}

else if(Num2 == 4 &&A22 == 21 &&A21 != 21) //一列四个上边一头堵住

{

n =1 + A21

m = 1 + x-1

qipan[A21][x-1] = 'x'

}

else if(Num3 == 4 &&A31 == 21 &&A32 != 21) //一左上右下斜列四个右边一头堵住

{

n =1 + y - A32 - 2

m = 1 + x - A32 - 2

qipan[y-A32-2][x-A32-2] = 'x'

}

else if(Num3 == 4 &&A32 == 21 &&A31 != 21) //一左上右下斜列四个左边一头堵住

{

n =1 + y + A31

m = 1 + x + A31

qipan[y+A31][x+A31] = 'x'

}

else if(Num4 == 4 &&A41 == 21 &&A42 != 21) //一左下右上斜列四个右边一头堵住

{

n =1 + y + A42

m = 1 + x - A42 - 2

qipan[y+A42][x-A42-2] = 'x'

}

else if(Num4 == 4 &&A42 == 21 &&A41 != 21) //一左下右上斜列四个左边一头堵住

{

n =1 + y - A41 - 2

m = 1 + x + A41

qipan[y-A41-2][x+A41] = 'x'

}

else if(Num1==3 &&A11 != 21 &&A12 != 21) //一排3 个两头没堵

{

n =1 + y-1

m = 1 + A11

if(dangerlevel(y-1,A11) >= dangerlevel(y-1,A12))

qipan[y-1][A11] = 'x'

else

qipan[y-1][A12] = 'x'

}

else if(Num2==3&&A21 != 21 &&A22 != 21) //一列 3 个两头没堵

{

n =1 + A21

m = 1 + x-1

if(dangerlevel(A21,x-1) >= dangerlevel(A22,x-1))

qipan[A21][x-1] = 'x'

else

qipan[A22][x-1] = 'x'

}

else if(Num3 == 3&&A31 != 21 &&A32 != 21) //一左上右下斜列3 个两头没堵

{

n =1 + y + A31

m = 1 + x + A31

if(dangerlevel(y+A31,x+A31) >= dangerlevel(y-A32 - 2,y - A32 -2))

qipan[y+A31][x+A31] = 'x'

else

qipan[y-A32-2][x-A32 -2] = 'x'

}

else if(Num4==3 &&A41 != 21 &&A42 != 21) //一左下右上斜列3 个两头没堵

{

n =1 + y - A41 - 2

m = 1 + x + A41

if(dangerlevel(y-A41-2,x+A41) >= dangerlevel(y-A42-2,x+A42))

qipan[y-A41-2][x+A41] = 'x'

else

qipan[y-A42-2][x+A42] = 'x'

}

else if(Num1 == 2&&A11 != 21 &&A12 != 21) //一排2个两头没堵

{

n =1 + y-1

m = 1 + A11

qipan[y-1][A11] = 'x'

}

else if( Num2 == 2&&A21 != 21 &&A22 != 21) //一列2个两头没堵

{

n =1 + A21

m = 1 + x-1

qipan[A21][x-1] = 'x'

}

else if(Num3 == 2&&A31 != 21 &&A32 != 21) //一左上右下斜列2 个两头没堵

{

n =1 + y + A31

m = 1 + x + A31

qipan[y+A31][x+A31] = 'x'

}

else if(Num4==2 &&A41 != 21 &&A42 != 21) //一左下右上斜列2个两头没堵

{

n =1 + y - A41 - 2

m = 1 + x + A41

qipan[y-A41-2][x+A41] = 'x'

}

else

attack()

}

void five::showqipan()

{

int p=0,q=0

for(int i = 0 i <= 20 i++)

{

if(p<10)

{

cout <<p <<' '

}

else

cout <<p

p++

}

cout <<endl

for(i = 0 i <20 i++)

{

if(i>=0)

{

q++

if(q<10)

cout <<q <<' '

else

cout <<q

}

for(int j = 0 j <20 j ++)

cout <<qipan[i][j]<<' '

cout <<endl

}

}

void five::print()

{

int p=0,q=0

for(int i = 0 i <= 20 i++)

{

if(p<10)

{

cout <<p <<' '

}

else

cout <<p

p++

}

cout <<endl

for(i = 0 i <20 i++)

{

if(i>=0)

{

q++

if(q<10)

cout <<q <<' '

else

cout <<q

}

for(int j = 0 j <20 j ++)

{

cout <<qipan[i][j]<<' '

}

cout <<endl

}

}

bool five::IsxyWin()

{

int num1=1,num2=1,num3=1,num4=1

for(int i = x i <x+5&&x+5<20 i ++)

{

if(qipan[y-1][i] != 'o')

break

if(qipan[y-1][i] == 'o')

num1++

}

for(i = x-2i >= 0 i --)

{

if(qipan[y-1][i] != 'o')

break

if(qipan[y-1][i] == 'o')

num1++

}

for( i = y i <y+5 i ++)

{

if(qipan[i][x-1] != 'o')

break

if(qipan[i][x-1] == 'o')

num2++

}

for(i = y-2i >= 0 i --)

{

if(qipan[i][x-1] != 'o')

break

if(qipan[i][x-1] == 'o')

num2++

}

for(i = 0 i <5 &&x+i<20 &&y+i<20i++ )

{

if(qipan[y+i][x+i] != 'o')

break

if(qipan[y+i][x+i] =='o')

num3++

}

for(i = 0 x - i -2>=0 &&y-i-2>=0 &&i <5i++ )

{

if(qipan[y-i-2][x-i-2] != 'o')

break

if(qipan[y-i-2][x-i-2] == 'o')

num3++

}

for(i = 0 x + i <20 &&y - i - 2 >= 0 &&i <5i ++)

{

if(qipan[y-i-2][x+i] != 'o')

break

if(qipan[y-i-2][x+i] == 'o')

num4++

}

for(i = 0 y + i <20 &&x - i - 2 >= 0 &&i <5i ++)

{

if(qipan[y+i][x-i-2] != 'o')

break

if(qipan[y+i][x-i-2] == 'o')

num4++

}

if(num1>=5||num2>=5||num3>=5||num4>=5)

return 1

else

return 0

}

bool five::IsmnWin()

{

int num1=1,num2=1,num3=1,num4=1

for(int i = m i <m+5&&m+5<20 i ++)

{

if(qipan[n-1][i] != 'x')

break

if(qipan[n-1][i] == 'x')

num1++

}

for(i = m-2i >= 0 i --)

{

if(qipan[n-1][i] != 'x')

break

if(qipan[n-1][i] == 'x')

num1++

}

for( i = n i <n+5 i ++)

{

if(qipan[i][m-1] != 'x')

break

if(qipan[i][m-1] == 'x')

num2++

}

for(i = n-2i >= 0 i --)

{

if(qipan[i][m-1] != 'x')

break

if(qipan[i][m-1] == 'x')

num2++

}

for(i = 0 i <5 &&m+i<20 &&n+i<20i++ )

{

if(qipan[n+i][m+i] != 'x')

break

if(qipan[n+i][m+i] =='x')

num3++

}

for(i = 0 m - i -2>=0 &&n-i-2>=0 &&i <5i++ )

{

if(qipan[n-i-2][m-i-2] != 'x')

break

if(qipan[n-i-2][m-i-2] == 'x')

num3++

}

for(i = 0 m + i <20 &&n - i - 2 >= 0 &&i <5i ++)

{

if(qipan[n-i-2][m+i] != 'x')

break

if(qipan[n-i-2][m+i] == 'x')

num4++

}

for(i = 0 n + i <20 &&m - i - 2 >= 0 &&i <5i ++)

{

if(qipan[n+i][m-i-2] != 'x')

break

if(qipan[n+i][m-i-2] == 'x')

num4++

}

if(num1>=5||num2>=5||num3>=5||num4>=5)

return 1

else

return 0

}

void main()

{

five a

int temp

cout <<"欢迎体验本游戏!这是本游戏的棋盘:" <<endl

a.showqipan()

cout <<"双人游戏请按1,人机游戏请按2,退出请按3:"

cin >>temp

if(temp == 3)

exit(1)

if(temp == 1)

{

cout <<"您选择了双人游戏,下面游戏开始:" <<endl

for(int i = 0 i ++)

{

a.getpointxy()

a.print()

if(a.IsxyWin())

{

cout <<"白棋胜!" <<endl

break

}

a.getpointmn()

a.print()

if(a.IsmnWin())

{

cout <<"黑棋胜!" <<endl

break

}

}

}

if(temp == 2)

{

int temp1=0

cout <<"您选择了人机游戏,您是白棋('o'),电脑是黑棋('x'),下面游戏开始:" <<endl

cout <<"您先下请按1,电脑先下请按2:"

cin >>temp1

if(temp1 == 1)

{

for(int i = 0 i ++)

{

a.getpointxy()

a.print()

if(a.IsxyWin())

{

cout <<"你赢了!恭喜!" <<endl

break

}

a.machinemn()

a.print()

cout <<"电脑走(" <<a.getm() <<',' <<a.getn() <<')' <<endl

if(a.IsmnWin())

{

cout <<"哈哈,你输了!" <<endl

break

}

}

}

if(temp1 == 2)

{

for(int i = 0 i ++)

{

a.machinemn()

a.print()

if(a.IsmnWin())

{

cout <<"哈哈,你输了!" <<endl

break

}

a.getpointxy()

a.print()

if(a.IsxyWin())

{

cout <<"你赢了!恭喜!" <<endl

break

}

}

}

}

cout <<"Press any key to EXIT\n"

getch()

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/yw/9018554.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-24
下一篇2023-04-24

发表评论

登录后才能评论

评论列表(0条)

    保存