如何判断输赢
同样我们还是要在我们的game.h里面声明一下
char is_win(char board[ROW][COL], int row, int col);//判断输赢 //这里我们之所以定义返回类型是字符型 是让我们在判断输赢的根据不同的情况返回不同的字符 //然后进一步判断是哪一方获得了胜利
大家玩过三子棋的都知道 我们的三子棋判断输赢需要判断 行 、列 和 对角线
在这里我们这样判断不同的情况
//*-玩家赢 //#-电脑 要注意什么情况返回哪个字符 这里我用的是这样的方法 //Q-平局 请大家往下看! //C-游戏继续
判断行:
int i, j; for (i = 0; i < row; i++) { int flag = 0; for (j = 0; j < col - 1; j++)//因为每次判断都和同一行的下一个 所以比较的时候 次数要比 { //列数小 1 if (board[i][j] == board[i][j + 1]&&board[i][j]!=' ') { //应为每次下棋不管 是电脑还是玩家 我们都要检查是否有 flag++; //人胜利 所以检查的时候有些位置还是空的 这些肯定三个 } //相等的话是不可取的 所以空的地方即使相等不能算进去 } if (flag == ROW - 1) //这里我们定义的flag如果等于了比较的次数 就说明两次的比较 { //都是相等的 这一行的三个就是相等的 if (board[i][j] == '*') return '*'; //循环结束后坐标是放在这一行中间的位置 所以我们直接看 else //这个的字符是什么 就可以判断出是谁赢了 return '#'; }
判断列:
其实行和列里面比较的思路是一样的 只不过
比较行 是行变化 拿同行中每一列进行比较
比较列 是列变化 拿同列中每一行进行比较
for (j = 0; j < col; j++) { int flag = 0; for (i = 0; i < row - 1; i++) //这些地方的道理是和比较行的道理是相同的 { if (board[i][j]==board[i+1][j]&&board[i][j]!=' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') //这里最后循环后的到的就是一列中间那个位置 return '*'; else return '#'; } }
判断对角线:
大家都知道一个四边形有两条对角线 而两条对角线的起点和终点都是不同的 所以内 他们的循环过程肯定是不同的首先我们看第一条:
第一条:
int flag = 0; //因为之前的flag是定义在循环里面 所以在循环外面是不能够用的 所以要重 for (i = 0, j = 0; i < row - 1 && j < col - 1; i++, j++)//新定义 { if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ') { flag++; //因为对角线的坐标 无论是横坐标还是竖坐标都是变换的 所以我把他们的循环 } //设置在了一起 另一条对角线也是一样的道理 只是起始点和终点不同罢了 } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; }
第二条:
flag = 0; for (i = 0, j = col - 1; i < row - 1 && j>0; i++, j--) { if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ') { flag++; } } //无论是第一条还是最后一条我们都要注意 终点的设置不是对角线 if (flag == ROW - 1) //的最后一个 而是最后一个的前一个 我们每次都是拿一个坐标去和 { //它的下一个坐标进行比较 如果我们拿最后一个的话 访问就会越界 if (board[i][j] == '*') //也就出错了 return '*'; else return '#'; }
到这里棋盘里的比较就没有了
之前的比较过程中 我们一直返回的都是某一方获得胜利的 而 游戏继续 其实很好写出来 就是需要注意 它放置的位置
大家都知道 如果一个程序 return 了 那么他后面的所有程序就不会在运行了
所以我们的游戏继续的程序一定要放在最后才行 先给大家看一下我写的游戏继续的代码
大家就知道是为什么了
for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') return 'C'; } }
我是 遍历(大致意思是很多组数据我一个一个去试 最后找到正确的一个)整个二维数组来找是否有空字符 如果有 那么就返回字符C 后面的程序就不会执行了
所以!我们游戏继续的程序的位置很重要 如果放在前面任意一个位置的话我们有些地方还没比较内 它找到空字符就返回了 这样肯定是不行的 所以 我把这个放在了最后!
大家都知道如果三子棋是平局的话那么整个棋盘肯定是被填满的 是不会有空字符的所以大家 看这个判断输赢函数的最后:
for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ')//游戏继续程序 返回字符C return 'C'; } } return 'Q'; //所有return都没执行那么游戏为平局!
我在最后的位置加上 return 'Q' 这样的话如果前面 游戏继续没有执行 return 的话就说明这个数组里面已经没有空字符了数组里面已经填满我们下的棋子了 毕竟我们遍历的是整个数组
这样我们判断输赢的函数就写完了 给大家看看整体是什么样子吧
//判断输赢 char is_win(char board[ROW][COL], int row, int col) { int i, j; for (i = 0; i < row; i++) //判断每一行 { int flag = 0; for (j = 0; j < col - 1; j++) { if (board[i][j] == board[i][j + 1]&&board[i][j]!=' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } } for (j = 0; j < col; j++) //判断每一列 { int flag = 0; for (i = 0; i < row - 1; i++) { if (board[i][j]==board[i+1][j]&&board[i][j]!=' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } } int flag = 0; for (i = 0, j = 0; i < row - 1 && j < col - 1; i++, j++) //判断第一条对角线 { if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } flag = 0; for (i = 0, j = col - 1; i < row - 1 && j>0; i++, j--)//判断第二条对角线 { if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } for (i = 0; i < row; i++) //游戏是否要继续 { for (j = 0; j < col; j++) { if (board[i][j] == ' ') return 'C'; } } return 'Q'; //游戏最终为平局 }
到这里我们所有的三子棋的所需要的函数都写完了 我们来总结一下:
- 打印并制作棋盘
- 玩家下棋
- 电脑下棋
- 判断输赢
因为我们每次使用我们都声明了他们也看看 我们现在的game.h是什么样的吧:
3.我们自己定义的头文件game.h
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 3 #define COL 3 void display_borad(char board[ROW][COL], int row, int col);//打印并制作棋盘 void player_move(char board[ROW][COL], int row, int col);//玩家下棋 void com_move(char board[ROW][COL], int row, int col);//电脑下棋 char is_win(char board[ROW][COL], int row, int col);//判断输赢
我们把所有需要引得头文件 声明得函数 都放在这里面 我们得另外两个程序 就只需要引我们自己的这个头文件 就相当于是把所用需要的东西都引了一遍 这样是不是方便很多 并且有助于我们写代码时保持头脑清晰
最后的最后我们来看之前给大家看过的这个:
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; } //我们设置C是游戏继续只要函数返回的不是 else if (ret == '#') //C那就说明一定有一种结果 { //是C我们就不进行操作让下棋这个循环继续直 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; } } } }
到这里内 我们整个游戏的搭建就算是完工了 Oh Yeah!
后面是我们三子棋代码的全部 对了这个三子棋版本可以设置棋盘大小的哦
设置的同时就不再是三子棋 就变成四子 五子 六子了 嘻嘻嘻!
总览三子棋代码
game.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" menu() { printf("************************\n"); printf("*********1. play********\n"); printf("*********0. exit********\n"); printf("************************\n"); } void work() { printf("----------------\n"); printf("您已经进入游戏!\n"); char board[ROW][COL]; memset(board, ' ', sizeof(board));//初始化棋盘 display_borad(board, ROW, COL);//打印并制作棋盘 //开始下棋 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; } } } } int main() { int input; srand((unsigned int)time(NULL)); do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 0: { printf("您已退出游戏!"); break; } case 1: { work(); break; } default: { printf("输入错误请重新输入!\n"); printf("------------------------\n"); break; } } } while (input); return 0; }
work.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //打印并制作棋盘 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++) { printf(" %c ", board[i][j]); if (j < col - 1)printf("|"); } printf("\n"); if (i < row - 1) { for (j = 0; j < col; j++) { printf("---"); if (j < col - 1)printf("|"); } printf("\n"); } } } //玩家走 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) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("您输入的位置已经被占用 请重新输入!\n"); } } else { printf("您输入的位置无效 请重新输入!\n"); } } } //电脑走 void com_move(char board[ROW][COL], int row, int col) { printf("电脑下:>\n"); while (1) { int x = rand() % row; int y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } //判断输赢 char is_win(char board[ROW][COL], int row, int col) { int i, j; for (i = 0; i < row; i++)//判断每一行 { int flag = 0; for (j = 0; j < col - 1; j++) { if (board[i][j] == board[i][j + 1]&&board[i][j]!=' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } } for (j = 0; j < col; j++) //判断每一列 { int flag = 0; for (i = 0; i < row - 1; i++) { if (board[i][j]==board[i+1][j]&&board[i][j]!=' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } } int flag = 0; for (i = 0, j = 0; i < row - 1 && j < col - 1; i++, j++)//判断第一条对角线 { if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } flag = 0; for (i = 0, j = col - 1; i < row - 1 && j>0; i++, j--)//判断第二条对角线 { if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ') { flag++; } } if (flag == ROW - 1) { if (board[i][j] == '*') return '*'; else return '#'; } for (i = 0; i < row; i++)//游戏是否要继续 { for (j = 0; j < col; j++) { if (board[i][j] == ' ') return 'C'; } } return 'Q';//游戏最终为平局 }
game.h:
#pragma once #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 3 #define COL 3 void display_borad(char board[ROW][COL], int row, int col);//打印并制作棋盘 void player_move(char board[ROW][COL], int row, int col);//玩家下棋 void com_move(char board[ROW][COL], int row, int col);//电脑下棋 char is_win(char board[ROW][COL], int row, int col);//判断输赢
好的 到这里我们这篇三子棋 博客 就写完了 有写得不好的地方还请各位大牛们指正!
新的一年祝大家新年快乐 万事如意 都能进到自己心仪的大厂 哈哈哈哈哈哈哈