本篇给大家带来两个玩家对战的五子棋,棋盘大小和玩家所下的棋子可以很容易的更改,读者如有更好的建议,可以在评论区留言

代码模块将分为3个部分,游戏页面逻辑书写写在 test.c 文件中,游戏所需要的声明书写在 game.h 文件中,实现游戏的函数写在 game.c 文件中


文章目录

  • 一、test.c文件
    • 1. 游戏界面的书写
    • 2. 游戏逻辑的书写
  • 二、game.h 文件
  • 三、game.c 文件
    • 1. 设计棋盘
    • 2. 初始化棋盘
    • 3. 打印棋盘
    • 4. 玩家下棋
      • (1)玩家落子
      • (2)判断玩家落子后是否游戏结束
  • 四、源码

一、test.c文件

1. 游戏界面的书写

如果小伙伴不喜欢该游戏界面,可以自行更改菜单 mnue 函数中的内容

#include "game.h";     //需要用到 game.h 中的声明void mnue()
{printf("******************\n");printf("***   1.play   ***\n");printf("***   0.exit   ***\n");printf("******************\n");
}

为了让玩家有更好的游戏体验,游戏玩了一次之后我们可以选择再来一把,或者退出游戏,这里采用 do while 循环

int main()
{int input = 0;do{//菜单mnue();printf("请输入:>");scanf("%d", &input);system("cls");            //将屏幕已经打印的内容清理掉,//需要头文件是 stdlib.h//用户选择switch (input){case 1:            //用户选择 1 开始游戏,进入到 game 函数中printf("欢迎来到五子棋,游戏开始\n");game();break;case 0:         //用户选择 0 退出游戏printf("退出游戏\n");break;default :     //如果选择的不是 1 则需要重新输入printf("输入错误,请重新输入\n");break;}} while (input);  //选择 0 条件不成立会退出循环,已结束游戏//选择 1 或输入了其他数字,判断为真//进入循环,打印菜单,让用户重新选择return 0;
}

2. 游戏逻辑的书写

用户选择 1 之后来到 game 函数

void game()
{char ret = 0;char board[ROW][COL];            //用于存储棋盘落子的信息init_board(board, ROW, COL);    //初始化棋盘落子的信息//用' '表示还没有落子print_board(board, ROW, COL);   //打印棋盘//提醒用户本游戏是如何落子printf("********************\n");printf("本游戏通过坐标来下棋\n");printf("********************\n");//玩家下棋是一个重复的过程//这里将玩家下棋封装成函数,其中第四个参数用来代表不同的玩家//每次落子之后,通过函数的返回值,来判断游戏是否结束while(1){printf("玩家1 请下棋:>");ret = play_board(board, ROW, COL, PIECE_ONE);if (ret != 'C')break;system("cls");print_board(board, ROW, COL);    //下棋之后,打印棋盘printf("玩家2 请下棋:>");ret = play_board(board, ROW, COL, PIECE_TWO);    if (ret != 'C')break;system("cls");print_board(board, ROW, COL);   //下棋之后,打印棋盘}//判断是谁赢了,以及是否平局if (ret == PIECE_ONE){printf("恭喜玩家1,获胜\n");}else if(ret == PIECE_TWO){printf("恭喜玩家2,获胜\n");}else{printf("很遗憾,没有决出胜负\n");}Sleep(5000);   //让输出结果停留 5s 需要的头文件是 windows.hsystem("cls");
}


二、game.h 文件

用来存放函数的声明,需要的头文件,以及棋盘的大小和棋子的字符,在该文件可以更改棋盘大小和棋子的符号

#define _CRT_SECURE_NO_WARNINGS 1    //在VS编译器用 scanf 等函数//需要定义该符号//需要的包含的头文件
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>//需要更改棋盘的大小或棋子的符号,改这里就可以了
#define ROW 12                  //棋盘的行数
#define COL 15                  //棋盘的列数
#define PIECE_ONE '*'         //玩家1 的棋子
#define PIECE_TWO '#'         //玩家2 的棋子//初始化
void init_board(int board[ROW][COL], int row, int col);//打印棋盘
void print_board(char board[ROW][COL], int row, int col);//玩家下棋,并判断游戏是否结束,用返回值带回判断的结果
//第四个参数通过传递玩家的棋子,用来代表不同的玩家
char play_board(char board[ROW][COL],int row, int col,char piece);

三、game.c 文件

1. 设计棋盘

棋盘的格子采用空格字符空格的形式

  • 一行中两个格子之间采用 | 分格
  • 相邻两行的格子中间采用连续的三个下划线
  • 两个连续的下划线之间也采用 | 分格

2. 初始化棋盘

根据棋盘格子的设计,棋盘最初是会打印字符的,为了可以达到视觉的效果,将数组全部初始化成空格

#include "game.h"          //需要用到 game.h 中的声明void init_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//初始化为空格for (i = 0; i < row; i++)for (j = 0; j < col; j++)board[i][j] = ' ';
}

