目录

一.游戏实现的整体思路

二.实现游戏大体框架

二.游戏函数的实现

1.初始化键盘

2.打印棋盘

3.下棋及胜负判断

(1)玩家下棋

(2)电脑下棋

(3)判断输赢

三.结语及源码


三子棋想必大家都不陌生,本篇文章带大家一起用C语言来实现三子棋小游戏,来体会体会编程的乐趣,本篇文章可以给你带来一种新的编程体验,带你实际了解逼真项目开发过程。(文章末尾贴有源码)

一.游戏实现的整体思路

首先,通过我们的观察以及结合我们之前学过的知识,我们发现三子棋的棋盘与二维数组及其类似,他们都是三行三列,我们可以将这个3✖3的游戏棋盘中的数据储存进二维数组,玩家或电脑每次下一步棋,我们就将数组对应位置的数据改为*或#号作为下的棋子(本文中以*作为玩家下的棋子,#作为电脑下的棋子),每下一步棋或者说改一下数组数据,我们都要打印一遍棋盘。每次打印完棋盘,我们需要判断游戏是否继续进行,也就是看是否有哪一方获得游戏胜利或者平局。

在项目开始之前,我们将创建三个文件,主文件test.c放游戏主要大致框架,game.c实现游戏逻辑,game.h存放函数声明,以及头文件引用等内容。

二.实现游戏大体框架

我们首先在game.h文件中引入头文件stdio.h,再分别再game.c和test.c中引入头文件game.h,这样仅仅只需要在game.h文件中引用头文件。

注:引用自己编写的头文件得用双引号,而不是尖括号

我们先做一个简易的游戏菜单,回想我们平时在玩游戏时,一般是都先弹出游戏菜单让我们进行选择,这里我们也一样,设置一个input变量来保存用户的选择即输入值,我们一般玩游戏也不只是只玩一局,我们每次玩一局以后,我们希望能供用户选择是退出游戏还是继续再玩一局,这时候,我们可以通过do while循环实现,当然别的循环语句也可以,这里我采用的是do while循环,当用户输入完值以后,我们通过使用分支语句对用户的选择进行分流,来实现用户选择后对应的功能,以下代码仅仅是测试主体逻辑,游戏的实现用prinft函数替代,下面会详细讲解游戏主要实现逻辑。

//test.c文件
void menu()
{printf("******************************\n");printf("********   1.play  ***********\n");printf("********   0.exit  ***********\n");printf("******************************\n");
}
int main()
{int input = 0;do {//打印游戏菜单menu();printf("请选择>:");scanf("%d", &input);switch (input){case 1:printf("玩游戏");break;case 0:printf("退出游戏\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);

二.游戏函数的实现

这里我们将编写以上switch语句case 1 中的游戏逻辑函数。

1.初始化键盘

我们首先在test.c文件中创建一个游戏逻辑的函数,我们会在这个函数里实现游戏的逻辑。我们先创建一个二维数组,这个数组将用来储存棋盘中的数据,为了增加代码的通用性,我们将定义一个宏作为二维数组的行和列,使我们未来想修改成别的数据时更加便利,我们将这个宏定义到game.h文件中,接着我们在game.h声明初始化键盘的函数,并在game.c来定义这个函数,最后在test.c调用这个函数。

//game.h文件
//游戏实现中各种函数的声明
#include <stdio.h>
#define ROW 3
#define COL 3//声明初始化棋盘函数
void init_keyboard(char keyboard[ROW][COL], int row, int col);

观察下图和代码,我们想先用空格将棋盘填充起来,这时,我们可以先将二维数组中的每个数据初始化为空格。

//game.c文件
//初始化棋盘
void init_keyboard(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){keyboard[i][j] = ' ';}}
}
//test.c文件
void game()
{//创建一个存放棋子的二维数组char keyboard[ROW][COL] = { 0 };printf("三子棋小游戏\n");//调用初始化游戏棋盘函数init_keyboard(keyboard, ROW, COL);
}

