2012年C语言五子棋课程设计报告.doc

上传人:wux****ua 文档编号:8368874 上传时间:2020-03-28 格式:DOC 页数:21 大小:255.50KB
返回 下载 相关 举报
2012年C语言五子棋课程设计报告.doc_第1页
第1页 / 共21页
2012年C语言五子棋课程设计报告.doc_第2页
第2页 / 共21页
2012年C语言五子棋课程设计报告.doc_第3页
第3页 / 共21页
点击查看更多>>
资源描述
本科控制软件设计课程设计题 目 五子棋 学 院 计信院 专 业 自动化 年 级 2011级 学 号 222011321042081 姓 名 谯平 同 组 人 张健、李益 指 导 教 师 黄仁杰 2012年 9 月 6 日目 录1、 设计简介 32、 设计模块 43、 小组分工 44、 流程图 45、 设计过程 56、 调试过程 67、 分析与总结 98、 源程序 9Table1、 设计简介 五子棋是一种传统的棋盘游戏,是起源于中国古代的传统黑白棋种之一。发展于日本,流行于欧美。容易上手,老少皆宜,而且趣味横生,引人入胜;不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。这种游戏用笔纸都可以进行。 本程序设计为人与人对弈,双方棋子为一种颜色。一方执O棋,一方执X棋,执O形棋的一方先行下子,移动光标键为“w(上)、s(下)、a(左)、d(右)”,落子键位“空格”,然后另一方走棋,移动光标键为“上、下、左、右”,落子键为“Enter。接着双方轮流走棋,每方都试图在游戏结束前让自己的棋子在横线、竖线、斜线方向五子相连,首先实现五子相连的一方获胜,游戏结束。程序执行过程中,要求棋盘、棋子时时可见,并且人可以通过按键盘按键移动光标,摆放棋子。同时在落子不同情况以及出现赢家的时候都会出现相应的声音。二、设计模块3、 小组分工 李益:初始化模块 谯平:下棋操作模块 张健:胜负判断模块四、流程图5、 设计过程 1、列出所需头文件名 2、定义棋盘的制符表及位置 3、定义双方玩家各自的操作键 4、定义数据结构 5、说明自定义函数原型 6、定义全局变量 7、初始化图像以及获得按键值 8、嵌入各自定义函数编写主函数 9、编写界面初始化函数void Init(void) 10、编写画棋盘函数void DrawMap(void) 11、编写交换棋手函数int ChangeOrder(void) 12、编写获取按键值函数int GetKey(void) 13、编写落子处理函数void DoError(void) 14、编写赢棋处理函数void DoWin(int Order) 15、编写走棋函数int ChessGo(Order , point Cursor) 16、编写判断是否赢棋函数int JudgeWin(Order,point Cursor) 17、编写判断在规定方向是否有五子相连函数int JudgeWinline(Order,point Cursor) 18、编写移动光标函数void MoveCursor(Order,press) 19、编写游戏结束处理函数void EndGame(void) 20、编写显示当前棋方函数void ShowOrderMsg(Order) 21、编写落子正确处理函数void DoOK(void) 22、编写检查用户按键类别函数int CheckKey(press)6、 调试过程 运行平台:C/C+程序设计学习与实验系统 1、点击运行,出现棋盘界面 2、根据界面提示键落子,玩家一先下,双方轮流落子。 3、一方五子相连,判出赢家,游戏结束。 4按任意键退出游戏。七、问题与与总结 1、用十六进制数制表格的方法不了解,参照网例的时候也不是很明白原理,以至于表格不是很完善,两行中间的一行在棋盘上没有清晰的显示出来。 2、设计这样稍微复杂的程序时,我们要多多利用自定义函数的嵌入方法,这样把主程序分为若干个自定义函数,不仅可以减少程序设计中的遗漏现象,还有利于我们建立完善的设计思维模式。 3、设计程序前要多翻阅资料与阅读范例,尽量减少程序编写时犯错,程序编写时犯错很浪费时间和精力,而且往往很难找出错误的地方。 4、编程的前提是读懂其他程序,平时需要多练习才行,这次设计的过程步履维艰,就是因为没有长期的阅读练习和教训累积。八、源程序 /* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */ #include #include #include #include #include /*/ /* 定义符号常量 */ /*定义画棋盘所需的制表符*/ #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 KEYEXIT 0/*退出键*/ #define KEYFALLCHESS 1/*落子键*/ #define KEYMOVECURSOR 2/*光标移动键*/ #define KEYINVALID 3/*无效键*/ /*定义符号常量: 真, 假 - 真为1, 假为0 */ #define TRUE 1 #define FALSE 0 /*/ /*定义数据结构 */ /*棋盘交叉点坐标的数据结构*/ struct point int x,y; ; /*/ /*自定义函数原型说明 */ void Init(void); int GetKey(void); int CheckKey(int press); int ChangeOrder(void); int ChessGo(int Order,struct point Cursor); void DoError(void); void DoOK(void); void DoWin(int Order); void MoveCursor(int Order,int press); void DrawCross(int x,int y); void DrawMap(void); int JudgeWin(int Order,struct point Cursor); int JudgeWinLine(int Order,struct point Cursor,int direction); void ShowOrderMsg(int Order); void EndGame(void); /*/ /*/ /* 定义全局变量 */ int gPlayOrder; /*指示当前行棋方 */ struct point gCursor; /*光标在棋盘上的位置 */ char gChessBoard1919;/*用于记录棋盘上各点的状态*/ /*/ /*/ /*主函数*/ void main() int press; int bOutWhile=FALSE;/*退出循环标志*/ Init();/*初始化图象,数据*/ while(1) press=GetKey();/*获取用户的按键值*/ switch(CheckKey(press)/*判断按键类别*/ /*是退出键*/ case KEYEXIT: clrscr();/*清屏*/ bOutWhile = TRUE; break; /*是落子键*/ case KEYFALLCHESS: if(ChessGo(gPlayOrder,gCursor)=FALSE)/*走棋*/ DoError();/*落子错误*/ else DoOK();/*落子正确*/ /*如果当前行棋方赢棋*/ if(JudgeWin(gPlayOrder,gCursor)=TRUE) DoWin(gPlayOrder); bOutWhile = TRUE;/*退出循环标志置为真*/ /*否则*/ else /*交换行棋方*/ ChangeOrder(); break; /*是光标移动键*/ case KEYMOVECURSOR: MoveCursor(gPlayOrder,press); break; /*是无效键*/ case KEYINVALID: break; if(bOutWhile=TRUE) break; /*游戏结束*/ EndGame(); /*/ /*界面初始化,数据初始化*/ void Init(void) int i,j; char *Msg= Player1 key:, UP-w, DOWN-s, LEFT-a, RIGHT-d, DO-space, , Player2 key:, UP-up, DOWN-down, LEFT-left, RIGHT-right, DO-ENTER, , exit game:, ESC, NULL, ; /*先手方为1号玩家*/ gPlayOrder = CHESS1; /*棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/ for(i=0;i19;i+) for(j=0;j19;j+) gChessBoardij=CHESSNULL; /*光标初始位置*/ gCursor.x=gCursor.y=0; /*画棋盘*/ textmode(C40); DrawMap(); /*显示操作键说明*/ i=0; textcolor(BROWN); while(Msgi!=NULL) gotoxy(25,3+i); cputs(Msgi); i+; /*显示当前行棋方*/ ShowOrderMsg(gPlayOrder); /*光标移至棋盘的左上角点处*/ gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); /*画棋盘*/ void DrawMap(void) int i,j; clrscr(); for(i=0;i19;i+) for(j=0;j19;j+) DrawCross(i,j); /*画棋盘上的交叉点*/ void DrawCross(int x,int y) gotoxy(x+MAPXOFT,y+MAPYOFT); /*交叉点上是一号玩家的棋子*/ if(gChessBoardxy=CHESS1) textcolor(LIGHTBLUE); putch(CHESS1); return; /*交叉点上是二号玩家的棋子*/ if(gChessBoardxy=CHESS2) textcolor(LIGHTBLUE); putch(CHESS2); return; textcolor(GREEN); /*左上角交叉点*/ 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); /*交换行棋方*/ int ChangeOrder(void) if(gPlayOrder=CHESS1) gPlayOrder=CHESS2; else gPlayOrder=CHESS1; return(gPlayOrder); /*获取按键值*/ int GetKey(void) char lowbyte; int press; while (bioskey(1) = 0) ;/*如果用户没有按键,空循环*/ press=bioskey(0); lowbyte=press&0xff; press=press&0xff00 + toupper(lowbyte); return(press); /*落子错误处理*/ void DoError(void) sound(1200); delay(50); nosound(); /*赢棋处理*/ void DoWin(int Order) 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(PLAYER1 WIN!); else cputs(PLAYER2 WIN!); gotoxy(25,21); cputs( /); getch(); /*走棋*/ int ChessGo(int Order,struct point Cursor) /*判断交叉点上有无棋子*/ if(gChessBoardCursor.xCursor.y=CHESSNULL) /*若没有棋子, 则可以落子*/ gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); textcolor(LIGHTBLUE); putch(Order); gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); gChessBoardCursor.xCursor.y=Order; return TRUE; else return FALSE; /*判断当前行棋方落子后是否赢棋*/ int JudgeWin(int Order,struct point Cursor) int i; for(i=0;i4;i+) /*判断在指定方向上是否有连续5个行棋方的棋子*/ if(JudgeWinLine(Order,Cursor,i) return TRUE; return FALSE; /*判断在指定方向上是否有连续5个行棋方的棋子*/ int JudgeWinLine(int Order,struct point Cursor,int direction) int i; struct point pos,dpos; const int testnum = 5; int count; switch(direction) case 0:/*在水平方向*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y; dpos.x=1; dpos.y=0; break; case 1:/*在垂直方向*/ pos.x=Cursor.x; pos.y=Cursor.y-(testnum-1); dpos.x=0; dpos.y=1; break; case 2:/*在左下至右上的斜方向*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y+(testnum-1); dpos.x=1; dpos.y=-1; break; case 3:/*在左上至右下的斜方向*/ 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=0&pos.x=0&pos.y=testnum) return TRUE; else count=0; pos.x+=dpos.x; pos.y+=dpos.y; return FALSE; /*移动光标*/ void MoveCursor(int Order,int press) switch(press) case PLAY1UP: if(Order=CHESS1&gCursor.y0) gCursor.y-; break; case PLAY1DOWN: if(Order=CHESS1&gCursor.y0) gCursor.x-; break; case PLAY1RIGHT: if(Order=CHESS1&gCursor.x0) gCursor.y-; break; case PLAY2DOWN: if(Order=CHESS2&gCursor.y0) gCursor.x-; break; case PLAY2RIGHT: if(Order=CHESS2&gCursor.x18) gCursor.x+; break; gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); /*游戏结束处理*/ void EndGame(void) textmode(C80); /*显示当前行棋方*/ void ShowOrderMsg(int Order) gotoxy(6,MAPYOFT+20); textcolor(LIGHTRED); if(Order=CHESS1) cputs(Player1 go!); else cputs(Player2 go!); gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); /*落子正确处理*/ void DoOK(void) sound(500); delay(70); sound(600); delay(50); sound(1000); delay(100); nosound(); /*检查用户的按键类别*/ int CheckKey(int press) if(press=ESCAPE) return KEYEXIT;/*是退出键*/ else if ( ( press=PLAY1DO & gPlayOrder=CHESS1) | ( press=PLAY2DO & gPlayOrder=CHESS2) ) return KEYFALLCHESS;/*是落子键*/ else if ( press=PLAY1UP | press=PLAY1DOWN | press=PLAY1LEFT | press=PLAY1RIGHT | press=PLAY2UP | press=PLAY2DOWN | press=PLAY2LEFT | press=PLAY2RIGHT ) return KEYMOVECURSOR;/*是光标移动键*/ else return KEYINVALID;/*按键无效*/
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!