C语言:三子棋小游戏
简介:
目标很简单:实现一个 三子棋小游戏。三子棋大家都玩过,规则就不提及了。本博文中实现的三子棋在对局中,电脑落子是随机的,不具有智能性,玩家的落子位置使用键盘输入坐标。下面开始详细介绍如何实现一个简单的三子棋游戏。
步骤一:制定框架
想要实现一个小游戏,第一件事就是制定框架,那么制定框架是什么意思?怎么制定框架?
#include"chess.h"
int main()
{int n = 0;do{menu();printf("input:\n");scanf("%d", &n);switch(n){case 1:game();break;case 0:printf("exit\n");break;default:printf("input error,input again:\n");break;}} while(n);return 0;
}
这里的menu函数只是一个打印函数,定义如下:
void menu()
{printf("**************\n");printf("*** 1.play ***\n");printf("*** 0.exit ***\n");printf("**************\n");
}
将main函数写全就是制定了一个完整的框架,只要我们输入1,就会进入game函数(之后实现)进行游戏,输入0就会退出游戏,结束程序,输入其他数会让我们重新输入。整个过程就是这么简单。我们只需要实现了game的过程,整个游戏就制作完成了。
那么game函数怎么实现呢?
步骤二:实现game函数
我们在做一个项目的时候,需要把函数的声明放在头文件里,函数的定义放在源文件里,但是具体情况可以根据个人偏好来,我个人是喜欢把主函数里会用到的函数声明放进头文件里,定义放在源文件里。如果在函数的定义中需要实现另外一个函数,就在另外一个函数的声明和定义就都放在源文件里。
要实现game函数,我们需要先将game的流程想清楚:
我们默认玩家先下棋,玩家输入一个合法坐标,然后电脑在下棋。并且每当玩家或者电脑下棋之后需要判断对局是否结束,如果结束,那么最后落子的一方胜利。另外,在玩家或者电脑下棋之后我们需要将棋盘和棋子打印出来。
void game()
{char pieces[ROW][COL] = { 0 };piecesInit(pieces, ROW, COL);board(pieces, ROW, COL);while (1){system("cls");board(pieces, ROW, COL);printf("player move!\n");playerMove(pieces, ROW, COL);system("cls");board(pieces,ROW,COL);if (judge(pieces, ROW, COL)){printf("you win\n");break;}printf("computer move!\n");computerMove(pieces, ROW, COL);Sleep(1000);system("cls");board(pieces, ROW, COL);if (judge(pieces, ROW, COL)){printf("you lose\n");break;}}
}
pieces二维数组是用来储存棋子位置信息的,玩家的棋子是星号,电脑的棋子是井号
下面对game函数中用到的函数进行解释:
piecesInit:将pieces初始化,使得每一个元素都是空格,这样初始状态就不会打印出棋子
board:传入pieces数组,将棋盘和棋子一并打印
playerMove:玩家下棋,将pieces中的一个空格元素变为星号
computerMoe:电脑下棋,将pieces中的一个空格元素变为井号
judge:返回值是int,如果对局结束了就返回1,未结束返回0
这样整个game的流程就形成了
步骤三:实现game函数中的各个函数
void board(char pieces[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){printf(" %c | %c | %c \n",pieces[i][0],pieces[i][1],pieces[i][2]);if (i < row - 1){printf("---|---|---\n");}}
}//如果不理解,可以在自己的电脑上把棋盘敲出来,就会明白board函数的原理,不敲出来不可能搞明白
void playerMove(char pieces[ROW][COL],int row,int col)
{int x = 0;int y = 0;while (1){printf("x:\n");scanf("%d", &x);printf("y:\n");scanf("%d", &y);x--;//用户输入的起始位置是1,而数组下标起始位置是0y--;if (x < 0 || x>2 || y < 0 || y>2 || pieces[x][y] != ' ')//判断是否非法printf("error,again\n");elsebreak;//正确输入,退出循环}pieces[x][y] = '*';
}
void computerMove(char pieces[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){x = rand() % 3;//取0到2的一个数y = rand() % 3;if (x >= 0 && x <= 2 && y >= 0 && y <= 2 && pieces[x][y] == ' ')//如果位置合法{pieces[x][y] = '#';break;}}
}
int judge(char pieces[ROW][COL], int row, int col)
{//判断是否有一行三个棋子一样for (int i = 0; i < row; i++){int sum = pieces[i][0] + pieces[i][1] + pieces[i][2];if (sum == 3 * '*' || sum == 3 * '#')return 1;}//判断是否有一列三个棋子一样for (int j = 0; j < col; j++){int sum = pieces[0][j] + pieces[1][j] + pieces[2][j];if (sum == 3 * '*' || sum == 3 * '#')return 1;}//判断两个对角线是否有三个棋子一样int sum1 = pieces[0][0] + pieces[1][1] + pieces[2][2];int sum2 = pieces[0][2] + pieces[1][1] + pieces[2][0];if (sum1 == 3 * '*' || sum1 == 3 * '#' || sum2 == 3 * '*' || sum2 == 3 * '#')return 1;return 0;
}
这样就实现了一个简单的三子棋,看看效果如何:
相关文章:

C语言:三子棋小游戏
简介: 目标很简单:实现一个 三子棋小游戏。三子棋大家都玩过,规则就不提及了。本博文中实现的三子棋在对局中,电脑落子是随机的,不具有智能性,玩家的落子位置使用键盘输入坐标。下面开始详细介绍如何实现一…...
JAVA - PO DTO 生成器
PO DTO 生成器 假设你是一个Java 高级程序员,我会提供一些信息,你需要帮我自动生成Java的PO、DTO 对象。 这些信息有着固定的形式,第一行是对象的类名,其后的每一行都是该对象的属性(简称“属性”)。 对于我属性,格式…...
tcpdump
TCPDump是一个用于抓取网络数据包的命令行工具。它可以帮助网络管理员和开发人员分析网络流量、故障排除以及安全问题。下面是一些TCPDump的详细用法: 基本用法: 监听指定网络接口:tcpdump -i eth0通过IP地址过滤:tcpdump host 19…...

数据通信——传输层TCP(可靠传输原理的ARQ)
引言 上一篇讲述了停止等待协议的工作流程,在最后提到了ARQ自动请求重传机制。接下来,我们就接着上一篇的篇幅,讲一下ARQ这个机制 还是这个图来镇楼 ARQ是什么? 发送端对出错的数据帧进行重传是自动进行的,因而这种…...

Compose - 交互组合项
按钮 Button OutLinedButton带外边框、TextButton只是文字、IconButton只是图标形状。 Button(onClick { }, //点击回调modifier Modifier,enabled true, //启用或禁用interactionSource MutableInteractionSource(),elevation ButtonDefaults.elevatedButtonElevation( /…...

【发版公告】Virbox Protector 3.1.3.19051 发版- elf 文件支持导入表保护
深盾安全-软件保护工具 Virbox Protector 3 ( 3.1.3.19051)迎来了版本升级.本次升级支持了 elf 文件导入表保护。 以下是本次 Virbox Protector 发版的主要功能: 新功能 1. ELF格式的程序支持导入表保护(Beta);; 2…...
点云数据做简单的平面的分割 三维场景中有平面,杯子,和其他物体 实现欧式聚类提取 对三维点云组成的场景进行分割
点云分割是根据空间,几何和纹理等特征对点云进行划分,使得同一划分内的点云拥有相似的特征,点云的有效分割往往是许多应用的前提,例如逆向工作,CAD领域对零件的不同扫描表面进行分割,然后才能更好的进行空洞修复曲面重建,特征描述和提取,进而进行基于3D内容的检索,组合…...

C++之std::search应用实例(一百八十九)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

一文详解 requests 库中 json 参数和 data 参数的用法
在requests库当中,requests请求方法,当发送post/put/delete等带有请求体的请求时,有json和data2个参数可选。 众所周知,http请求的请求体格式主要有以下4种: application/json applicaiton/x-www-from-urlencoded mu…...

Django学习笔记-AcApp端授权AcWing一键登录
笔记内容转载自 AcWing 的 Django 框架课讲义,课程链接:AcWing Django 框架课。 AcApp 端使用 AcWing 一键授权登录的流程与之前网页端的流程一样,只有申请授权码这一步有一点细微的差别: 我们在打开 AcApp 应用之后会自动向 AcW…...

如何在小红书进行学习直播
诸神缄默不语-个人CSDN博文目录 因为我是从B站开始的,所以一些直播常识型的东西请见我之前写的如何在B站进行学习直播这一篇。 本篇主要介绍一些小红书之与B站不同之处。 小红书在手机端是可以直接点击“”选择直播的。 文章目录 1. 电脑直播-小红书直播软件2. 电…...

F5服务器负载均衡能力如何?一文了解
但凡知道服务器负载均衡这个名词的,基本都知道 F5,因为负载均衡是 F5 的代表作,换句话来说,负载均衡就是由 F5 发明的。提到F5服务器负载均衡能力如何?不得不关注F5提出的关于安全、网络全面优化的解决方案,…...

Ubuntu18.04安装docker-io
1. 安装docker 1.1 网上一搜,全是更新仓库、下载依赖、添加docker的gpg密钥、添加docker仓库、安装docker-ce的步骤,但是在安装docker-ce时却提示“package "docker-ce" has no installation candidate”,就很迷。 1.2 安装docke…...

代码随想录笔记--栈与队列篇
目录 1--用栈实现队列 2--用队列实现栈 3--有效的括号 4--删除字符串中的所有相邻重复项 5--逆波兰表达式求值 6--滑动窗口的最大值 7--前k个高频元素 1--用栈实现队列 利用两个栈,一个是输入栈,另一个是输出栈; #include <iostrea…...
【力扣】55. 跳跃游戏 <贪心>
【力扣】55. 跳跃游戏 给一个非负整数数组 nums ,最初位于数组的第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1…...

在iPhone 15发布之前,iPhone在智能手机出货量上占据主导地位,这对安卓来说是个坏消息
可以说这是一记重拳,但似乎没有一个有价值的竞争者能与苹果今年迄今为止的智能手机出货量相媲美。 事实上,根据Omdia智能手机型号市场跟踪机构收集的数据,苹果的iPhone占据了前四名。位居榜首的是iPhone 14 Pro Max,2023年上半年…...
题目:2620.计数器
题目来源: leetcode题目,网址:2620. 计数器 - 力扣(LeetCode) 解题思路: 定义两个全局变量,一个判断 n 是否改变,另一个记录上一次出现的数。 解题代码: /*** par…...
【MySQL】MySQL系统变量(system variables)列表(SHOW VARIABLES 的结果例)
文章目录 【MySQL】MySQL系统变量(system variables)列表(SHOW VARIABLES 的结果例)SHOW VARIABLES 的结果例参考 【免责声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和数据库技术(ID:S…...
【多AZ】浅述云计算多az
多AZ(Availability Zone)是云计算中一种重要的容灾和冗余策略,它通过在不同的地理位置或不同的设备上存储数据副本以及网络切换策略,以保证在单个设备或地理位置发生故障时,云加计算集群仍然能够提供服务。 多AZ的特点…...
Element浅尝辄止13:Collapse 折叠面板
通过折叠面板收纳内容区域 1.如何使用? 可同时展开多个面板,面板之间不影响 <el-collapse v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency" name"1">&l…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...