五子棋课程设计.docx
- 文档编号:8715550
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:22
- 大小:25.97KB
五子棋课程设计.docx
《五子棋课程设计.docx》由会员分享,可在线阅读,更多相关《五子棋课程设计.docx(22页珍藏版)》请在冰豆网上搜索。
五子棋课程设计
C语言课
程设计
学院:
班级:
姓名:
学号:
所在系:
指导教师:
2009年12月22号
一题目与要求
题目:
五子棋
要求:
利用C语言实现小型的五子棋人机对弈游戏
二问题的提出
本人计划编一个五子棋游戏程序,主要是实现人机对弈的功能。
三功能要求
1、实现人机对弈功能;
2、基本的C作图的方法及循环控制模块;
3、评分规则及胜负判断。
四详细设计
1.程序中用到的库函数所在头文件应用#include命令包含进来
2.定义符号常量:
(1)定义画棋盘所需的制表符
(2)定义棋盘左上角点在屏幕上的位置
(3)定义12号玩家的操作键键码
(4)定义游戏中途退出键
(5)定义棋盘上交叉点的状态并指出棋子归属
(6)定义按键类别
(7)定义真假符号常量
3.定义棋盘交叉点坐标的数据结构棋盘交叉点坐标的数据结构
4.自定义函数原型说明
5.定义全局变量定义全局变量
6.主函数:
(1)初始化图象,数据
(2)获取用户的按键值
(3)判断按键类别
(4)定义退出键(
(5)清屏
(6)定义落子键(
(7)定义走棋落子错误和正确
(8)如果当前行棋方赢棋退出循环标志置,否则交换行棋方
(9)定义光标移动键和无效键
(10)游戏结束
7.界面初始化,数据初始化:
(1)先手方为1号玩家
(2)棋盘数据清零
(3)光标初始位置
(4)显示操作键说明
(5)显示当前行棋方
(6)光标移至棋盘的左上角点处
8.画棋盘
(1)画棋盘上的交叉点
(2)交叉点上是一号玩家的棋子
(3)交叉点上是二号玩家的棋子
(4)左上角交叉点
(5)左下角交叉点
(6)右上角交叉点
(7)右下角交叉点
(8)左边界交叉点
(9)右边界交叉点
(10)上边界交叉点上边界交叉点
(11)下边界交叉点
(12)棋盘中间的交叉点
9.交换行棋方
10.获取按键值,如果用户没有按键,空循环
11.落子错误处理
12.赢棋处理赢棋处理
13.走棋:
判断交叉点上有无棋子,若没有棋子,则可以落子
14.判断当前行棋方落子后是否赢棋即判断在指定方向上是否有连续5个行棋方的棋子
15.判断在指定方向上是否有连续5个行棋方的棋子:
(1)在水平方向
(2)在垂直方向
(3)在左下至右上的斜方向
(4)在左上至右下的斜方向
16.移动光标
17.游戏结束处理
18.显示当前行棋方
19.落子正确处理落子正确处理
20.检查用户的按键类别:
(1)退出键
(2)落子键
(3)光标移动键
(4)按键无效等。
五、总体设计结构图
编译预处理
主函数
设计界面
胜负判断
定义其他功能键
六、调试与测试
将全部程序分块进行调试,测试结果运行正常
七、下面是五子棋原程序
/*程序中用到的库函数所在头文件应用#include命令包含进来*/
#include
#include
#include
#include
#include
#include
#include
#include
#definepi3.1415926
/**********************************************************/
/*定义符号常量*/
/*定义画棋盘所需的制表符*/
#defineCROSSRU0xbf/*右上角点*/
#defineCROSSLU0xda/*左上角点*/
#defineCROSSLD0xc0/*左下角点*/
#defineCROSSRD0xd9/*右下角点*/
#defineCROSSL0xc3/*左边*/
#defineCROSSR0xb4/*右边*/
#defineCROSSU0xc2/*上边*/
#defineCROSSD0xc1/*下边*/
#defineCROSS0xc5/*十字交叉点*/
/*定义棋盘左上角点在屏幕上的位置*/
#defineMAPXOFT5
#defineMAPYOFT2
/*定义1号玩家的操作键键码*/
#definePLAY1UP0x1157/*上移--'W'*/
#definePLAY1DOWN0x1f53/*下移--'S'*/
#definePLAY1LEFT0x1e41/*左移--'A'*/
#definePLAY1RIGHT0x2044/*右移--'D'*/
#definePLAY1DO0x3920/*落子--空格键*/
/*定义2号玩家的操作键键码*/
#definePLAY2UP0x4800/*上移--方向键up*/
#definePLAY2DOWN0x5000/*下移--方向键down*/
#definePLAY2LEFT0x4b00/*左移--方向键left*/
#definePLAY2RIGHT0x4d00/*右移--方向键right*/
#definePLAY2DO0x1c0d/*落子--回车键Enter*/
/*若想在游戏中途退出,可按Esc键*/
#defineESCAPE0x011b
/*定义棋盘上交叉点的状态,即该点有无棋子*/
/*若有棋子,还应能指出是哪个玩家的棋子*/
#defineCHESSNULL0/*没有棋子*/
#defineCHESS1'O'/*一号玩家的棋子*/
#defineCHESS2'X'/*二号玩家的棋子*/
/*定义按键类别*/
#defineKEYEXIT0/*退出键*/
#defineKEYFALLCHESS1/*落子键*/
#defineKEYMOVECURSOR2/*光标移动键*/
#defineKEYINVALID3/*无效键*/
/*定义符号常量:
真,假---真为1,假为0*/
#defineTRUE1
#defineFALSE0
/**********************************************************/
/*定义数据结构*/
/*棋盘交叉点坐标的数据结构*/
structpoint
{
intx,y;
};
/**********************************************************/
/*自定义函数原型说明*/
voidInit(void);
intGetKey(void);
intCheckKey(intpress);
intChangeOrder(void);
intChessGo(intOrder,structpointCursor);
voidDoError(void);
voidDoOK(void);
voidDoWin(intOrder);
voidMoveCursor(intOrder,intpress);
voidDrawCross(intx,inty);
voidDrawMap(void);
intJudgeWin(intOrder,structpointCursor);
intJudgeWinLine(intOrder,structpointCursor,intdirection);
voidShowOrderMsg(intOrder);
voidEndGame(void);
/**********************************************************/
/**********************************************************/
/*定义全局变量*/
intgPlayOrder;/*指示当前行棋方*/
structpointgCursor;/*光标在棋盘上的位置*/
chargChessBoard[19][19];/*用于记录棋盘上各点的状态*/
/**********************************************************/
/**********************************************************/
/*主函数*/
voidmain()
{
intpress;
intbOutWhile=FALSE;/*退出循环标志*/
inti,j=0,x,y,k=1;
inta=DETECT,b;
initgraph(&a,&b,"d:
\\tc");
while(!
kbhit())
{j+=10;
for(i=0;i<=2000;i++)
{
x=300+100*cos(2*i*pi/1000)*sin(i*pi/1000+j*pi/1000);
y=240+100*cos(2*i*pi/1000)*cos(i*pi/1000+j*pi/1000);
if(j%500==0)k++;
putpixel(x,y,k);
}
delay(5000);
cleardevice();
}
getch();
closegraph();
Init();/*初始化图象,数据*/
while
(1)
{
press=GetKey();/*获取用户的按键值*/
switch(CheckKey(press))/*判断按键类别*/
{
/*是退出键*/
caseKEYEXIT:
clrscr();/*清屏*/
bOutWhile=TRUE;
break;
/*是落子键*/
caseKEYFALLCHESS:
if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/
DoError();/*落子错误*/
else
{
DoOK();/*落子正确*/
/*如果当前行棋方赢棋*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile=TRUE;/*退出循环标志置为真*/
}
/*否则*/
else
/*交换行棋方*/
ChangeOrder();
}
break;
/*是光标移动键*/
caseKEYMOVECURSOR:
MoveCursor(gPlayOrder,press);
break;
/*是无效键*/
caseKEYINVALID:
break;
}
if(bOutWhile==TRUE)
break;
}
/*游戏结束*/
EndGame();
}
/**********************************************************/
/*界面初始化,数据初始化*/
voidInit(void)
{
inti,j;
char*Msg[]=
{
"Player1key:
",
"UP----w",
"DOWN--s",
"LEFT--a",
"RIGHT-d",
"DO----space",
"",
"Player2key:
",
"UP----up",
"DOWN--down",
"LEFT--left",
"RIGHT-right",
"DO----ENTER",
"",
"exitgame:
",
"ESC",
NULL,
};
/*先手方为1号玩家*/
gPlayOrder=CHESS1;
/*棋盘数据清零,即棋盘上各点开始的时候都没有棋子*/
for(i=0;i<19;i++)
for(j=0;j<19;j++)
gChessBoard[i][j]=CHESSNULL;
/*光标初始位置*/
gCursor.x=gCursor.y=0;
/*画棋盘*/
textmode(C40);
DrawMap();
/*显示操作键说明*/
i=0;
textcolor(GREEN);
while(Msg[i]!
=NULL)
{
gotoxy(25,3+i);
cputs(Msg[i]);
i++;
}
/*显示当前行棋方*/
ShowOrderMsg(gPlayOrder);
/*光标移至棋盘的左上角点处*/
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*画棋盘*/
voidDrawMap(void)
{
inti,j;
clrscr();
for(i=0;i<19;i++)
for(j=0;j<19;j++)
DrawCross(i,j);
}
/*画棋盘上的交叉点*/
voidDrawCross(intx,inty)
{
gotoxy(x+MAPXOFT,y+MAPYOFT);
/*交叉点上是一号玩家的棋子*/
if(gChessBoard[x][y]==CHESS1)
{
textcolor(LIGHTBLUE);
putch(CHESS1);
return;
}
/*交叉点上是二号玩家的棋子*/
if(gChessBoard[x][y]==CHESS2)
{
textcolor(LIGHTBLUE);
putch(CHESS2);
return;
}
textcolor(WHITE);
/*左上角交叉点*/
if(x==0&&y==0)
{
putch(CROSSLU);
return;
}
/*左下角交叉点*/
if(x==0&&y==18)
{
putch(CROSSLD);
return;
}
/*右上角交叉点*/
if(x==18&&y==0)
{
putch(CROSSRU);
return;
}
/*右下角交叉点*/
if(x==18&&y==18)
{
putch(CROSSRD);
return;
}
/*左边界交叉点*/
if(x==0)
{
putch(CROSSL);
return;
}
/*右边界交叉点*/
if(x==18)
{
putch(CROSSR);
return;
}
/*上边界交叉点*/
if(y==0)
{
putch(CROSSU);
return;
}
/*下边界交叉点*/
if(y==18)
{
putch(CROSSD);
return;
}
/*棋盘中间的交叉点*/
putch(CROSS);
}
/*交换行棋方*/
intChangeOrder(void)
{
if(gPlayOrder==CHESS1)
gPlayOrder=CHESS2;
else
gPlayOrder=CHESS1;
return(gPlayOrder);
}
/*获取按键值*/
intGetKey(void)
{
charlowbyte;
intpress;
while(bioskey
(1)==0)
;/*如果用户没有按键,空循环*/
press=bioskey(0);
lowbyte=press&0xff;
press=press&0xff00+toupper(lowbyte);
return(press);
}
/*落子错误处理*/
voidDoError(void)
{
sound(1200);
delay(50);
nosound();
}
/*赢棋处理*/
voidDoWin(intOrder)
{
sound(1500);delay(100);
sound(0);delay(50);
sound(800);delay(100);
sound(0);delay(50);
sound(1500);delay(100);
sound(0);delay(50);
sound(800);delay(100);
sound(0);delay(50);
nosound();
textcolor(RED+BLINK);
gotoxy(25,20);
if(Order==CHESS1)
cputs("PLAYER1WIN!
");
else
cputs("PLAYER2WIN!
");
gotoxy(25,21);
cputs("\\<^+^>/");
getch();
}
/*走棋*/
intChessGo(intOrder,structpointCursor)
{
/*判断交叉点上有无棋子*/
if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL)
{
/*若没有棋子,则可以落子*/
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
textcolor(LIGHTBLUE);
putch(Order);
gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);
gChessBoard[Cursor.x][Cursor.y]=Order;
returnTRUE;
}
else
returnFALSE;
}
/*判断当前行棋方落子后是否赢棋*/
intJudgeWin(intOrder,structpointCursor)
{
inti;
for(i=0;i<4;i++)
/*判断在指定方向上是否有连续5个行棋方的棋子*/
if(JudgeWinLine(Order,Cursor,i))
returnTRUE;
returnFALSE;
}
/*判断在指定方向上是否有连续5个行棋方的棋子*/
intJudgeWinLine(intOrder,structpointCursor,intdirection)
{
inti;
structpointpos,dpos;
constinttestnum=5;
intcount;
switch(direction)
{
case0:
/*在水平方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y;
dpos.x=1;
dpos.y=0;
break;
case1:
/*在垂直方向*/
pos.x=Cursor.x;
pos.y=Cursor.y-(testnum-1);
dpos.x=0;
dpos.y=1;
break;
case2:
/*在左下至右上的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y+(testnum-1);
dpos.x=1;
dpos.y=-1;
break;
case3:
/*在左上至右下的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y-(testnum-1);
dpos.x=1;
dpos.y=1;
break;
}
count=0;
for(i=0;i { if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) { if(gChessBoard[pos.x][pos.y]==Order) { count++; if(count>=testnum) returnTRUE; } else count=0; } pos.x+=dpos.x; pos.y+=dpos.y; } returnFALSE; } /*移动光标*/ voidMoveCursor(intOrder,intpress) { switch(press) { casePLAY1UP: if(Order==CHESS1&&gCursor.y>0) gCursor.y--; break; casePLAY1DOWN: if(Order==CHESS1&&gCursor.y<18) gCursor.y++; break; casePLAY1LEFT: if(Order==CHESS1&&gCursor.x>0) gCursor.x--; break; casePLAY1RIGHT: if(Order==CHESS1&&gCursor.x<18) gCursor.x++; break; casePLAY2UP: if(Order==CHESS2&&gCursor.y>0) gCursor.y--; break; casePLAY2DOWN: if(Order==CHESS2&&gCursor.y<18) gCursor.y++; break; casePLAY2LEFT: if(Order==CHESS2&&gCursor.x>0) gCursor.x--; break; casePLAY2RIGHT: if(Order==CHESS2&&gCursor.x<18) gCursor.x++; break; } gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); } /*游戏结束处理*/ voidEndGame(void) { textmode(C80); } /*显示当前行棋方*/ voidShowOrderMsg(intOrder) { gotoxy(6,MAPYOFT+20); textcolor(LIGHTRED); if(Order==CHESS1) cputs("Player1go! "); else cputs("Player2go! "); gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); } /*落子正确处理*/ voidDoOK(void)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 五子棋 课程设计