3. 打印棋盘

 print_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//打印列号printf("  ");        //为了对齐,打印行号时,会占用两个空格for (i = 1; i <= COL; i++)printf(" %x  ", i);        //因为10以上的数字会占用两个位置//这里采用十六进制的形式打印printf("\n");for (j = 0; j < row; j++){//打印行号printf("%x ", j + 1);      //采用十六进制的形式打印//打印 * | * | *     (这里 * 号表示字符)for (i = 0; i < col; i++){printf(" %c ", board[j][i]);//不打印最后一列的竖线if (i < col - 1)printf("|");}printf("\n");//为了对齐printf("  ");//打印___|___|___ ,最后一行打印   |   |   for (i = 0; i < col; i++){//将最后一行的3个下划线换成3个空格j == row - 1 ? printf("   ") : printf("___");//不打印最后一列的竖线if (i < col - 1)printf("|");}printf("\n");}
}

4. 玩家下棋

(1)玩家落子

char play_board(char board[ROW][COL], int row, int col, char piece)
{int x = 0;int y = 0;while (1){scanf("%d %d", &x, &y);//坐标合法if (x >= 1 && x <= row && y >= 1 && y <= col){//坐标是否被占用,玩家并不知道要从 0 开始,所以坐标应当 -1if (board[x - 1][y - 1] != PIECE_ONE && board[x - 1][y - 1] != PIECE_TWO){board[x - 1][y - 1] = piece;//判断是否结束游戏,注意这里传参传的是调整好的坐标//最后一个参数是用来代表玩家的return is_win(board, row, col, x - 1, y - 1, piece);        }else{printf("输入错误,请重新输入:>");}}else{printf("坐标非法,请重新输入:>");}}
}

(2)判断玩家落子后是否游戏结束

玩家在下当前这棵棋子时,如果游戏结束,只可能是包含这棵棋子的横线五颗,竖线五颗,主斜线五颗,以及副斜线五颗

应当注意:在传参时已经将坐标调整为是从 0 开始的

这里我们以横线五颗为例说明,其他只需要改变判断的坐标,其思路是类似的

static char is_win(char board[ROW][COL], int row, int col, int x, int y, char piece)
{int i = 0;int j = 0;int k = 0;//记录当前棋盘的总棋子数static int count = 0;count++;//判断竖线for (i = x - 4; i <= x; i++){//坐标越界if (i < 0 || i + 4 >= row)continue;//判断是否有连续相等的五颗for (j = 0; j < 5; j++){if (board[i + j][y] != piece)break;}//判断是否获胜if (j == 5)return  piece;}//判断横线for (i = y - 4; i <= y; i++){//坐标越界if (i < 0 || i + 4 >= col)continue;//判断是否有连续相等的五颗for (j = 0; j < 5; j++){if (board[x][i + j] != piece)break;}//判断是否获胜if (j == 5)return  piece;}//判断正斜线for (i = x - 4, j = y - 4; i <= x; i++, j++){//坐标越界if (i < 0 || j < 0 || i + 4 >= row || j + 4 >= col)continue;//判断是否有连续相等的五颗for (k = 0; k < 5; k++){if (board[i + k][j + k] != piece)break;}//判断是否获胜if (k == 5)return  piece;}//判断副斜线for (i = x + 4, j = y - 4; i <= x; i++){//坐标越界if (i >= row || j < 0 || i + 4 < 0 || j + 4 >= col)continue;//判断是否有连续相等的五颗for (k = 0; k < 5; k++){if (board[i - k][j + k] != piece)break;}//判断是否获胜if (k == 5)return  piece;}//判断是否平局if (count == row * col)return 'Q';return 'C';
}

四、源码

test.c 文件

#include "game.h";void mnue()
{printf("******************\n");printf("***   1.play   ***\n");printf("***   0.exit   ***\n");printf("******************\n");
}void game()
{char ret = 0;char board[ROW][COL];init_board(board, ROW, COL);        //初始化print_board(board, ROW, COL);      //打印棋盘printf("********************\n");printf("本游戏通过坐标来下棋\n");printf("********************\n");while(1){printf("玩家1 请下棋:>");ret = play_board(board, ROW, COL, PIECE_ONE);if (ret != 'C')break;system("cls");print_board(board, ROW, COL);printf("玩家2 请下棋:>");ret = play_board(board, ROW, COL, PIECE_TWO); if (ret != 'C')break;system("cls");print_board(board, ROW, COL);}if (ret == PIECE_ONE){printf("恭喜玩家1,获胜\n");}else if(ret == PIECE_TWO){printf("恭喜玩家2,获胜\n");}else{printf("很遗憾,没有决出胜负\n");}Sleep(5000);system("cls");
}int main()
{int input = 0;do{//菜单mnue();printf("请输入:>");scanf("%d", &input);system("cls");//用户选择switch (input){case 1:printf("欢迎来到五子棋,游戏开始\n");game();break;case 0:printf("退出游戏\n");break;default :printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}

game.h 文件

#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#include<stdlib.h>
#include<windows.h>#define ROW 8
#define COL 8
#define PIECE_ONE '*'
#define PIECE_TWO '#'//初始化
void init_board(int board[ROW][COL], int row, int col);//打印棋盘
void print_board(char board[ROW][COL], int row, int col);//玩家下棋,并判断游戏是否结束
char play_board(char board[ROW][COL], int row, int col, char piece);

game.c 文件

#include "game.h"void init_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++)for (j = 0; j < col; j++)board[i][j] = ' ';
}void print_board(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//打印列号printf("  ");        //为了对齐for (i = 1; i <= COL; i++)printf(" %x  ", i);printf("\n");for (j = 0; j < row; j++){//打印行号printf("%x ", j + 1);//打印 * | * | * for (i = 0; i < col; i++){printf(" %c ", board[j][i]);if (i < col - 1)printf("|");}printf("\n");//为了对齐printf("  ");//打印___|___|___ ,最后一行打印   |   |   for (i = 0; i < col; i++){j == row - 1 ? printf("   ") : printf("___");if (i < col - 1)printf("|");}printf("\n");}
}static char is_win(char board[ROW][COL], int row, int col, int x, int y, char piece)
{int i = 0;int j = 0;int k = 0;//记录当前棋盘的总棋子数static int count = 0;count++;//判断竖线for (i = x - 4; i <= x; i++){if (i < 0 || i + 4 >= row)continue;for (j = 0; j < 5; j++){if (board[i + j][y] != piece)break;}//判断是否获胜if (j == 5)return  piece;}//判断横线for (i = y - 4; i <= y; i++){if (i < 0 || i + 4 >= col)continue;for (j = 0; j < 5; j++){if (board[x][i + j] != piece)break;}//判断是否获胜if (j == 5)return  piece;}//判断正斜线for (i = x - 4, j = y - 4; i <= x; i++, j++){if (i < 0 || j < 0 || i + 4 >= row || j + 4 >= col)continue;for (k = 0; k < 5; k++){if (board[i + k][j + k] != piece)break;}//判断是否获胜if (k == 5)return  piece;}//判断副斜线for (i = x + 4, j = y - 4; i <= x; i++){if (i >= row || j < 0 || i + 4 < 0 || j + 4 >= col)continue;for (k = 0; k < 5; k++){if (board[i - k][j + k] != piece)break;}//判断是否获胜if (k == 5)return  piece;}//判断是否平局if (count == row * col)return 'Q';return 'C';
}char play_board(char board[ROW][COL], int row, int col, char piece)
{int x = 0;int y = 0;while (1){scanf("%d %d", &x, &y);//坐标合法if (x >= 1 && x <= row && y >= 1 && y <= col){//坐标是否被占用if (board[x - 1][y - 1] != PIECE_ONE && board[x - 1][y - 1] != PIECE_TWO){board[x - 1][y - 1] = piece;return is_win(board, row, col, x - 1, y - 1, piece);        //判断是否结束游戏}else{printf("输入错误,请重新输入:>");}}else{printf("坐标非法,请重新输入:>");}}
}

本代码只提供了两个玩家对战的模式,读者有兴趣可以开发人机对战模式
代码亲测有效,如有建议,可以评论留言

C语言学会数组就可以做五子棋 - 快来试试吧(包含源码)相关推荐

  1. 百度seo快排点击系统源码[易语言]拨号模拟点击(仅供学习使用!)

    [百度seo快排点击系统源码]易语言写的利用chrome模拟点击自己网站排名,从而提高百度搜索排名的软件源码.真实可用,请勿用作非法用途. 文件:n459.com/file/25127180-4773 ...

  2. 五子棋服务端程序java_9网上五子棋对战(java)服务端源码

    9网上五子棋对战(java)服务端源码 网上五子棋对战(java)服务端源码 /* 五子棋游戏是本人在学习java swing时写的一个程序,程序分两部分:服务器端和客户端.运行程序时先运行服务器端, ...

  3. c语言远控,远控鼠标!C语言简单编程:整舍友必备+附送实例源码!

    远控鼠标!C语言简单编程:整舍友必备+附送实例源码!-1.jpg (10.71 KB, 下载次数: 0) 2018-10-11 05:24 上传 关注<一碳科技>有更多干货等着你哦! 远控 ...

  4. c语言比较函数memcmp,c语言函数memcmp()如何比较内存前n个字节实例源码介绍

    c语言函数memcmp()如何比较内存前n个字节实例源码介绍.引入头文件:#include 定义memcmp()函数:int memcmp (const void *s1, const void *s ...

  5. 2021laysns内核仿大婶娱乐网模板整站源码 非常漂亮 可做娱乐资源网 整站打包源码

    介绍: laysns内核仿大婶娱乐网模板首发可做娱乐资源网整站打包源码2021最新版,其实风格和115资源网是一样的,有着会员投稿系统! 完整带Laysns系统可运营做资源站娱乐网 网盘下载地址: h ...

  6. html5+css3做的响应式企业网站前端源码

    大家好,今天给大家介绍一款,html5+css3做的响应式企业网站前端源码 (图1).送给大家哦,获取方式在本文末尾. 图1 首页banner幻灯片切换特效(图2) 图2 首页布局简约合理(图3) 图 ...

  7. C语言源码做的班级档案管理系统课程设计(源码+课程设计报告)

    一.课程设计的目的: C语言课程设计是计算机科学与技术专业重要的实践性教学环节之一,本次设计结合实际应用的要求,使课程设计既覆盖C语言程序设计的知识点,又接近工程实际需要.本次设计的目的是通过课程设计 ...

  8. C语言源码做的职工工资管理系统课程设计(源码+课程设计报告)

    一.课程设计的目的: C语言课程设计是计算机科学与技术专业重要的实践性教学环节之一,本次设计结合实际应用的要求,使课程设计既覆盖C语言程序设计的知识点,又接近工程实际需要.本次设计的目的是通过课程设计 ...

  9. Java 五子棋 包含强大人机 步骤流程 包含源码

    我们分3个大步骤来实现: 1. 在窗体上画棋盘.画棋子(棋子在网格交点.交替落子) 2. 判断输赢,即寻找是否在同一直线上有5子相邻 3. 人机大战 前2个步骤就可以实现基础的人人对战,让我们开始吧 ...

最新文章

  1. Spring security获取当前用户
  2. 一篇绝好的讲sql server索引的文章,值得收藏
  3. VC6中使用高版本系统API的方法
  4. php按需加载方式来增加程序的灵活度
  5. 大数据在各个行业中的应用_三维设计广泛应用各个行业
  6. 数据结构---模式匹配
  7. Gartner 2018 年WAF魔力象限报告:云WAF持续增长,Bot管理与API安全拥有未来
  8. html5的所有标签页,HTML5所有标签总集
  9. 2015级C++第7周项目 友元、共享数据保护、多文件结构
  10. java log4j trace_关于LOG4J中的日志级别TRACE
  11. 恶意软件、反病毒网关简析
  12. 软考项目管理十大管理及过程
  13. 挖金矿问题java课程设计_Win32 挖金矿游戏源代码
  14. Excel合并不同工作簿的表到同一个工作簿
  15. python画成绩正态分布图_数据分析基础(1)——神奇的正态分布
  16. React:styled-components的使用
  17. Win系统EPUB阅读软件评测
  18. 北航计算机沙江波,北航材料学院导师
  19. 如何制作注册登录网址
  20. 凤姐模仿Lady Gaga 称和国外明星平起平坐(图)

热门文章

  1. python实现 Python蟒蛇绘制(嵩天老师 )
  2. 看《流金岁月》杨珂带领销售团队成功之处
  3. 同期及上期数据对比显示
  4. DDD 实战 (11):冲刺 1 代码 TDD 实现之道
  5. 免费的可直接运行的简单易懂的C++学生信息管理系统
  6. java uuid去掉横线_UUID去横杠-的正确方式
  7. CSS 内边距 padding 属性
  8. Word2010中怎样压缩图片使文件变小
  9. Canvas绘制基本线条的方式
  10. 唯有卡拉特拉瓦,才敢让建筑飞起来!