文章目录

  • 一,游戏的基本框架
  • 二 、主函数的设计
  • 三、重要功能设计
    • 3.1 游戏界面的设计
    • 3.2棋盘的初始化
    • 3.3棋盘的设计
    • 3.4 玩家下棋
    • 3.5 电脑下棋
    • 3.6 胜负判断
      • 3.6.1 行的判断
      • 3.6.2 列的判断
      • 3.6.3 对角的判断
      • 3.6.4 判断平局
  • 四.game.h文件
  • 五. 完整代码

一,游戏的基本框架

游戏中有人机,双人两种模式。五子棋作为一个平面游戏,很明显用二维数组来写最合适不过。为了让代码看起来更有条理,我们用三个.c文件,分别是:text.c 用来测试我们的游戏;game.c 游戏功能的实现;is_win.c 判断输赢的版块。另外,还有一个game.h 文件来放我们的函数声明和头文件。


二 、主函数的设计

主函数的主要逻辑我们用switch,case语句来实现,为了能够在选择错误后重新选择,我们在switch 语句外层又嵌套了do while语句来实现循环,且循环终止条件就是游戏的退出的条件,代码如下:

int main()
{srand((unsigned int)time(NULL));int input;do{menu();printf("请选择>");scanf("%d", &input);switch (input){case 1:game1();break;case 2:game2();break;case 0:printf("退出\n");break;default:printf("请重新输入\n");break;}} while (input);return 0;
}

其中,game1()表示人机模式,game2()表示双人模式。

三、重要功能设计

3.1 游戏界面的设计

代码如下:

void menu()
{printf("*************************\n");printf("*****1.人机   2.双人*****\n");printf("******** 0.退出  ********\n");printf("*************************\n");}

3.2棋盘的初始化

上面我们提到“五子棋作为一个平面游戏,很明显用二维数组来写最合适不过”因此,我们定义一个行为ROW,列为COL的二维数组,并将其初始化为’ ',代码如下:

void Init_board(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){board[i][j] = ' ';}}
}

代码运行结果如图:

3.3棋盘的设计

如图,这是我们想要的棋盘设计结果

我们先打印“ %c ”,再打印“ | ”,利用for循环完成一行的打印,这里我们要注意的是:当打印完每行最后一个“ %c”时,是不需要再次打印“ | ”的,因此在这里我们加一个if语句进行判断,当j<col-1时才进行“ | ”的打印。
代码如下:

for (int j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}

当每打印完上述的一行后,我们进行换行后,打印“—|”,再次利用for循环进行一行的打印,在这里也要注意当进行一行的最后一次打印时我们只需要打印“—”,因此在这里我们需要加一个if,else 的判断语句,代码如下:

printf("\n");for (int i = 0; i < col; i++){if (i < col - 1){printf("---|");}else{printf("---");}}

最后我们再用一个for循环进行多行的打印,完整代码如下:

void print_board(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");for (int i = 0; i < col; i++){if (i < col - 1){printf("---|");}else{printf("---");}}printf("\n");}
}

3.4 玩家下棋

玩家输入坐标,在这里要注意的是玩家输入的坐标减一才是我们二维数组的下标。

scanf("%d%d", &x, &y);i = x - 1;j = y - 1;