2.打印棋盘

如果说初始化键盘是磨刀,那么打印键盘就是切菜了,这是准备阶段的最后一步了,和上面声明和定义一样,都在特定的文件中编写,下面就仅仅展示定义的代码,仔细观察下图,我们发现可以通过双层循环的方式打印这个棋盘。

我们把1、2行合并看作一行,不难看出,我们可以通过循环三次,最后一次不打印最后横线那一行。竖排也是类似,不打印最后一排竖线。以下代码for循环里嵌套的第一个for循环也就是打印上图数字编号为1的那一行,for循环里嵌套的第二个for循环也就是打印上图编号为2的那一行。

//game.h文件
//打印棋盘
void display_keyboard(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){// %c | %c | %c for (j = 0; j < col; j++){printf(" %c ", keyboard[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");}}
}

3.下棋及胜负判断

下棋分为玩家下棋,电脑下棋,其中还有胜负的判断,大概思路是写一个循环,循环里首先是玩家下棋,接着打印棋盘和判断输赢,然后是电脑下棋,打印棋盘和判断输赢,无论有哪一方获得了胜利,就退出循环。

//test.c文件
char ret = 0;do{//玩家下棋printf("玩家下棋:\n");player_move(keyboard, ROW, COL);//打印棋盘display_keyboard(keyboard, ROW, COL);//判断输赢ret = is_win(keyboard, ROW, COL);if (ret != 'C'){break;}//电脑下棋printf("电脑下棋:\n");computer_move(keyboard, ROW, COL);//打印棋盘display_keyboard(keyboard, ROW, COL);//判断输赢ret = is_win(keyboard, ROW, COL);if (ret != 'C'){break;}} while (1);

以下来编写这个循环里的几个函数

(1)玩家下棋

我们通过让玩家输入他们想要下棋的坐标来实现下棋步骤,在玩家输入坐标又可能出现以下情况。

a.玩家输入正确坐标,更改棋盘数组的数据

b.玩家输入坐标不合法,即输入了错误的数字(默认输入是1到3)

c.玩家输入的坐标被占用

出现b、c情况时,我们需要让玩家重新输入,这时我们可以设计一个循环,如果玩家输入正确的坐标就退出循环,如果玩家输入错误的坐标就让玩家重新输入,知道玩家输入正确坐标为止。

//game.c文件
//玩家下棋(*)
void player_move(char keyboard[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请输入您要下的坐标:");while (1){scanf("%d %d", &x, &y);if ((x >= 1 && x <= row) || (y >= 1 && y <= col)){if (keyboard[x - 1][y - 1] == ' '){keyboard[x - 1][y - 1] = '*';break;}else{printf("输入的左边已占用!请重新输入");}}else{printf("请输入一个合法的坐标!\n");}}
}

(2)电脑下棋

电脑下棋也是同样的,我们用坐标来决定下哪,这个坐标如何形成呢,我们这里使用的是一个随机数字,我们用rand函数随机生成一个随机数,但使用rand函数之前必须要用srand函数设置一个随机数起点,srand函数得使用一个实时变化的量才可以确保我们生成的数字是随机的想想我们的生活中,时间是每时每刻都在发生变化的,于是我们将时间戳作为srand函数的参数生成随机数起点,time函数是生成时间戳的函数。

注:rand和srand函数得使用头文件stdlib.h,而time函数得使用头文件time.h,前面说过所有得头文件引用和声明都在game.h文件中编写。

因为生成得随机数范围是0~RAND_MAX,C语言中规定RAND_MAX的大小是0x7fff,因此我们必须将得到的随机数进行一个求余的操作才能得到我们想要得到的数据,同样,得到这个数据后我们必须判断该数据的坐标是否可以使用,这时我们需通过循环来寻找一个符合的随机数。得到这个数后,再修改棋盘数据来实现下棋的功能。

//game.c文件
//电脑下棋(#)
void computer_move(char keyboard[ROW][COL], int row, int col)
{//用时间戳随机生成随机数起始点(用时间绑定)srand((unsigned int)time(NULL));while (1){//生成随机数int x = rand() % row;int y = rand() % col;if (keyboard[x][y] == ' '){keyboard[x][y] = '#';break;}}
}

(3)判断输赢

每当有一方下了棋,就必须有判断输赢的机制,我们设计一个is_win函数来判断输赢,如果玩家赢则返回字符*,如果电脑赢则返回#,如果平局则返回Q,如果游戏未分胜负,继续进行,则返回C。

a.判断哪方输赢,我们通过列举法,赢了无非是三个棋子在同一个横排,同一个竖排或两条对角线,无非就是这三种可能。

b.平局即以上都不满足和棋盘满了,我们这里仅仅需要判断棋盘是否满了就可以了,因为如果有哪一方赢了,上面的return函数早就将结果带回了原函数,这里我们编写一个is_full函数来判断棋盘是否满了,如果满了则返回1,没满返回0,再将结果返回is_win函数。

c.以上几种情况都不满足就只有游戏未分胜负一种可能了,我们仅仅用一个return函数返回字符C即可。

//game.c文件
//判断棋盘是否满了
int is_full(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;int flat = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (keyboard[i][j] == ' '){flat = 0;}}}return flat;
}//判断游戏是否结束
char is_win(char keyboard[ROW][COL], int row, int col)
{int i = 0;//同一个横排获得胜利for (i = 0; i < row; i++){if (keyboard[i][0] == keyboard[i][1] && keyboard[i][1] == keyboard[i][2] && keyboard[i][0] != ' '){return keyboard[i][0];}}//同一个竖列获得胜利for (i = 0; i < col; i++){if (keyboard[0][i] == keyboard[1][i] && keyboard[1][i] == keyboard[2][i] && keyboard[0][i] != ' '){return keyboard[0][i];}}//对角线获得胜利if (keyboard[0][0] == keyboard[1][1] && keyboard[1][1] == keyboard[2][2] && keyboard[1][1] != ' '){return keyboard[1][1];}if (keyboard[0][2] == keyboard[1][1] && keyboard[1][1] == keyboard[2][2] && keyboard[1][1] != ' '){return keyboard[1][1];}//平局if (is_full(keyboard, row, col)){return 'Q';}//继续return  'C';
}

