C语言实现五子棋(完整灵活升级版)(gobang by c

您所在的位置:网站首页 五子棋算法代码怎么写 C语言实现五子棋(完整灵活升级版)(gobang by c

C语言实现五子棋(完整灵活升级版)(gobang by c

2024-07-11 06:17| 来源: 网络整理| 查看: 265

 

看了 C 视频教程中的三子棋实现,修改代码升级为五子棋,或者说 n子棋(即可以自由设置成功的时候棋子的连接数),代码中也写了详细的注释,分享给大家~ 

运行环境:Visual Studio 2019

该代码总共包含三个文件,一个是 main.c 主文件,还有2个分别是 game.c 和 game.h 实现游戏功能的文件。

 

1. main.c 文件

main.c 文件定义了代码的整个架构,主要包含2个部分

1. 显示游戏菜单:玩家选择是否开始游戏或者结束游戏

2. 定义了 game() 这个函数来实现游戏的整个基本架构,即 初始化 —— 判断棋盘是否满 —— 玩家下棋 —— 判断玩家是否胜利 —— 电脑下棋 —— 判断电脑是否胜利 。其中 ret 存放游戏最终的结果,'o' 表示玩家赢,'x' 表示电脑赢,'Q' 表示平局

1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include "game.h" 3 4 // 测试五子棋游戏 5 void menu() { 6 printf("***************************************\n"); 7 printf("******* 1. play 0. exit ********\n"); 8 printf("***************************************\n"); 9 } 10 11 // 游戏的整个算法实现 12 void game() { 13 // 用于存储判断输赢最终 14 char ret = 0; 15 // 用于判断棋盘是否满的值 16 int fullValue = 0; 17 if (ROW * COL % 2 == 0) { 18 fullValue = ROW * COL; 19 } 20 else { 21 fullValue = ROW * COL - 1; 22 } 23 //printf("fullValue = %d \n", fullValue); 24 // 计算所走步数 25 int count = 0; 26 // 数组-存放走出的棋盘信息 27 char board[ROW][COL] = { 0 }; 28 // 数组-存放判断电脑和玩家胜利的最终结果 29 // 这个是字符串(字符数组)的初始化,因为后面字符串比较要用到strcmp这个函数,所以这里需要定义的是字符数组 30 char PlayerWin[TARGET+1] = ""; 31 char ComputerWin[TARGET+1] = ""; 32 // 初始化棋盘,全部都是空格 33 InitBoard(board, ROW, COL); 34 // 初始化用于判断是玩家赢还是电脑有赢的两个变量 35 InitWin(PlayerWin, ComputerWin, TARGET); 36 // 打印棋盘 37 DisplayBoard(board, ROW, COL, count); 38 // 开始下棋 39 while (1) 40 { 41 // 判断棋盘是否满了,满了就平局 42 if (count == fullValue) { 43 break; 44 ret = "Q"; 45 } 46 47 // 玩家下棋 48 PlayerMove(board, ROW, COL); 49 count++; 50 DisplayBoard(board, ROW, COL, count); 51 // 判断玩家是否赢 52 ret = IsWin(board, PlayerWin, ComputerWin, ROW, COL, TARGET); 53 if (ret != 'C') { 54 break; 55 } 56 57 // 电脑下棋 58 ComputerMove(board, ROW, COL); 59 count++; 60 DisplayBoard(board, ROW, COL, count); 61 // 判断电脑是否赢 62 ret = IsWin(board, PlayerWin, ComputerWin, ROW, COL, TARGET); 63 if (ret != 'C') { 64 break; 65 } 66 } 67 // 跳出循环,说明比较结果出来了,那么就对比赛结果进行判断 68 if (ret == 'o') { 69 printf("!!!!!! 游戏结束 —— 玩家赢 \n"); 70 } 71 else if (ret == 'x') { 72 printf("!!!!!! 游戏结束 —— 电脑赢 \n"); 73 } 74 else { 75 printf("!!!!!! 游戏结束 —— 平局\n"); 76 } 77 } 78 79 void test() { 80 int input = 0; 81 // 放在这里是因为srand只能执行一次,而test也是只执行一次 82 srand((unsigned int)time(NULL)); 83 // 用时间戳来设置随机种子,把time返回的time_t类型强制转换成无符号整型 84 if (ROW >= TARGET && COL >= TARGET) { 85 // 进入游戏环节 86 do 87 { 88 // 显示游戏菜单 89 menu(); 90 printf("请选择:> "); 91 scanf("%d", &input); 92 switch (input) 93 { 94 case 1: 95 game(); 96 break; 97 case 0: 98 printf("退出游戏\n"); 99 break; 100 default: 101 printf("选择错误_,请重新选择!\n"); 102 break; 103 } 104 } while (input); 105 } 106 else { 107 printf("棋盘的行和列值必须大于等于目标数 \n"); 108 } 109 } 110 111 int main() { 112 test(); 113 return 0; 114 }

 

2. game.h 文件

game.h 文件中包含了一些重要参数的设置,以及 game.c 中定义函数的声明。

1 #pragma once 2 #define ROW 7 // 棋盘的行数 3 #define COL 7 // 棋盘的列数 4 #define TARGET 5 // 几个相连算是赢 5 6 #include 7 #include // rand 函数 8 #include // time 函数 9 #include 10 11 // --------- 声明 ---------- 12 13 // 棋盘初始化 14 void InitBoard(char board[ROW][COL], int row, int col); 15 // 用于判断是否赢的数组初始化 16 void InitWin(char PlayerWin[], char ComputerWin[], int target); 17 // 显示棋盘 18 void DisplayBoard(char board[ROW][COL], int row, int col, int count); 19 // 玩家走 20 void PlayerMove(char board[ROW][COL], int row, int col); 21 // 电脑走 22 void ComputerMove(char board[ROW][COL], int row, int col); 23 // 判断是否游戏结束 24 // 返回四种游戏的状态: 玩家赢 - 'o' 电脑赢 - 'x' 平局 - 'Q' 继续 - 'C' 25 char IsWin(char board[ROW][COL], char PlayerWin[], char ComputerWin[], int row, int col, int target);

 

3. game.c 文件

game.c 文件中存放了实现五子棋游戏的主要函数的定义,其中判断游戏是否有一方获胜的 IsWin 函数相对不好理解,大家要注意以下几点:

1. 横向、竖向和2个对角线方向的代码中有许多重复的部分,其中要修改的就是 i, j 变量循环时的取值范围以及看清楚 i, j 到底是表示行还是表示列,除了竖向以外,i 都是表示行,j 都是表示列,竖向则相反。

2. i, j 的范围到底是怎么来的,为了更清楚了解 i, j 的取值范围,可以利用高中解数学题目时常用到的 “取特殊值法” 来求解,就是举个例子以此来然后判断 i, j 的取值范围,如下图所示,取了  ROW=7, COL=7, TARGET=5 来获取相应的取值范围。

 

1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include "game.h" 3 4 // 棋盘初始化,初始化所有棋盘值为空 5 void InitBoard(char board[ROW][COL], int row, int col) { 6 int i = 0; 7 int j = 0; 8 for (i = 0;i < row;i++) { 9 for (j = 0;j < col;j++) { 10 board[i][j] = ' '; 11 } 12 } 13 } 14 15 // 初始化用于比对判断是玩家赢还是电脑赢的数组PlayerWin和ComputerWin 16 void InitWin(char PlayerWin[], char ComputerWin[], int target) { 17 int i = 0; 18 for (i = 0; i < target;i++) { 19 char str_temp1[2] = { 'o', '\0'}; 20 char str_temp2[2] = { 'x', '\0'}; 21 strcat(PlayerWin, str_temp1); 22 strcat(ComputerWin, str_temp2); 23 } 24 // 字符型数组求长度的方法,求长度要用strlen,不能用sizeof(arr)/sizeof(arr[0]) 25 //printf("InitWin -len(PlayerWin)=%d \n", strlen(PlayerWin)); 26 //printf("InitWin - len(ComputerWin)=%d \n", strlen(ComputerWin)); 27 //printf("InitWin - %s \n", PlayerWin); 28 //printf("InitWin - %s \n", ComputerWin); 29 } 30 31 // 显示棋盘 32 void DisplayBoard(char board[ROW][COL], int row, int col, int count) { 33 int i = 0; 34 printf(" \n -- 第 %d 步 \n", count); 35 printf("\n"); 36 // 显示列标签 37 printf(" "); 38 for (i = 0;i < col;i++) { 39 if (i + 1 > 9) { 40 printf(" %d ", i+1); 41 } 42 else { 43 printf(" %d ", i+1); 44 } 45 } 46 printf("\n"); 47 for (i = 0;i < row;i++) { 48 // 显示行标签 49 if (i + 1 > 9) { 50 printf(" %d ", i+1); 51 } 52 else { 53 printf(" %d ", i+1); 54 } 55 int j = 0; 56 for (j = 0;j < col;j++) { 57 // 1. 打印一行数据 58 printf(" %c ", board[i][j]); 59 if (j < col - 1) 60 printf("|"); 61 } 62 printf("\n"); 63 printf(" "); 64 // 2. 打印分割行 65 if (i < row - 1) { 66 for (j = 0;j < col;j++) { 67 printf("---"); 68 if (j < col - 1) 69 printf("|"); 70 } 71 printf("\n"); 72 } 73 } 74 printf("\n"); 75 } 76 77 // 玩家走 o(玩家根据输入的坐标位置填写o) 78 void PlayerMove(char board[ROW][COL], int row, int col) { 79 int x = 0; 80 int y = 0; 81 printf("玩家走:> \n"); 82 while (1) { 83 printf("请输入要下的坐标:> "); 84 scanf("%d%d", &x, &y); 85 // 判断x,y坐标的合法性 86 if (x >= 1 && x = 1 && y


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3