收藏 分销(赏)

五子棋电气班c语言程序设计报告.doc

上传人:丰**** 文档编号:5359178 上传时间:2024-10-30 格式:DOC 页数:31 大小:471.04KB 下载积分:12 金币
下载 相关 举报
五子棋电气班c语言程序设计报告.doc_第1页
第1页 / 共31页
五子棋电气班c语言程序设计报告.doc_第2页
第2页 / 共31页


点击查看更多>>
资源描述
C语言课程设计 C语言程序设计报告 题目: 五子棋 班级: 电气Qxxx班 人数: 3人 小组成员: xx、xx、xx 指导老师: xx 时间: 2015.11.30 目录 第一章 课程设计的目的和要求 3 1.1 课程设计的目的 3 1.2 课程设计的要求 3 1.3 课程设计的实验环境 3 第二章 功能描述 4 第三章 总体设计 5 3.1 功能模块设计 5 3.1.1 任务执行流程图 5 3.1.2 下棋函 数流程图 6 3.2 数据结构设计 7 3.2.1 定义结构体 7 3.2.2 定义数组 7 3.2.3 全局变量 7 3.3 函数功能描述 7 第四章 程序实现 8 4.1源码分析 8 4.2运行结果及界面介绍 22 第五章 后记 27 第一章 课程设计的目的和要求 1.1 课程设计的目的 1.加深对C语言数据类型,运算,语句结构及其程序设计的基本方法理解和掌握; 2.熟练掌握流程图的绘制、程序设计文档的书写; 3.通过编写一个完整的程序,一方面可以检查我们这学期的学习情况,为以后的学习打下坚实的基础; 4.熟悉C语言游戏编程,掌握五子棋游戏开发的基本原理,从而为以后的程序开发奠定基础。 1.2 课程设计的要求 1、编写程序代码,调试所写程序使其能够正确运行; 2、能进行基本的五子棋操作,有图形界面,能够用键盘操作; 3、能够实现悔棋、存档和读档等附加功能 1.3 课程设计的实验环境 该课程设计在设计与实验过程中需要在windows XP系统/windows 2000以上系统中进行,程序设计要求在visual C++6.0平台中进行,完成代码的编写、编译、调试、测试等工作。本游戏对计算机硬件和操作系统要求极低,所以在这里只是把自己的电脑硬件参数和系统参数列下: 硬件:Cpu:2.1GHZ,内存,2GB,硬盘:320GB,操作系统:windows xp 软件环境:安装VC++6.0 第二章 功能描述 本程序用C语言实现了五子棋游戏,能进行基本的五子棋操作。程序能实现界面的初始化功能、下棋功能、人机智能对战功能、胜负判断功能、悔棋功能、读档及存档功能,通过键盘操作控制下棋。 (1)显示欢迎界面。在游戏开始时出现一个欢迎的界面同时介绍了游戏的规则; (2)初始化功能。程序初始化屏幕和棋盘,默认玩家先行。 (3)下棋操作。利用W、S、A、D及空格键实现下棋操作,在下棋过程中能随时按ESC键退出。 (4)人机智能对战功能。电脑根据玩家的下棋对棋盘进行智能分析,然后下棋,实现人机对弈。 (5)悔棋功能。玩家可以有三次悔棋机会。 (6)胜负判断功能。程序能对下棋的结果进行判断,分出胜负。并显示获胜方。 (7)读档、存档功能。游戏中途退出会提示是否存档,如果存档,则下次开始的时候会提示是否读档继续上次的游戏。 第三章 总体设计 3.1 功能模块设计 开始 3.1.1 任务执行流程图 初始化程序 按Esc键 玩家行棋 按Esc键 玩家 获胜? 否 是 电脑行棋 显示玩家 获胜信息 电脑 获胜? 否 是 显示电脑 获胜信息 结束 3.1.2 下棋函数流程图 结束 向键值指示的方向移动一步 key=SPACE?? 显示获胜信息 Key=ESC? board[i][j]等于’ ’? 玩家 获胜? 下一步超出边界? 交换行棋方 画棋子,显示运动轨迹 获取key值 board[i][j] 赋值为’b’ 开始 是 否 否 是 否 是 否 否 是 3.2 数据结构设计 3.2.1 定义结构体 将棋盘上每个点的左边定义为一个结构体; typedef struct { int x, y; }point; 3.2.2 定义数组 定义数组board[15][15]表示棋盘,用来记录棋盘上每个棋子的状态; 3.2.3 全局变量 定义整形数组 back[4] 用来记录前两步双方下棋的状态,便于后面进行悔棋操作 定义整形 n = 3; 用来记录悔棋次数 3.3 函数功能描述 1、显示欢迎信息 bool welcome(); 2、初始化棋盘 void InitBoard(); 3、输出棋盘 void chessboard(); 4、判断胜负 int Win(char c); 5、下棋 void play(point &r); 6、显示获胜 void showsusscced(char c); 7、悔棋 bool BackStep(int back[]); 8、人机对战智能算法 void ComAlgo(point &r); 9、存盘函数 bool SaveLoad(); 10、读盘函数 bool DownLoad(); 第四章 程序实现 4.1源码分析 1、显示欢迎信息 bool welcome() { char ch; printf("\n\n\n\n"); printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n"); printf("┃ Welcome you to gobang World! ┃\n"); printf("┃1、You can use the A,D,W and S key to move the chessman; ┃\n"); printf("┃2、You can press Space key to enter after you move it; ┃\n"); printf("┃3、You can use Esc key to exit the game; ┃\n"); printf("┃4、Don't move the pieces out of the chessboard. ┃\n"); printf("┃ Do you want to continue?(Y/N) ┃\n"); printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n"); while (! strchr("YN", ch = toupper(getch()))) { putchar('\a'); } if(ch == 'N') return false; else return true; } 2、初始化棋盘 void InitBoard() { char ch; int i, j; printf("\n\n是否读档?(Y/N)\n"); if((ch = toupper(getch())) == 'Y' && DownLoad()) printf("读档成功!\n"); else { for(i = 0; i < 15; i ++) for(j = 0; j < 15; j ++) board[i][j] = ' '; } chessboard(); } 3、输出棋盘 void chessboard() { //清屏 system("cls"); //输出棋盘的上边缘 printf(" 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \n"); printf(" ┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓\n"); printf(" ┃ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┃\n"); for(int i = 1; i <= 15; i ++) { //输出列序号及相应的列元素 printf("%02d┣─", i); for(int j = 1; j <= 15; j ++) { switch (board[i - 1][j - 1]) { //(由于在命令行模式下显示,所以,颜色是颠倒的) case ' ': printf("┼─"); break; //如果当前位置无子,则输出棋盘 case 'h': printf("○─"); break; //如果是黑子,则输出黑子的符号 case 'b': printf("●─"); break; //如果是白子,则输出白子的符号 case 'g': printf("⊙─"); break; //显示光标 } } //输出每列的最后一个制表符 printf("┫%02d\n", i); printf(" ┃ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┃\n"); } printf(" ┗━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┷━┛ \n"); printf(" 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \n"); } 4、下棋 void play(point &r) { char key, c; do { while (! strchr("ADWSZ", key = toupper(getch()))) { if(key == 27 || key == 32) break; putchar('\a'); } switch(key) { case 'A': //向左 if(r.y <= 1) break; else r.y --; c = board[r.x - 1][r.y - 1]; //记录光标 board[r.x - 1][r.y - 1] = 'g'; chessboard(); board[r.x - 1][r.y - 1] = c; break; case 'D': //向右 if(r.y >= 15) break; else r.y ++; c = board[r.x - 1][r.y - 1]; board[r.x - 1][r.y - 1] = 'g'; chessboard(); board[r.x - 1][r.y - 1] = c; break; case 'W': //向上 if(r.x <= 1) break; else r.x --; c = board[r.x - 1][r.y - 1]; board[r.x - 1][r.y - 1] = 'g'; chessboard(); board[r.x - 1][r.y - 1] = c; break; case 'S': //向下 if(r.x >= 15) break; else r.x ++; c = board[r.x - 1][r.y - 1]; board[r.x - 1][r.y - 1] = 'g'; chessboard(); board[r.x - 1][r.y - 1] = c; break; case 32: //SPACE空格 if(board[r.x - 1][r.y - 1] != ' ') key = 0; //key的值修改为非32的数值 else { board[r.x - 1][r.y - 1] = 'b'; back[0] = r.x - 1; back[1] = r.y - 1; //记录当前位置,便于悔棋 chessboard(); } break; case 'Z': //悔棋 BackStep(back); break; case 27: //ESC退出 printf("Game Over!\n"); printf("是否存档?(Y/N)\n"); if((c = toupper(getch())) == 'Y' && SaveLoad()) printf("存档成功!\n"); exit(1); default: fflush(stdin); } }while(key != 32); } 注: 1、W、S、A、D分别表示上下左右键。如果超出了棋盘则不进行操作。否则向键值指示的方向移动一步。 2、c = board[r.x - 1][r.y - 1]; board[r.x - 1][r.y - 1] = 'g'; chessboard(); board[r.x - 1][r.y - 1] = c; 这四句表示记录当前移动位置,然后显示光标,显示完以后还原棋盘。 3、按空格键表示下棋,如果当前位置有棋子则不进行操作。back[0] = r.x - 1; back[1] = r.y - 1; 用于记录当前位置,便于悔棋 。 4、按Z悔棋 5、按ESC键退出,并且提示是否存档。 5、判断胜负 int Win(char c) { int i, j, ok = 1; //判断横着的5个是否都相等 for(i = 0; i < 15; i ++) { for(j = 0; j < 11; j ++) if(board[i][j]==c && board[i][j+1]==c && board[i][j+2]==c && board[i][j+3]==c && board[i][j+4]==c) return ok; } //判断竖着的5个是否都相等 for(j = 0; j < 15; j ++) { for(i = 0; i < 11; i ++) if(board[i][j]==c && board[i+1][j]==c && board[i+2][j]==c && board[i+3][j]==c && board[i+4][j]==c) return 1; } //判断左斜5个是否都相等 for(i = 0; i < 11; i ++) { for(j = 0; j < 11; j ++) if(board[i][j]==c && board[i+1][j+1]==c && board[i+2][j+2]==c && board[i+3][j+3]==c && board[i+4][j+4]==c) return ok; } //判断右斜5个是否都相等 for(i = 0; i < 11; i ++) { for(j = 14; j > 3; j --) if(board[i][j]==c && board[i+1][j-1]==c && board[i+2][j-2]==c && board[i+3][j-3]==c && board[i+4][j-4]==c) return ok; } return ok = 0; } 注:全篇扫面棋盘,从四个方向判断是否存在连着5个棋子 6、显示获胜 void showsusscced(char c) { if(c == 'b') { printf("游戏结束 白棋获胜!\n"); } else if(c == 'h') { printf("游戏结束 黑棋获胜!\n"); } else { printf("游戏结束 和棋!\n"); } } 7、悔棋 bool BackStep(int back[]) { if(n > 0) { board[back[0]][back[1]] = board[back[2]][back[3]] = ' '; chessboard(); n --; printf("悔棋成功,您还有%d次悔棋机会\n", n); return true; } else { printf("悔棋超过三次,您不能悔棋了!\n"); return false; } } 8、存盘函数 bool SaveLoad() { FILE *f; f = fopen("Load.TXT", "w"); if(f == NULL) { printf("存档失败!\n"); return false; } else { fwrite(board, sizeof(char), 225, f); fclose(f); return true; } } 9、读盘函数 bool DownLoad() { FILE *f; f = fopen("Load.TXT", "r"); if(f == NULL) { printf("读档失败!\n"); return false; } else { fread(board, sizeof(char), 225, f); fclose(f); return true; } } 注:存盘存在当前文件夹内的Load.txt文件中,用fwrite()函数和fread()函数读取和存储数组元素。 10、人机对战智能算法 void ComAlgo(point &r) { //棋型数组 int qiju[2][15][15][8][2] = {0}; /*其中第一个下标为0时表示白棋,为1时表示黑棋,第二和第三个下标表示(x,y), 第四个下标表示8个方向,最后一个下标为0时表示棋子数,为1时表示空格数*/ char d; //表示黑棋或白棋 int k, i, j, q, a = 1; //(k, i, j, q, 0/1)表示棋型数组; a, b用来计数 int b = 0, y1 = 0, y2 = 0, x1 = 0, x2 = 0; // b表示得分; (x1, y1)和(x2, y2)表示坐标 int a1[15][15] = {0}, a2[15][15] = {0}; //用来记录白棋和黑棋各个棋子位置的得分 /****************为双方填写棋型表************/ for(k = 0; k < 2; k ++) for(i = 0; i < 15; i ++) for(j = 0; j < 15; j ++) { if(board[i][j] == ' ') { for(q = 0; q < 8; q ++) { if(k == 0) d = 'b'; else d = 'h'; //左← if(q == 0 && j >= 0) { for(;j - a >= 0;) { if(board[i][j-a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i][j-a] == ' ' && j - a >= 0) {qiju[k][i][j][q][1] = 1; a = 1;} else { qiju[k][i][j][q][1] = 0; a = 1;} } //左上↖ if(q == 1 && i >= 0 && j >= 0) { for(;i - a >= 0 && j - a >= 0;) { if(board[i-a][j-a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i-a][j-a] == ' ' && j - a >= 0 && i - a >= 0) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //上↑ if(q == 2 && i >= 0) { for(;i - a >= 0;) { if(board[i-a][j] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i-a][j] == ' ' && i - a >= 0) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //右上↗ if(q == 3 && i >= 0 && j < 15) { for(;i - a >= 0 && j + a < 15;) { if(board[i-a][j+a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i-a][j+a] == ' ' && i - a >= 0 && j + a < 15) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //右→ if(q == 4 && j < 15) { for(;j + a < 15;) { if(board[i][j+a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i][j+a] == ' ' && j + a < 15) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //右下↘ if(q == 5 && i < 15 && j < 15) { for(;i + a < 15 && j + a < 15;) { if(board[i+a][j+a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i+a][j+a] == ' ' && i + a < 15 && j + a < 15) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //下↓ if(q == 6 && i < 15) { for(;i + a < 15;) { if(board[i+a][j] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i+a][j] == ' ' && i + a < 15) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } //左下↙ if(q == 7 && j >= 0 && i < 15) { for(;i + a < 15 && j - a >= 0;) { if(board[i+a][j-a] == d) {b++; a++; continue;} else break; } qiju[k][i][j][q][0] = b; b = 0; if(board[i+a][j-a] == ' ' && i + a < 15 && j - a >= 0) {qiju[k][i][j][q][1] = 1; a = 1;} else {qiju[k][i][j][q][1] = 0; a = 1;} } } } } /******************根据评分规则对每一个空格评分***************/ for(k = 0; k < 2; k ++) for(i = 0; i < 15; i ++) for(j = 0; j < 15; j ++) { if(k == 0) //为白棋评分 { for(q = 0; q < 4; q ++) { //活四 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 4 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 7000; //活三 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 3 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 301; //活二 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 2 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 43; //活一 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 1 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 11; //死四 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 4 && ( (qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0) ) ) b += 7000; //死三 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 3 && ( (qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0 && qiju[k][i][j][q+4][1] == 1) ) ) b += 63; //死二 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 2 && ( (qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0 && qiju[k][i][j][q+4][1] == 1) ) ) b += 6; //死一 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 1 && ( (qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0 && qiju[k][i][j][q+4][1] == 1) ) ) b += 1; } if(b == 126 || b == 189 || b == 252) b = 1500; if(b == 106) b = 1000; a1[i][j] = b; b = 0; } if(k == 1) //为黑棋评分 { for(q =0 ; q < 4; q ++) { //活四 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 4 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 30000; //活三 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 3 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 1500; //活二 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 2 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 51; //活一 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 1 && qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 1 ) b += 16; //死四 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 4 && ( (qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0) ) ) b += 30000; //死三 if( (qiju[k][i][j][q][0] + qiju[k][i][j][q+4][0]) == 3 && ( (qiju[k][i][j][q][1] == 1 && qiju[k][i][j][q+4][1] == 0) || (qiju[k][i][j][q][1] == 0 && qiju[k][i][j][q+4][1] == 1) ) ) b += 71; //死二 if( (qiju[k]
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服