三.结语及源码

以下是该文章所有代码总结

test.c文件

//test.c文件
#define _CRT_SECURE_NO_WARNINGS 1//实现游戏主要框架
#include "game.h"void game()
{char keyboard[ROW][COL] = { 0 };printf("三子棋小游戏\n");//初始化游戏棋盘init_keyboard(keyboard, ROW, COL);//打印棋盘display_keyboard(keyboard, ROW, COL);//下棋char ret = 0;do{//玩家下棋printf("玩家下棋:\n");player_move(keyboard, ROW, COL);ret = is_win(keyboard, ROW, COL);if (ret != 'C'){break;}display_keyboard(keyboard, ROW, COL);printf("电脑下棋:\n");computer_move(keyboard, ROW, COL);display_keyboard(keyboard, ROW, COL);ret = is_win(keyboard, ROW, COL);if (ret != 'C'){break;}} while (1);if (ret == '*'){printf("玩家胜利!\n");}else if(ret == '#'){printf("电脑胜利!\n");}else{printf("平局!\n");}
}void menu()
{printf("******************************\n");printf("********   1.play  ***********\n");printf("********   0.exit  ***********\n");printf("******************************\n");
}
int main()
{int input = 0;do {//打印游戏菜单menu();printf("请选择>:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}

game.h文件

//game.h文件
#define _CRT_SECURE_NO_WARNINGS 1//游戏实现中各种函数的声明
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3//初始化键盘
void init_keyboard(char keyboard[ROW][COL], int row, int col);
//打印键盘
void display_keyboard(char keyboard[ROW][COL], int row, int col);
//玩家下棋
void player_move(char keyboard[ROW][COL], int row, int col);
//电脑下棋
void computer_move(char keyboard[ROW][COL], int row, int col);
//判断游戏是否结束
char is_win(char keyboard[ROW][COL], int row, int col);

game.c文件

//game.c文件
#define _CRT_SECURE_NO_WARNINGS 1//实现游戏的逻辑
#include "game.h"//初始化键盘
void init_keyboard(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){keyboard[i][j] = ' ';}}
}//打印键盘
void display_keyboard(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){//printf(" %c | %c | %c \n", keyboard[i][0], keyboard[i][1], keyboard[i][2]);//   |   |   for (j = 0; j < col; j++){printf(" %c ", keyboard[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 keyboard[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请输入您要下的坐标:");while (1){scanf("%d %d", &x, &y);if ((x >= 1 && x <= row) || (y >= 1 && y <= col)){if (keyboard[x - 1][y - 1] == ' '){keyboard[x - 1][y - 1] = '*';break;}else{printf("输入的左边已占用!请重新输入");}}else{printf("请输入一个合法的坐标!\n");}}
}//电脑下棋(#)
void computer_move(char keyboard[ROW][COL], int row, int col)
{srand((unsigned int)time(NULL));while (1){int x = rand() % row;int y = rand() % col;if (keyboard[x][y] == ' '){keyboard[x][y] = '#';break;}}
}//判断棋盘是否满了
int is_full(char keyboard[ROW][COL], int row, int col)
{int i = 0;int j = 0;int flat = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (keyboard[i][j] == ' '){flat = 0;}}}return flat;
}//判断游戏是否结束
char is_win(char keyboard[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){if (keyboard[i][0] == keyboard[i][1] && keyboard[i][1] == keyboard[i][2] && keyboard[i][0] != ' '){return keyboard[i][0];}}for (i = 0; i < col; i++){if (keyboard[0][i] == keyboard[1][i] && keyboard[1][i] == keyboard[2][i] && keyboard[0][i] != ' '){return keyboard[0][i];}}if (keyboard[0][0] == keyboard[1][1] && keyboard[1][1] == keyboard[2][2] && keyboard[1][1] != ' '){return keyboard[1][1];}if (keyboard[0][2] == keyboard[1][1] && keyboard[1][1] == keyboard[2][2] && keyboard[1][1] != ' '){return keyboard[1][1];}//平局if (is_full(keyboard, row, col)){return 'Q';}//继续return  'C';
}

