C语言小游戏:三子棋

目录

🌍前言

🚅目录设计

💎游戏逻辑设置

⚔三子棋棋盘设计

⚔三子棋运行逻辑

👀怎么设置人下棋

👀怎么设置电脑下棋

✈如何判断输赢

✍结语


🌍前言

Hello,csdn的各位小伙伴你们好啊!这次小赵给大家带来的C语言小游戏是三子棋,三子棋也就是大家常玩的井字棋,这样的一个编程想必会让很多人都兴奋不已,好了好了那我们赶快开始吧。

🚅目录设计

目录的设计我们已经讲过好几遍了,还是最简单的那个,简单一个打印*加一些选项。然后用我们的switch函数来实现我们的选择,如输入1进入游戏,0跳出游戏,其他报错然后重新输入。

void meun()
{printf("*************************************************\n");printf("*********************0.exit**********************\n");printf("*********************1.play**********************\n");printf("*************************************************\n");printf("请输入你的选择:");
}
int main()
{int a = 0;do{meun();scanf("%d", &a);switch (a){case 1:game();break;case 0:printf("游戏结束\n");break;default:printf("输入错误,请重新输入\n");break;}} while (a);

 在这里我们就不多说了,详细的讲解大家可以看看前面的扫雷和猜数字游戏。(大家可以关注小赵的专栏c语言小游戏哦!

🚀游戏逻辑设置

前面的东西聊完了,那么我们就不得不聊聊我们的游戏逻辑设计,我们得先想明白我们下这个三子棋需要什么,棋盘,棋子对不对,这个至少不能少吧,那下面呢,是不是得看怎样才算赢了这了这盘棋,接着还需要考虑我们和谁下棋得问题,当然小赵在这里剧透一波,这里是和电脑哦!怎么样是不是瞬间对这个代码感到好奇了,那我们抓紧开始吧。

⚔三子棋棋盘设计

首先是棋盘设置,在这里小赵找到了一张我们正常的井字棋的图片。

小赵仿照这个图做了一个我们可以通过编程实现的较为简单的棋盘

​​​​​​​

我们可以注意到这样的一个棋盘就更好实现,因为里面的很多元素是重复的而且可以靠我们|-——来解决。当然这里我们还是和扫雷时候一样进行一个封装,将这个代码装入我们的函数中。

#define ROW  3//定义行
#define COL  3//定义列
void InitBoard(char arr[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){arr[i][j] = ' ';//对数组初始化,每个位置都是空白}}
}
void PrintBoard(char arr[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", arr[i][j]);//打印占棋子位子if (j < col - 1)printf("|");//打印棋盘元素//   |     |    (最后一个没有)}printf("\n");//换行for (int j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");//———|———|———(最后一个没有|)}printf("\n");}
}

那么我们的整个棋盘就算结束了,到这里。 

🚀下棋

下面就是下棋了,在这里我们先约定一下我们的棋子是什么,在这里小赵就定义一下*为我们的棋子,那么我们每次下棋实际上就是将这些空白地方放上我们的棋子,也就是取代我们的%c的空白位置。

👀怎么设置人下棋

那么人怎么下棋呢,你完全可以根据小赵的上周的博客那篇教你学C里面讲的二维数组一样,把这个棋盘的下棋位置当成二维数组的每个位置,那么我们在下的时候只需要根据我们的每个坐标来下棋就好了,在这里小赵也是封装成了一个函数。

void PersonSet(char arr[ROW][COL], int row, int col)
{int ret;do{int x, y;scanf("%d %d", &x, &y);if (x-1 < row && y-1 < col){if (arr[y-1][x-1] == ' '){arr[y-1][x-1] = '*';//对第几列第几行下棋ret = 0;}}else{printf("输入错误,请重新输入\n");//报错重新输入ret = 1;}} while (ret);
}

为了方便大家知道自己的棋是怎么下的,小赵又画了一张图供大家参考,当然画的不好请见谅。

👀怎么设置电脑下棋

这里的电脑下棋,小赵实在也不知道该如何去做一个去能分析对手下棋的强大AL,所以很抱歉,这里小赵用的还是未知数,当然如果大家有什么好的想法可以在小赵的评论区留下留言,让小赵也能学习学习。好了我们接着看电脑下棋,这里为了有所区别,小赵这里给电脑另一个棋字#,让我们有所区分。这里也是封装成一个函数了。

void ComputerSet(char arr[ROW][COL], int row, int col)
{srand((unsigned int)time(NULL));while (1) {int x = rand() % row + 1;int y = rand() % col + 1;if (arr[y - 1][x - 1] == ' '){arr[y - 1][x - 1] = '#';break;}}
}

🚀如何判断输赢

那么这个时候就是最关键的时候了。我们该如何判断输赢了,我们知道井字棋的结局共有三种,第一种是人赢了,第二种电脑赢,第三种平局(即棋盘下满了)。而且还要考虑到什么情况横着竖着和斜着,这里可以说是相当复杂了。我们一步一步来。

✊平局

平局怎么判定,其实就是棋盘上的棋子都下满了,那我们只需要用循环一个个扫就行了,确保棋盘上没有一个空的地方,且这个时候双方没有输赢(这个放在下面)。

int is_FULL(char arr[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for(int j=0;j<col;j++)if (arr[i][j] =' '){return 0;//如果有空位,返回零}}return 1;//扫完所有放棋子,都没有空位,返回1
}

这里小赵用一种返还数字的方式来判断究竟有木有空的地方,这样我们在下面只需要将判断的三种结局的方式用一个函数穿起来就好了。 

✊判断输赢

在判断输赢这里,我们要尽可能的巧妙和省代码,比如判断人赢还是电脑赢,其实就是判断某一种棋子是否连三个相等。其次就是我们上面的平局用的1/0我们可以加入其中,如若是平局就进入if函数来出来,同时我们还要注意我们这个是一个判断,那么这个判断的时候就要注意我们判断的时候可能不是输赢平,那我们就要继续下,那我们可以再设置一个返还数字在下面,这样经过所有判断都没结果后,我们就输出一个字母意思是继续。

char is_win(char arr[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){if (arr[i][0] ==arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' '){return arr[i][0];//如果一竖行都是一种棋子,则返回这个棋子}}for (i = 0; i < col; i++){if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' '){return arr[0][i];//如果一横行都是一种棋子,则返回这个棋子}}if (arr[0][0] == arr[1][1] && arr[1][1] ==arr[2][2] && arr[1][1] != ' '){return arr[1][1];//如果左斜着都是一种棋子,则返回这个棋子}if (arr[0][2] == arr[1][1] &&arr[1][1] == arr[2][0] && arr[1][1] != ' '){return arr[1][1];//如果右斜着都是一种棋子,则返回这个棋子}//判断平局if (is_FULL(arr, row, col))//返回1为真,0为假。{return 'Q';//如果是平局返还Q}return 'C';//若上面都不是,返还c意思是游戏继续}

🛸游戏运行逻辑

我们现在手上已经有了这么多的函数下面就要编我们的整个运行的逻辑吧。首先我们要确定的是我们的判断应该什么时候进行,我觉得应该下一次就判断一次,因为我们的函数中是有继续的选项的,所以完全可以下一次判断一次,同时下一次打印一次。

void game()
{char ret;char arr[ROW][COL];InitBoard(arr, ROW, COL);//定义数组PrintBoard(arr, ROW, COL);//打印棋盘while (1){PersonSet(arr, ROW, COL);//人下PrintBoard(arr, ROW, COL);//打印棋盘ret = is_win(arr, ROW, COL);//判断输赢if (ret != 'C')//如果输出的不是c,就是不是继续,跳出循环{break;}printf("电脑下\n");ComputerSet(arr, ROW, COL);//电脑下PrintBoard(arr, ROW, COL);//打印棋盘ret = is_win(arr, ROW, COL);//判断if (ret != 'C'){break;}}if (ret == '*')//输出人的棋{printf("玩家赢\n");}else if (ret == '#')//输出电脑的棋{printf("电脑赢\n");}else//都不是,即使Q{printf("平局\n");}}

🌍整个代码

最后我们将我们的所有代码像之前的扫雷一样,装在不同的文件中。

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#pragma once
#define ROW  3
#define COL  3
void InitBoard(char arr[ROW][COL], int row, int col);
void PrintBoard(char arr[ROW][COL], int row, int col);
void PersonSet(char arr[ROW][COL], int row, int col);
void ComputerSet(char arr[ROW][COL], int row, int col);
char is_win(char arr[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void meun()
{printf("*************************************************\n");printf("*********************1.exit**********************\n");printf("*********************2.play**********************\n");printf("*************************************************\n");printf("请输入你的选择:");
}
void game()
{char ret;char arr[ROW][COL];InitBoard(arr, ROW, COL);PrintBoard(arr, ROW, COL);while (1){PersonSet(arr, ROW, COL);PrintBoard(arr, ROW, COL);ret = is_win(arr, ROW, COL);if (ret != 'C'){break;}printf("电脑下\n");ComputerSet(arr, ROW, COL);PrintBoard(arr, ROW, COL);ret = is_win(arr, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家赢\n");}else if (ret == '#'){printf("电脑赢\n");}else{printf("平局\n");}}int main()
{int a = 0;do{meun();scanf("%d", &a);switch (a){case 2:game();break;case 1:printf("游戏结束\n");break;default:printf("输入错误,请重新输入\n");break;}} while (a);
}

✍结语

好了今天的分享就到这里了,大家等会可以试着去敲属于自己的三子棋C语言游戏哦!如果大家喜欢小赵的C语言游戏系列,也可以订阅小赵的C语言小游戏系列,如果大家对这个游戏代码有更好的改进完善方案也可以在评论区留言哦,小赵会一一回复的。

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持小赵,如有不足还请指点,小赵及时改正,感谢大家支持!!!

​​​​​​​​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/210067.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用DateFormat、Date、Calendar等相关类,编程实现如下功能

&#xff08;1&#xff09;用户输入2个日期&#xff0c;第一个日期用整数形式输入&#xff0c;把输入的整数设置为日历对象1的年月日的值。第二个日期以字符串形式输入&#xff0c;形如“2022-10-25”&#xff0c;并设置为日历对象2的年月日的值。将2个日期以“xx年xx月xx日”的…

C++12.4

沙发床的多继承 多继承代码实现沙发床沙发床继承于沙发和床 代码&#xff1a; #include <iostream>using namespace std;//封装 沙发 类 class Sofa { private:string sitting;double *size; public://无参构造函数Sofa() {cout << "Sofa::无参构造函数&quo…

接口自动化测试用例

1、接口文档 根据开发、产品的接口文档&#xff0c;以及评审&#xff0c;进行设计接口测试用例&#xff0c;它不像UI测试&#xff0c;有个界面&#xff0c;对于简单的系统&#xff0c;需求文档不提供也能覆盖所有功能&#xff0c;接口测试虽说可以抓包&#xff0c;但抓包无法覆…

STM32串口接收不定长数据(空闲中断+DMA)

玩转 STM32 单片机&#xff0c;肯定离不开串口。串口使用一个称为串行通信协议的协议来管理数据传输&#xff0c;该协议在数据传输期间控制数据流&#xff0c;包括数据位数、波特率、校验位和停止位等。由于串口简单易用&#xff0c;在各种产品交互中都有广泛应用。 但在使用串…

HDFS客户端及API操作实验

实验二 HDFS客户端及API操作 实验目的&#xff1a; 1.掌握HDFS的客户端操作&#xff0c;包括上传文件、下载文件、重命名、查看目录等&#xff1b; 2.掌握HDFS的Java API使用&#xff0c;能够利用Java API实现上传、下载等常用操作&#xff1b; 实验内容&#xff1a; HDF…

深度学习——第3章 Python程序设计语言(3.3 Python数据类型)

3.3 Python数据类型 目录 1. Python数值数据类型 2. Python库的导入和使用 3. Python序列数据类型 4. Python组合数据类型 计算机能处理各种类型的数据&#xff0c;包括数值、文本等&#xff0c;不同的数据属于不同的数据类型&#xff0c;有不同的存储方式&#xff0c;支持…

EM32DX-C2【C#】

1说明&#xff1a; 分布式io&#xff0c;CAN总线&#xff0c;C#上位机二次开发&#xff08;usb转CAN模块&#xff09; 2DI&#xff1a; 公共端是&#xff1a; 0V【GND】 X0~X15&#xff1a;自带24v 寄存器地址&#xff1a;0x6100-01 6100H DI输入寄存器 16-bit &#x…

nginx部署和安装-后端程序多端口访问-后端代理设置

部分补充 查看nginx是否安装http_ssl_module模块 ./nginx -V 看到有 configure arguments: --with-http_ssl_module, 则已安装。 如果没有安装&#xff1a;参考文档 nginx官网地址&#xff1a;nginx: download 这里下载nginx-1.18.0稳定版tar.gz 下载后&#xff0c;利用…

2023年多元统计分析期末试题

一、简答题 1、试述距离判别法、Fisher判别法和贝叶斯判别法的异同。 二、 2、设 X {X} X~ N 2 {N_2} N2​(μ&#xff0c;Σ)&#xff0c;其中 X {X} X ~ ( X 1 {X_1} X1​, X 2 {X_2} X2​, X 3 {X_3} X3​)&#xff0c;μ ( μ 1 {μ_1} μ1​&#xff0c; μ 2 {μ_2} …

长度最小的子数组

长度最小的子数组 描述 : 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 题目…

MySQL表的查询、更新、删除

查询 全列查询 指定列查询 查询字段并添加自定义表达式 自定义表达式重命名 查询指定列并去重 select distinct 列名 from 表名 where条件 查询列数据为null的 null与 (空串)是不同的&#xff01; 附&#xff1a;一般null不参与查询。 查询列数据不为null的 查询某列数据指定…

GPT市场将取代插件商店 openAI已经关闭plugins申请,全部集成到GPTs(Actions)来连接现实世界,可以与物理世界互动了。

Actions使用了plugins的许多核心思想&#xff0c;也增加了新的特性。 ChatGPT的"Actions"与"Plugins"是OpenAI在GPT模型中引入的两种不同的功能扩展机制。这两种机制的目的是增强模型的功能&#xff0c;使其能够处理更多样化的任务和请求。下面是对两者的比…

快手视频如何去掉水印?三个简单好用视频去水印方法

快手视频如何去掉水印&#xff1f;尽管新兴的短视频平台如春笋般涌现&#xff0c;吸引了众多观众在业余时间浏览和分享视频&#xff0c;快手作为当下主流短视频之一&#xff0c;许多自媒体创作者也常常会下载一些热门的视频素材进行二次编辑。然而&#xff0c;他们都可能会面临…

Apache solr XXE 漏洞(CVE-2017-12629)

任务一&#xff1a; 复现环境中的漏洞 任务二&#xff1a; 利用XXE漏洞发送HTTP请求&#xff0c;在VPS服务器端接受请求&#xff0c;或收到DNS记录 任务三&#xff1a; 利用XXE漏洞读取本地的/etc/passwd文件 1.搭建环境 2.开始看wp的时候没有看懂为什么是core&#xff0c;然…

SaToken利用Redis做持久化

官网解释 官网解释 教程 引入依赖 <!-- 提供Redis连接池 --> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId> </dependency><!-- Sa-Token 整合 Redis &#xff08;使用 jdk 默认序…

2023年亚太杯APMCM数学建模大赛B题玻璃温室小气候调控

2023年亚太杯APMCM数学建模大赛 B题 玻璃温室小气候调控 原题再现 温室作物的产量受各种气候因素的影响&#xff0c;包括温度、湿度和风速[1]。其中&#xff0c;适宜的温度和风速对植物生长至关重要[2]。为了调节玻璃温室内的温度、风速等气候因素&#xff0c;在温室设计中常…

能源企业管理ERP系统都有哪些?可以帮助企业解决哪些难点

能源企业在不同的发展阶段面对的经营压力以及遇到的管理问题各异&#xff0c;随着部分产品结构的复杂化&#xff0c;日常经营管理工作也愈加繁琐。 有些能源企业内部存在信息传递不畅、经营数据统计不及时、部门协作效率低、多仓库和多平台数据不统一等情况&#xff0c;而这些…

【WebSocket】通信协议基于 node 的简单实践和心跳机制和断线重连的实现

前后端 WebSocket 连接 阮一峰大佬 WebSocket 技术博客 H5 中提供的 WebSocket 协议是基于 TCP 的全双工传输协议。它属于应用层协议&#xff0c;并复用 HTTP 的握手通道。它只需要一次握手就可以创建持久性的连接。 那么什么是全双工呢&#xff1f; 全双工是计算机网络中的…

Windows中使用ScreenToGif进行Gif录屏

文章目录 一、前言二、下载ScreenToGif2.1、官网2.2、Github下载 三、使用ScreenToGif3.1、安装打开3.2、录像机3.3、录屏3.4、保存Gif动图3.5、保存完成 四、最后 一、前言 之前写文章时需要录制网页操作效果&#xff0c;使用的是谷歌的扩展插件【镀铬捕获】&#xff0c;后面…

前端mp3文件转wav文件的实现

一、音频文件格式转换 1&#xff09;安装fluent-ffmpeg和ffmpeg插件 npm install fluent-ffmpeg; npm install ffmpeg;2&#xff09;mp3转wav test.js文件&#xff1a; const ffmpeg require(fluent-ffmpeg);ffmpeg(./test.mp3) .format(wav) .audioBitrate(16k) .audioFre…