当输入坐标后,我们要进行坐标的合理性判断:1.所输入坐标是否超出棋盘范围;2.所输入坐标是否已被占用。如果所输入坐标合理,则将坐标位置赋予一定的字符(本游戏中,在人机对战中,玩家所下为**‘,在双人对战中,玩家一所下为,玩家二为‘#’**);若坐标不合理,则提示后重新输入。

int player_board(char board[ROW][COL], int row, int col)
{printf("玩家下:\n");int i = 0;int j = 0;int x = 0;int y = 0;while (1){scanf("%d%d", &x, &y);i = x - 1;j = y - 1;if (x >= 1 && y >= 1 && x <= row && y <= col){if (board[i][j] != ' '){printf("此坐标已经被占用,请重新下:\n");}else{board[i][j] = '*';int ret = is_win(board, ROW, COL, &i, &j, '*');return ret;}}else{printf("非法坐标,请重新下:\n");}}
}

运行结果:

3.5 电脑下棋

电脑下棋我们采用的是通过随机数函数生成合理坐标,然后进行下棋(电脑所下为**‘#’**)。这里要注意的就是随机函数srand(),必须与srand()函数,时间戳搭配使用,且srand()函数只能调用一次,我们在主函数中进行调用。

int main()
{srand((unsigned int)time(NULL))//srand()函数的调用;//由于srand函数的参数为无符号数,因此要将时间戳(time函数)的返回值类型强转化为无符号数。
int computer_board(char board[ROW][COL], int row, int col)
{printf("电脑下:\n");while (1){int ret1 = rand() % row;int ret2 = rand() % col;if (board[ret1][ret2] == ' '){board[ret1][ret2] = '#';int ret = is_win(board, ROW, COL, &ret1, &ret2, '#');return ret;}}
}

运行结果:

3.6 胜负判断

3.6.1 行的判断

我们通过所下的坐标来找到当前行的最左端,然后对这一行进行遍历,如果发现了有五个连续且一样的字符,则获胜。代码如下:

int Col_win(char board[ROW][COL], int row, int col, int* ret1, char ret)
{int count = 0;for (int i = 0; i < col; i++){if (board[*ret1][i] == ret){count++;}if (count == renju){break;}if (i + 1 <= col && board[*ret1][i + 1] != ret){count = 0;}}if (count == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}return 3;
}

3.6.2 列的判断

与上述行的判断一样,我们通过所下的坐标来找到当前列的最上端,然后对这一行进行遍历,如果发现了有五个连续且一样的字符,则获胜。代码如下:

int Row_win(char board[ROW][COL], int row, int col, int* ret2, char ret)
{int count = 0;for (int i = 0; i < row; i++){if (board[i][*ret2] == ret){count++;}if (count == renju){break;}if (i + 1 <= row && board[i + 1][*ret2] != ret){count = 0;}}if (count == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}return 3;
}

3.6.3 对角的判断

通过所下的坐标来找到当前对角的端点,对对角进行遍历,若有五个连续且相同的字符,则获胜。
代码如下;

int Dia1_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{//下半角int count1 = 0;for (int i = 0; i < row && i < col; i++){if (board[*ret1 - (*ret2 - i)][i] == ret){count1++;}if (count1 == renju){break;}if (i + 1 < col && board[*ret1 - (*ret2 - i - 1)][i + 1] != ret){count1 = 0;}}if (count1 == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}//上半角int count2 = 0;for (int i = col - 1; i >= 0; i--){if (board[*ret1 + (i - *ret2)][i] == ret){count2++;}if (count2 == renju){break;}if (i - 1 > 0 && board[*ret1 + (i - *ret2)][i - 1] != ret){count2 = 0;}}if (count2 == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}return 3;}
int Dia2_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{//上半角int count1 = 0;for (int i = 0; i < row && i < col; i++){if (board[*ret1 + *ret2 - i][i] == ret){count1++;}if (count1 == renju){break;}if (i + 1 < col && board[*ret1 + *ret2 - i - 1][i + 1] != ret){count1 = 0;}}if (count1 == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}//下半角int count2 = 0;for (int i = col - 1; i >= 0; i--){if (*ret1 - (i - *ret2) >= 0 && board[*ret1 - (i - *ret2)][i] == ret){count2++;}if (count2 == renju){break;}if (i - 1 > 0 && board[*ret1 - (i - *ret2) + 1][i - 1] != ret){count2 = 0;}}if (count2 == renju){if (ret == '#'){return 1;}if (ret == '*'){return 2;}}return 3;}

3.6.4 判断平局

我们将整个二维数组遍历一遍,在没有获胜的前提下,若没有发现**‘ ’,则证明棋盘已下满——平局;若发现了‘ ’**,则继续游戏。代码如下:

int is_full(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 4;
}

四.game.h文件

此文件里主要是一些函数声明,头文件和宏定义。

#define ROW 7//定义行
#define COL 7//定义列
#define renju 5//定义几子琪
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Init_board(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);
int player_board(char board[ROW][COL], int row, int col);
int player_board1(char board[ROW][COL], int row, int col);
int player_board2(char board[ROW][COL], int row, int col);
int computer_board(char board[ROW][COL], int row, int col);
int is_full(char board[ROW][COL], int row, int col);
int is_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret);
int is_win2(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret);

五. 完整代码

//text.c#include"game.h"
void game1()
{int flag = 0;char board[ROW][COL] = { 0 };Init_board(board, ROW, COL);print_board(board, ROW, COL);while (1){int ret1 = player_board(board, ROW, COL);if (ret1 == 1 || ret1 == 0){print_board(board, ROW, COL);break;}print_board(board, ROW, COL);int ret2 = computer_board(board, ROW, COL);if (ret2 == 1 || ret1 == 0){print_board(board, ROW, COL);break;}print_board(board, ROW, COL);}
}
//双人
void game2()
{int flag = 0;char board[ROW][COL] = { 0 };Init_board(board, ROW, COL);print_board(board, ROW, COL);while (1){int ret1 = player_board1(board, ROW, COL);if (ret1 == 1 || ret1 == 0){print_board(board, ROW, COL);break;}print_board(board, ROW, COL);int ret2 = player_board2(board, ROW, COL);if (ret2 == 1 || ret1 == 0){print_board(board, ROW, COL);break;}print_board(board, ROW, COL);}
}
void menu()
{printf("*************************\n");printf("*****1.人机   2.双人*****\n");printf("******** 0.退出  ********\n");printf("*************************\n");}
int main()
{srand((unsigned int)time(NULL));int input;do{menu();printf("请选择>");scanf("%d", &input);switch (input){case 1:game1();break;case 2:game2();break;case 0:printf("退出\n");break;default:printf("请重新输入\n");break;}} while (input);return 0;
}
//game.h#include"game.h"
void Init_board(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){board[i][j] = ' ';}}
}
void print_board(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");for (int i = 0; i < col; i++){if (i < col - 1){printf("---|");}else{printf("---");}}printf("\n");}
}
int player_board(char board[ROW][COL], int row, int col)
{printf("玩家下:\n");int i = 0;int j = 0;int x = 0;int y = 0;while (1){scanf("%d%d", &x, &y);i = x - 1;j = y - 1;if (x >= 1 && y >= 1 && x <= row && y <= col){if (board[i][j] != ' '){printf("此坐标已经被占用,请重新下:\n");}else{board[i][j] = '*';int ret = is_win(board, ROW, COL, &i, &j, '*');return ret;//break;}}else{printf("非法坐标,请重新下:\n");}}
}int computer_board(char board[ROW][COL], int row, int col)
{printf("电脑下:\n");while (1){int ret1 = rand() % row;int ret2 = rand() % col;if (board[ret1][ret2] == ' '){board[ret1][ret2] = '#';int ret = is_win(board, ROW, COL, &ret1, &ret2, '#');return ret;//break;}}
}
//双人
int player_board1(char board[ROW][COL], int row, int col)
{printf("玩家下A:\n");int i = 0;int j = 0;int x = 0;int y = 0;while (1){scanf("%d%d", &x, &y);i = x - 1;j = y - 1;if (x >= 1 && y >= 1 && x <= row && y <= col){if (board[i][j] != ' '){printf("此坐标已经被占用,请重新下:\n");}else{board[i][j] = '*';int ret = is_win2(board, ROW, COL, &i, &j, '*');return ret;//break;}}else{printf("非法坐标,请重新下:\n");}}
}
int player_board2(char board[ROW][COL], int row, int col)
{printf("玩家下B:\n");int i = 0;int j = 0;int x = 0;int y = 0;while (1){scanf("%d%d", &x, &y);i = x - 1;j = y - 1;if (x >= 1 && y >= 1 && x <= row && y <= col){if (board[i][j] != ' '){printf("此坐标已经被占用,请重新下:\n");}else{board[i][j] = '#';int ret = is_win2(board, ROW, COL, &i, &j, '#');return ret;//break;}}else{printf("非法坐标,请重新下:\n");}}
}
//is_win.c#include"game.h"
//判断行
int Col_win(char board[ROW][COL], int row, int col, int* ret1, char ret)
{int count = 0;for (int i = 0; i < col; i++){if (board[*ret1][i] == ret){count++;}if (count == renju){break;}if (i + 1 <= col && board[*ret1][i + 1] != ret){count = 0;}}if (count == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}return 3;
}
//判断列
int Row_win(char board[ROW][COL], int row, int col, int* ret2, char ret)
{int count = 0;for (int i = 0; i < row; i++){if (board[i][*ret2] == ret){count++;}if (count == renju){break;}if (i + 1 <= row && board[i + 1][*ret2] != ret){count = 0;}}if (count == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}return 3;
}
//左
int Dia1_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{//下半角int count1 = 0;for (int i = 0; i < row && i < col; i++){if (board[*ret1 - (*ret2 - i)][i] == ret){count1++;}if (count1 == renju){break;}if (i + 1 < col && board[*ret1 - (*ret2 - i - 1)][i + 1] != ret){count1 = 0;}}if (count1 == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}//上半角int count2 = 0;for (int i = col - 1; i >= 0; i--){if (board[*ret1 + (i - *ret2)][i] == ret){count2++;}if (count2 == renju){break;}if (i - 1 > 0 && board[*ret1 + (i - *ret2)][i - 1] != ret){count2 = 0;}}if (count2 == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}return 3;}
int Dia2_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{//上半角int count1 = 0;for (int i = 0; i < row && i < col; i++){if (board[*ret1 + *ret2 - i][i] == ret){count1++;}if (count1 == renju){break;}if (i + 1 < col && board[*ret1 + *ret2 - i - 1][i + 1] != ret){count1 = 0;}}if (count1 == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}//下半角int count2 = 0;for (int i = col - 1; i >= 0; i--){if (*ret1 - (i - *ret2) >= 0 && board[*ret1 - (i - *ret2)][i] == ret){count2++;}if (count2 == renju){break;}if (i - 1 > 0 && board[*ret1 - (i - *ret2) + 1][i - 1] != ret){count2 = 0;}}if (count2 == renju){if (ret == '#'){//printf("电脑赢了");return 1;}if (ret == '*'){//printf("你赢了");return 2;}}return 3;}
int is_full(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 4;
}
int is_win(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{int a = Col_win(board, row, col, ret1, ret);int b = Row_win(board, row, col, ret2, ret);int c = Dia1_win(board, row, col, ret1, ret2, ret);int d = Dia2_win(board, row, col, ret1, ret2, ret);int e = is_full(board, row, col);if (e == 0){if (a == 1 || b == 1 || c == 1 || d == 1){printf("电脑赢了\n");return 1;}else if (a == 2 || b == 2 || c == 2 || d == 2){printf("你赢了\n");return 1;}else{return 2;}}else{printf("平局\n");return 0;}
}
//双人
int is_win2(char board[ROW][COL], int row, int col, int* ret1, int* ret2, char ret)
{int a = Col_win(board, row, col, ret1, ret);int b = Row_win(board, row, col, ret2, ret);int c = Dia1_win(board, row, col, ret1, ret2, ret);int d = Dia2_win(board, row, col, ret1, ret2, ret);int e = is_full(board, row, col);if (e == 0){if (a == 1 || b == 1 || c == 1 || d == 1){printf("B赢了\n");return 1;}else if (a == 2 || b == 2 || c == 2 || d == 2){printf("A赢了\n");return 1;}else{return 2;}}else{printf("平局\n");return 0;}
}

C语言实现五子棋小游戏(内附源码)相关推荐

  1. C语言小游戏大全,C语言贪吃蛇小游戏(附源码)

    一.C语言小游戏大全,C语言贪吃蛇小游戏(附源码) 贪吃蛇小游戏源码和更多C语言课设项目小游戏源码免 费 下 载 链 接 如下: c语言项目课设小游戏源码资料压缩包.zip-C文档类资源-CSDN下载 ...

  2. 【C语言】第一个C语言项目——“猜数字”游戏(内附源码)

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello米娜桑,这里是君兮_,今天又抽空为大家更新我们的主线0基础C语言啦!鉴于最近讲解了非常多的选择语句与循环语句,咱们今天就来讲讲 ...

  3. Java实现五子棋小游戏(附源码)

    今天给大家分享一个用java写的小游戏--<五子棋> (完整代码可在[资源下载]目录查看) . 推荐学习专栏: Java基础学习专栏:[Java]基础篇 Java进阶学习专栏:[Java] ...

  4. 分享一个C语言矿井逃生迷宫小游戏【附源码】

    用C语言写的一个迷宫小游戏,游戏玩法是通过鼠标控制帽子上的灯走出迷宫 // 定义常量 #define PI 3.141592653589 // 圆周率 #define UNIT_GROUND 0 // ...

  5. C语言做的接鸡蛋小游戏(附源码注释)【原创】

    //以下是接鸡蛋小游戏源码 .建议在VS中运行调试! /* 头文件 */ # include <windows.h> # include <stdlib.h> # includ ...

  6. 【休闲游戏 实战1】推箱子PC端小游戏(附源码)

    游戏链接 :点击打开链接 效果图: 第100关有些难度,用了449步才过关(我用的是可跳关版的,直接玩的最后一关) 源码解读 源码一共3个文件:index.html(游戏界面加载,核心功能),js/m ...

  7. 齿轮画板Python小游戏(附源码)

    齿轮画板Python小游戏 相信很多人都玩过类似下面这样的小玩具,我叫它齿轮画板,很多人叫它万花尺.前段时间我的孩子在玩这种游戏时由于控制不好,总是很难画好完整的图案.于是我萌发了用编程来实现这个游戏 ...

  8. turbo c实现雷电小游戏demo(附源码)

    计算机图形学的课后大作业要求turbo c做一个小动画, 故花了2天左右的时间做了一个雷电的小游戏, 也参考了一些例子, 代码比较简单, 只有400多行, 结构比较简单, 代码已经传到csdn,附链接 ...

  9. 【python】pygame实现植物大战僵尸小游戏(附源码 有注释)

    全部源码和数据集请点赞关注收藏后评论区留言或私信博主要 完全免费~~ 动态演示视频已经上传到我的个人主页 有兴趣的伙伴可自行前往 观看 相信许多小伙伴们都玩过植物大战僵尸这款游戏,可以说是很多人的童年 ...

  10. 带你开发个转盘抽奖小游戏【附源码】

    程序IT圈 只提供有用的编程技术,关注即可习得新技能 1效果图 小时候有没有玩过老虎机抽奖游戏?今天一起来用代码编程实现个简单抽奖的小游戏!首先,先带大家看看实现的效果图是怎么样的: 2分析如何实现 ...

最新文章

  1. 谈一谈浏览器解析CSS选择器的过程【前端每日一题-6】
  2. angular1x初始与架构演进(一)
  3. C++中mutable、volatile关键字
  4. 孪生再世代表数字几_《孪生双鱼座》
  5. 452. 用最少数量的箭引爆气球(贪心算法+思路+详解)07
  6. msp430中如何连续对位进行取反_四元数数控:如何保养视觉对位平台?
  7. 知方可补不足~用xsl来修饰xml
  8. NOIP2017(不算是题解)
  9. Ruby on Rails 实践
  10. javascript DOM对象转jquery对象
  11. matlab高斯窗函数,Matlab的窗函数,矩形窗,三角窗,汉明窗,汉宁窗,布莱克曼窗
  12. 指针的运用——快慢指针
  13. Mac系统的环境变量配置
  14. 基于深度信念网络的表示学习用于lncrna -疾病关联预测
  15. Possibly consider using a shorter maxLifetime value.解决方法
  16. python计算机视觉--基于(BOW)的图像检索与识别
  17. 一位清华计算机专业的学生怎么看LINUX与WINDOWS
  18. 第四章-循环程序设计代码实例(C++蓝豹子)
  19. 《R语言与数据挖掘》⑦聚类分析建模
  20. 「津津乐道播客」#322 津津有味:你吃的不是糖油混合物,是无处安放的情绪...

热门文章

  1. 在线问答系统--静态页面布置
  2. 动态生成的html代码
  3. 模糊数学Python(二)模糊聚类分析
  4. 基于模糊等价关系的模糊聚类分析
  5. SAP顾问生涯闲记:做过的最好玩的Global项目是什么样子
  6. 私域运营中,企业私域流量挖掘用户价值的三种手段
  7. xbox虚拟服务器,《微软模拟飞行》体积减半,主机版也快到来了
  8. mpg123源码详解
  9. 计算机保存照片怎么显示内存不足怎么办,电脑另存为图片时显示内存不足怎么处理...
  10. 【考研】915自控攻略