1.游戏总体的逻辑 以及 开始操作:game.c
编写一个选择界面:
menu() { printf("************************\n"); printf("*********1. play********\n");//注意我们这里用 1 表示开始玩 而 非零 在vs表示为真 printf("*********0. exit********\n");//0表示为假 这样也方便了我们后续操作的书写 printf("************************\n"); }
因为要玩游戏嘛 这个游戏我们肯定无论如何都要运行一次 所以我们采用do-while循环 这样游戏就肯定会让你判断一次是否开始游戏了! 大家来看:
int main() { int input; srand((unsigned int)time(NULL));//这里要用到随机值这个知识点后面会给大家讲到 do { menu(); //把menu()放在循环里面也是为了当游戏已经判断出输赢 printf("请选择:>"); //当work scanf("%d", &input); switch (input) { case 0: { printf("您已退出游戏!"); break; } case 1: { work(); break; } default: { printf("输入错误请重新输入!\n"); printf("------------------------\n");//这里之所以打出一条线来 是为了美观 大家看 break; //下图 } } } while (input); return 0; }
这里 input 的用法很关键 也很特别 大家看 while 循环 和 switch选择语句所用到的判断条件都是
input 当你选择 0 时 因为break 跳出的是 switch选择语句 出来后进行 while 的判断 0 为假 程序自然就结束了
当你选择的是 1 时 work()工作完返回来 break 跳出 来到 while 的判断 为真 继续循环
再次显示menu() 的界面 给玩家选择是否再玩一局!
怎么样? 这样的设计是不是很巧妙
这样时不是看上去美观些许
到这里游戏开始操作的程序就是这些了 让我们继续!
2.编写游戏中所需要用到的函数:work.c
初始化棋盘
棋盘的初始化我们可以使用memset函数
memset函数:
memset()函数原型是extern void *memset(void *buffer, int c, int count) buffer:为指针或是数组,
c:是赋给buffer的值,
count:是buffer的长度.(摘自 落叶随风)
memset(board, ' ', sizeof(board));//初始化棋盘
这里我们初始化棋盘 是为了后续棋盘的打印 如果不初始化棋盘就会是这样的
因为棋盘的二维数组是一个局部变量 里面的值都是随机的 所以打印出来才会出现这样的现象!
打印并制作棋盘
在制作棋盘前 我们首先得了解 棋盘长什么样子
大家可以这样看看 其中黄色和蓝色各是一种 种类 大家也注意到蓝色最后一排是没有的
其中黄色 由这些成分组成 %c | 每打印一个 空格+%c 就要打印一个 | 但是最后一列没有
蓝色部分 由这些成分组成 --- | 每打印三个 - 就要打印一个 | 同样最后一列没有
在制作棋盘之前我们要在我们定义的 game.h 里声明这个函数:
#define ROW 3 #define COL 3//因为程序中要多次应用到行和列的数字 所以我们把它define void display_borad(char board[ROW][COL], int row, int col);//打印并制作棋盘 //因为只是拿这个函数用于打印并制作棋盘并不需要它返回什么 所以我们定义为 void 类型 //传入我们初始化好的二位数组 行 列
game.c 里面是这样调用函数的
display_borad(board, ROW, COL);//打印并制作棋盘
好的现在已经开始写我们的代码:
void display_borad(char board[ROW][COL], int row, int col) { int i; int j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) //打印黄色的部分 不会打印最后一列的 | 所以当我们的j循环到 { //最后列就让他不打印所以 用 if 语句来判断是否打印 printf(" %c ", board[i][j]); if (j < col - 1)printf("|"); } printf("\n"); //黄色部分结束后要进行换行 if (i < row - 1) //这里的if 语句 是用来判断整个蓝色部分打不打印 而我们最后 { //一行是不打印的所以我们同样也用 if语句 来进行判断 for (j = 0; j < col; j++) { printf("---"); //这里是打印蓝色的部分 而当我们打印到最后也与之前同理 用 if (j < col - 1)printf("|");//用if 语句来进行判断 是否打印 } printf("\n");//同样这里也是需要换行的 } } } //大家可以对照着理解一下 %c | %c | %c ----|----|---- //这里面的-字体好像没有我的vs的大 所以写了4个 哈哈哈哈哈 %c | %c | %c ----|----|---- %c | %c | %c
好的这样我们的棋盘就制作并很好的打印出来了
开始下棋
因为我们下棋是和电脑下棋 而下棋肯定是你走一步 我走一步 所以呢 这肯定是一个循环的过程 而循环结束的标志就是其中一方赢了 然后break出来 并打印结果 这就是我们总体的一个思路 让我们来看看怎么实现它吧
玩家下棋:
当然在开始前我们还是需要在我们定义的 game.h 里面先声明一下这个函数的
1. void player_move(char board[ROW][COL], int row, int col);//玩家下棋 2.
接下来是我们程序的运行:
//玩家走 void player_move(char board[ROW][COL], int row, int col) //我们设置为玩家的棋子是符号 '*' { int x, y; printf("请选择您的棋子位置:>"); //判断棋子有效性 while (1) //这里设置循环的目的是为了当我们输入的坐标无效时 让玩家循环回来重新输入 { scanf("%d %d", &x, &y); if (x >= 1 && x <= ROW && y >= 1 && y <= COL) //ROW=3 COL=3 { if (board[x - 1][y - 1] == ' ') //因为玩家可能并不知知道我们的棋盘(二维数组)的 { //下标是从 0 开始的 所以玩家输入的数据范围可能是 board[x - 1][y - 1] = '*'; //1~3 所以玩家输入进去的数字 是比我们的下标的数据 break; //范围大 1 的 所以我们这里要减 1 } else { printf("您输入的位置已经被占用 请重新输入!\n"); //这里是为了保证我们输入的坐标 } //里面是空的 所以我们用 if 判断 } else { printf("您输入的位置无效 请重新输入!\n"); //判断棋子的有效性 } } }
因为当我们的玩家下完棋后 我们肯定要给他看一看他下的那一步 棋盘现在是什么样子的
同样电脑下完棋我们也要显示棋盘是什么样子
先给大家看看这个是什么样子的吧 后面会仔细的说清楚 嘿嘿
//开始下棋 while (1) { char ret; player_move(board, ROW, COL); display_borad(board, ROW, COL); ret=is_win(board, ROW, COL); if (ret != 'C') //判断输赢 { //*-玩家赢 if (ret == '*') //#-电脑赢 { //Q-平局 printf("恭喜你赢了!\n"); //C-游戏继续 printf("----------------\n"); break; } else if (ret == '#') { printf("很遗憾!电脑赢了\n"); printf("----------------\n"); break; } else { printf("此局为平局!\n"); printf("----------------\n"); break; } } com_move(board, ROW, COL); display_borad(board, ROW, COL); ret=is_win(board, ROW, COL); if (ret != 'C') { if (ret == '*') { printf("恭喜你赢了!\n"); break; } else if (ret == '#') { printf("很遗憾!电脑赢了\n"); break; } else { printf("此局为平局!\n"); printf("----------------\n"); break; } } } }
电脑下棋:
在这里电脑下棋 我们给他设置成随机的数字 所以要用到 srand函数 和 rand函数
这里就给大家讲讲这个随机的数字怎么生成的
rand函数 是用来生成一个随机数 头文件是<stdio.h> 返回类型是整型
返回 0~Rand_Max(32767)中的一个数
srand函数相当于是给rand函数生成一个起始点 就是让rang函数不再是从0开始到Rand_max 如果你给rand函数设置的起始点是固定的那么好几次生成的随机数
srand(1); int x = rand(); for (int i = 0; i < 5; i++)//这里五次输出 都是 41 { //如果说你在使用rand函数之前没有使用srand函数 那么结果和srand(1) printf("%d\n", x); //是一样的 }
所以我们要给srand函数里传入 一个变化的值 这个时候就要用到 time函数
time函数:
time函数这样定义的 这个函数的返回的类型是 time_t (就好比是int char)这个类型是一个无符号整型 但是不同平台这个类型的定义是不同的 我用的是 vs 而在vs里面是一个有符号的长整型
所以这里用的时候记得 给time函数进行强制转换 (如果你用的也是vs的话)
因为srand函数要求的是 我们给它传入的数要是一个无符号的数
其中time_t它返回从1970年1月1日零时零分零秒到目前为止所经过的时间
最后有一点 在我们使用这个函数之前 我们还要引用
srand函数:
这个函数他是这样的 void srand(unsigned seed)
他要求传入一个无符号的数
因为我们要让这个随机数是变化的 而rand函数 srand函数 time函数通常结合在一起使用
最终拿出来就是这样的 srand((unsign int)time(NULL) ) NULL的意思就是表示空的意思
你可以写 0
因为我们的主函数是一定会执行的所以我们就把 srand函数放到主函数里面去
对了 在使用它们之前出了 引头文件<time.h>还有一个<stdlib.h>哦!
好的 说完这个我们就可以开始编写 电脑下棋的部分了
同样我们还是要在我们定义的game.h里面先声明
void com_move(char board[ROW][COL], int row, int col);//电脑下棋
让我们看看work.c该怎么写:
void com_move(char board[ROW][COL], int row, int col) { printf("电脑下:>\n"); while (1) { int x = rand() % row; //这里我们设定的是3×3的棋盘 这里它模3 那么得到的结果就是在0~2之间 int y = rand() % col; //如果定义的是4×4 也是一样的道理 if (board[x][y] == ' ') //电脑也是需要判断选出的坐标是否被占用的 但是呢 不需要提示 { //毕竟我们也不能提示我们的电脑看啊 board[x][y] = '#'; break; } } }
到这里我们的下棋部分就写完了 接下来是我们的判断输赢部分