以上是本文所有内容了,本文仅仅想传达开发中的一种设计模式和游戏设计的思路,更重要是提高编程过程中的趣味性,码文不易,大家的三连是对小编最大的鼓励,谢谢

三子棋小游戏带你走进编程世界(c语言版)相关推荐

  1. C语言实现三子棋小游戏(编程思路以及代码详解)

    目录 前言 一.三子棋游戏的实现逻辑 二.创建菜单并控制游戏开始或游戏结束 三.创建棋盘并且初始化棋盘 四.打印棋盘并验证打印棋盘和初始化棋盘模块的实现 五.玩家下棋 六.电脑下棋 六.输赢判断 七. ...

  2. C语言小项目--三子棋小游戏

    学了这么长时间的C语言,你是否觉得没有一个没写过稍微长点的代码显得很没有成就感!不怕,今天带你做一个小游戏,领略一下写C和小游戏的快乐.写完记得给自己一个鼓励哦! 一.三子棋小游戏 想必大家都玩过三子 ...

  3. 三子棋小游戏(超详细)

    目录 一.实现三子棋游戏的基本逻辑 二.具体的函数实现 1. 菜单函数 2. 棋盘的实现 2.1 棋盘的初始化 2.2 棋盘的打印 3. 玩家下棋 4. 电脑下棋 5.判断棋盘状态 三. 三个文件 3 ...

  4. 【牛客刷题】上手用C语言写一个三子棋小游戏超详解哦(电脑优化)

    作者:[南航科院小张 南航科院小张的博客 专栏:从c语言的入门到进阶 学习知识不只是要懂,还要会用:想要找到好的工作,这里给大家介绍一件可以斩获诸多大厂offer的利器–牛客网 点击免费注册和我一起开 ...

  5. 使用C语言编写三子棋小游戏

    使用C语言编写三子棋小游戏: 首先进行分析: 1.需要将游戏实现分为三个部分:头文件,函数功能实现,游戏组合测试. 2.游戏可以循环进行,不必多次打开,可采用 do...while循环结构. 3.游戏 ...

  6. 如何制作三子棋小游戏

    首先,一个游戏的制作,必须由大化小,分步完成. 当我们想要制作三子棋小游戏时,必须先搞清楚这个小游戏的逻辑和原理. 三子棋是黑白棋的一种.三子棋是一种民间传统游戏,又叫九宫棋.圈圈叉叉.一条龙.井字棋 ...

  7. vs2010c语言小游戏,用C语言写一个三子棋小游戏(用VS2010实现,加强版)

    前几天写了一个三子棋小游戏,但是比较简单,因为以前写的游戏棋盘只能是3x3那么大.今天对那个程序做了两点改进: 1.现在可以实现在任意大小的棋盘上下棋了. 2.因为棋盘可能变大,为了玩家方便确定坐标, ...

  8. 呆头呆脑的电脑----三子棋小游戏(C语言版)

    目录 1.需求分析 2.程序架构 3.代码实现(分函数呈现) (1)主函数代码实现 分析: 异常处理: (2)菜单函数的实现 分析: (3)游戏函数的实现 分析: (4)棋盘的初始化 分析: (5)棋 ...

  9. 趣讲用c语言实现三子棋小游戏

    目录 直接先看看最后运行效果吧 三子棋如何设计的,及其步骤 1,源文件已经头文件的创建 2.创建主函数 3.test函数的创建 4.game函数的创建和运行 5.五个函数的实现 a.init_boar ...

最新文章

  1. Python函数你真的都学会了吗?来看看这篇Python高阶函数!
  2. egg mysql insert_egg-mysql
  3. 74HC595串口转并口芯片学习
  4. Android 获取文件后缀名
  5. Word中部分内容出现乱码、不显示页码和目录
  6. ctf中对于rar压缩包的暴力破解问题
  7. 阿里P7需要精通哪些技术?看完Github上星标98K的对标阿里P7学习路线我彻底惊了
  8. 淘宝产品,为什么转化率还是这么低?
  9. 央企招聘:中国航空油料集团2023公开招聘
  10. 微信公众号开发 - 开发环境搭建
  11. C语言#判断今天是工作日还是休息日
  12. 解决kali无法定位软件包
  13. 数据分析实战----北京租房数据统计分析
  14. oa项目环境搭建的操作步骤详解
  15. 信用风险计量模型汇总
  16. 适合小白的大白话讲解---Git与Github的区别
  17. java 生成banner 服务 字体
  18. TSN (Time-Sensitive Networking)时间敏感网络
  19. python 实现 短信登录 b站 并打印cookie内容
  20. 移动机器人的那些避障方法你知多少?

热门文章

  1. 实验室第八周周工作总结
  2. Opencv之视频入门
  3. 爬梯:ElasticSearch分布式搜索引擎
  4. [附源码]JSP+ssm计算机毕业设计“美丽乡村摄影”网站设计与实现fumie【源码、数据库、LW、部署】
  5. 数组 去除重复元素 的多种方法
  6. C语言编程求某人岁数
  7. 移动应用安全过去及未来发展情况思考汇总
  8. java分类锁_【基本功】java锁分类详解
  9. Python 爬虫“王者”:豆瓣海报爬取
  10. 如何将flv文件转为mp4文件?一个简单的解决办法