项目名称五子棋.docx
《项目名称五子棋.docx》由会员分享,可在线阅读,更多相关《项目名称五子棋.docx(16页珍藏版)》请在冰点文库上搜索。
项目名称五子棋
项目名称:
五子棋
姓名:
司远征
学号:
02092050
班级:
信计22
完成时间:
2004-5-9
指导教师:
罗建军
一.项目背景
1.项目任务
编写人机对弈的五子棋游戏
2.项目功能
1)人机交互下子
2)电脑有一定的防御能力
3)用户可以任意终止游戏或重新开始
4)可以判断双方的输赢
3.运行条件
Windows98/XP
VisualC++6.0
二.项目实现
1.算法
1)要完成该游戏首先要解决显示问题,因此定义一棋盘类。
该类中应包括棋盘信息,判断
输赢的函数,电脑完成计算的函数,以及游戏终止的函数。
定义的棋盘类如下:
classQipan
{public:
charQizi[9][9];//棋盘信息
charC_Weizi[2];//存放电脑要下的棋子坐标
voidQipanInitialize();//对棋盘初始化
~Qipan();
voidQipan:
:
ShowMe();//显示棋盘
boolQipan:
:
Check();//判断棋盘是否已下满
voidC_Qizi(inti0,intj0);//电脑计算出要下的坐标
boolWin_lose(chara,inti0,intj0);//判断输赢
};
用Qizi[9][9]来存放各位置的棋子信息(未下的为*,电脑的为1,用户的为0),用户输入要下棋子坐标
后,电脑根据用户刚下的位置计算自己要下的位置,用伪代码描述为:
1)获得用户刚下的位置坐标i0,j0
2)在I0,J0所在的行和列分别查找用户的棋子个数sum_line,sum_row
3)if(sum_row>=sum_line)
{
从I0,J0开始向左查找相连的子;
if(没有空位)
{再从I0,J0向又查找;
if(没有空位)
{从该位置向右查找空位;
保存该位置到C_Weizi[2];
}
else
{保存该位置到C_Weizi[2];}
}
else
{保存该位置到C_Weizi[2];}
}
else
{
仿造上述方法在列中查找;
找到后保存该位置到C_Weizi[2];
}
电脑根据计算所得的坐标下子。
2)主函数的流程:
初始化棋盘;
显示棋盘;
while(棋盘未下满)
{用户输入要下的位置i0,j0;
根据i0,j0的值执行相应的功能;
判断是否赢了;
if(赢)
{break;}
else
{电脑计算并下子;
判断是否赢了;
}
2.程序
#include
//定义棋盘类
classQipan
{public:
charQizi[9][9];//棋盘信息
charC_Weizi[2];//存放电脑要下的棋子坐标
voidQipanInitialize();//对棋盘初始化
~Qipan();
voidQipan:
:
ShowMe();//显示棋盘
boolQipan:
:
Check();//判断棋盘是否已下满
voidC_Qizi(inti0,intj0);//电脑计算出要下的坐标
boolWin_lose(chara,inti0,intj0);//判断输赢
};
//定义棋盘初始化函数
voidQipan:
:
QipanInitialize()
{
for(inti=0;i<=8;i++)
{for(intj=0;j<=8;j++)
Qizi[i][j]='*';
}
}
//定义解构函数
Qipan:
:
~Qipan()
{cout<"<//定义显示函数
voidQipan:
:
ShowMe()
{
for(inti=0;i<=8;i++)
{
switch(i)
{
case2:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<"<else
cout<}
break;
}
case3:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<else
cout<}
break;
}
case4:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<else
cout<}
break;
}
case5:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<else
cout<}
break;
}
case6:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<else
cout<}
break;
}
default:
{
for(intj=0;j<=8;j++)
{if(j==8)
cout<else
cout<}
}
}
}
}
//判断是否棋盘已下满
boolQipan:
:
Check()
{
for(inti=0;i<=8;i++)
{
for(intj=0;j<=8;j++)
{
if(Qizi[i][j]=='*')
returntrue;
}
}
returnfalse;
}
//电脑计算要下的子坐标并保存
voidQipan:
:
C_Qizi(inti0,intj0)
{
intsum_line=0,sum_row=0;
for(inti=0;i<=8;i++)
{if(Qizi[i][j0]=='0')
sum_line++;
}
for(intj=0;j<=8;j++)
{if(Qizi[i0][j]=='0')
sum_row++;
}//比较横行和纵行上人的棋子个数
if(sum_row>=sum_line)
{
j=j0;
while(Qizi[i0][j]=='0'&&j>=0)
j--;
if(j<0||Qizi[i0][j]=='1')
{
j=j0;
while(Qizi[i0][j]=='0'&&j<=8)
j++;
if(Qizi[i0][j]=='1')
{
j=j0;
while((Qizi[i0][j]=='1'||Qizi[i0][j]=='0')&&j<=8)
j++;
C_Weizi[0]=i0;//存放要下的位置坐标
C_Weizi[1]=j;
}
else
{C_Weizi[0]=i0;//存放要下的位置坐标
C_Weizi[1]=j;
}
}
else
{C_Weizi[0]=i0;//存放要下的位置坐标
C_Weizi[1]=j;
}
}
//如果纵行人的棋子较多
else
{//从人刚下的位置往上检验相连的子
i=i0;
while(Qizi[i][j0]=='0'&&i>=0)
i--;
if(i<0||Qizi[i][j0]=='1')
{i=i0;
while(Qizi[i][j0]=='0'&&i<=8)
i++;
if(Qizi[i][j0]=='1')
{
while((Qizi[i][j0]=='0'||Qizi[i][j0]=='1')&&i<=8)
i++;
C_Weizi[0]=i;
C_Weizi[1]=j0;
}
else
{C_Weizi[0]=i;
C_Weizi[1]=j0;
}
}
else
{C_Weizi[0]=i;
C_Weizi[1]=j0;
}
}
}
//判断输赢(可以对人和电脑判断)
boolQipan:
:
Win_lose(chara,inti0,intj0)
{inti=i0-1;intj=j0-1;
intsum_line=0,sum_row=0,sum_xie1=0,sum_xie2=0;
while(Qizi[i][j0]==a&&i>=0)
i--;
i+=1;
while(Qizi[i][j0]==a)
{
sum_line++;
i++;
}
if(sum_line==5)returntrue;//判断纵行是否满足
while(Qizi[i0][j]==a&&j>=0)
j--;
j+=1;
while(Qizi[i0][j]==a)
{sum_row++;
j++;
}
if(sum_row==5)returntrue;//判断横行是否满足
i=i0-1;j=j0-1;
while(Qizi[i][j]==a&&i>=0&&j>=0)
{i--;j--;}
i+=1;
j+=1;
while(Qizi[i][j]==a)
{sum_xie1++;i++;j++;}
if(sum_xie1==5)returntrue;//判断斜行是否满足
i=i0-1;j=j0+1;
while(Qizi[i][j]==a&&i>=0&&j>=0)
{i--;j++;}
i+=1;j-=1;
while(Qizi[i][j]==a)
{sum_xie2++;i++;j--;}
if(sum_xie2==5)returntrue;//判断另一斜行是否满足
returnfalse;
}
//主函数
voidmain()
{
Qipanqipan1;
qipan1.QipanInitialize();//初始化棋盘
inti=1,j=1;
while(qipan1.Check())//当棋盘全部下满时停止游戏
{
qipan1.ShowMe();
if(qipan1.Win_lose('1',i-1,j-1))//判断电脑是否赢了
{
cout<<"你输了!
!
"<break;
}
else
{
cout<<"输入棋子位置:
";
cin>>i>>j;
if(i==0&&j==0)
{break;}
else
{
if(i==-1&&j==-1)
{
qipan1.QipanInitialize();
qipan1.ShowMe();
cout<<"输入棋子位置:
";//刷新之后重新开始
cin>>i>>j;
qipan1.Qizi[i-1][j-1]='0';
if(qipan1.Win_lose('0',i-1,j-1))
{
cout<<"你赢了!
!
"<break;
}
else
{//电脑完成计算
qipan1.C_Qizi(i-1,j-1);
qipan1.Qizi[qipan1.C_Weizi[0]][qipan1.C_Weizi[1]]='1';
}
}
else
{//输入的坐标必须满足条件
while(i<=0||i>9||j<=0||j>9||qipan1.Qizi[i-1][j-1]=='0'||
qipan1.Qizi[i-1][j-1]=='1')
{
cout<<"请重新输入:
";
cin>>i>>j;
}
qipan1.Qizi[i-1][j-1]='0';
//判断人是否赢了
if(qipan1.Win_lose('0',i-1,j-1))
{
cout<<"你赢了!
!
"<break;
}
else
{//电脑完成计算
qipan1.C_Qizi(i-1,j-1);
qipan1.Qizi[qipan1.C_Weizi[0]][qipan1.C_Weizi[1]]='1';
}
}
}
}
}
}
三.项目总结
1)编写类的多个成员函数时应该逐个编写并检验,否则出错的话很难查找。
2)一个程序的关键部分是算法,让电脑做一件就要为它编制相应的算法。
3)编写程序时应该考虑到所有的可能性,并给出相应的处理方法。
4)逐步求精。
例如当编写电脑计算如何下子的函数时,先实现一些比较简单的功能,让它可以给出一个
没有下过子的位置,然后检验该函数,成功的话,就说明该函数的接口是可行的,然后只须再改进该、
函数即可,增强它的功能。