【C语言】数组的应用:三子棋游戏

由于代码较长,为了增加可读性,我们把代码分别写到game.h,game.c,test.c,里面,其中game.h用来声明函数,实现函数功能的代码在game.c,测试游戏的代码在test.c

为了方便后续的更改,代码使用了宏定义,并没有把棋盘大小写死,这样只要后续要是想要写五子棋甚至n子棋,只需要更改宏定义的数值即可。

下面是game.h中对于所有函数的声明

下面是test.c

仍然是采用的do..while()循环加上switch语句,这与我们前面写过的猜数字游戏类似,上来先打印一个菜单,让输入1或0决定开始游戏还是退出游戏,如果玩一次不过瘾还可以连续玩,直到输入0退出游戏

首先程序运行起来之后不管三七二十一都先打印一个菜单,供玩家选择,当玩家输入1才开始游戏,这时候先初始化棋盘,然后把棋盘打印出来,屏幕上就会呈现一个空棋盘,然后玩家和电脑就可以开始下棋了,由于玩家和电脑都要走很多步才能结束游戏,因此显然是一个循环,循环结束的条件就是有没有一方获得胜利或者平局。

先来看初始化棋盘的函数

我们所谓的棋盘其实就是一个三行三列的二维数组,创建并把这个二维数组中的所有元素均初始化为空格。

再来看打印棋盘的函数

前面我们已经把二维数组的所有内容均初始化为了0,如果我们直接打印,其实是什么也看不到,这样的棋盘对于玩家来讲是非常不友好的,因此我们要打印一个更优美的棋盘,比如这样的

这其实是由一些符号拼起来的一个像棋盘的图案,就是先来一行三空格一竖杠,再来一行三个_一个竖杠,重复多次即可,而且最后一行是不需要竖杠的,最后一列也是不需要___|的,然而这样我们发现最后一行永远都是三空格一竖杠,在形状上显得略微不对称,就像这样

因此我们最后又人为的打印了一行三空格一竖杠,让图形看着更加对称

玩家下棋的函数

由于数组下标是从0开始的,我们要想在第一行第一列下棋1,应该输入坐标是0 0,这显然不符合大众的理解,大众并不知道数组下标是从零开始的,因此我们这里让打印的是arr[x-1][y-1],要考虑到以下几种情况:首先玩家因为我们的棋盘只有三行三列,玩家如果输入一个坐标在第五行,显然是不行的,这时候我们让玩家重新输入,再者就是玩家输入的坐标可能已经被占用了,这时候就提示玩家坐标已被占用,请重新输入,如果上述两种问题均不存在,则在对应的坐标位置放上一个*,当然我们走完之后要紧接着调用打印棋盘的函数打印一下,效果如图:

电脑下棋的函数

为了方便,我们就让电脑随机下棋即可,电脑下棋我们通过模上row和模上col就能产生0~row-1,与0~col-1,有了这样的限制,电脑就不会产生非法坐标了,生成随机数的方式就是rand函数,在调用rand函数之前要调用srand函数,这是rand函数的语法,srand函数用于设置时间戳,且只需要在主函数中调用一次即可,这里有一个设置时间戳的固定方法就是srand((unsigned)time(NULL)),希望读着能够记住这个写法。在以后需要产生随机数的时候均可以直接套用。

电脑下棋虽然不会有非法坐标,但是也会出现坐标已经被占用的情况,这时候我们就让电脑悄悄地再下一次即可。

接下来是判断棋盘是否已经满了的函数

这个逻辑还是非常简单的,我们只要遍历一遍此时的二维数组,看看是否有空格即可,如果一个空格都没有,当然就满了。

最后是判断玩家输赢的函数

假设玩家赢返回*,电脑赢返回#,没有结束返回C,平局返回Q

这样写的好处就是有三点连成一线的时候直接返回其中任意一个坐标处的内容即可,玩家赢,说明有三个*连成了一条线,我们返回其中任意一个就是*,这就与我们前面让玩家赢返回*的逻辑对应上了,电脑赢同理,判断是否平局其实就是看看棋盘是不是已经满了,利用前面的isfull函数即可。

自此所有的函数都写完了,一个简易的三子棋游戏就完成了。效果如图

只要我们不输入0,在一局下完之后会紧接着再打印菜单让玩家选择。

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

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

相关文章

ThreadLocal学习笔记

ThreadLocal类图 ThreadLocal/InheritableThreadLocal/ \TransmittableThreadLocal(阿里巴巴) TransmissibleThreadLocal(阿里巴巴)ThreadLocal 这是Thread类的局部变量,每个线程私有。 它主要用于解决多线程中的数据共享问题,保…

k8s 版本发布与回滚

一、实验环境准备: kubectl get pods -o wide kubectl get nodes -o wide kubectl get svc 准备两个nginx镜像,版本号一个是V3,一个是V4 二、准备一个nginx.yaml文件 apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploylab…

翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二 1. 将任何静态图表转换为动态数据可视化 ChatGPT Vision 不仅可以将涂鸦变成功能齐全的 Streamlit 应用程序,还…

SpringBoot整合nacos的入门Demo

Nacos介绍 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速…

操作系统(6)----线程相关

目录 1.线程与进程的关系 2.线程的属性 3.线程的实现方式 用户级线程 内核级线程 多线程模型 一对一模型: 多对一模型: 多对多模型: 4.线程的状态和转换 5.线程的组织与控制 1.线程与进程的关系 可以把线程理解为“轻量级进程”。线程是一个…

大创项目推荐 题目:基于卷积神经网络的手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…

【Spring实战】31 Spring Boot3 集成 Gateway 微服务网关

文章目录 1. 定义2. 功能3. 示例代码1) 创建一个业务服务2)创建一个网关服务3)启动服务4)验证 4. 代码参考结语 1. 定义 Spring Cloud Gateway 是一个基于 Spring Framework 的开源网关服务,用于构建微服务架构中的 API 网关。它…

C51 单片机学习(一):基础外设

参考 51单片机入门教程 1. 单片机简介 1.1 定义 单片机(Micro Controller Unit,简称 MCU) 内部集成了 CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能单片机的任务是信息采集(依靠传感器)、处…

休息日的思考与额外题——链表

文章目录 前言链表知识点 一、 92. 反转链表 II二、21. 合并两个有序链表总结 前言 一个本硕双非的小菜鸡,备战24年秋招,计划二刷完卡子哥的刷题计划,加油! 二刷决定精刷了,于是参加了卡子哥的刷题班,训练…

富文本编辑器CKEditor4简单使用-01

富文本编辑器CKEditor4简单使用-01 1. 快速体验入门1.1 通过从 CDN 加载 CKEditor 来快速体验1.2 从官方网站下载软件包1.2.1 官网下载1.2.2 解压、简单使用(自带index页面示例)1.2.3 将 CKEditor 4 添加到自己的页面1.2.3.1 目录结构1.2.3.2 效果1.2.3.…

TensorFlow2实战-系列教程6:迁移学习实战

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、迁移学习 用已经训练好模型的权重参数当做自己任务的模型权重初始化一般全连接层需…

【机器学习】工程实践问题概述

机器学习实际应用时的工程问题与面临的挑战 一、实现细节问题 1.1 训练样本 训练样本与标注对各类机器学习算法和模型的精度影响 训练样本的选择对各类机器学习算法和模型的影响 训练样本的优化 如何进行数据增强? 如何进行数据清洗? 样本的标注对各类机…

数据结构(二)------单链表

制作不易,三连支持一下呗!!! 文章目录 前言一.什么是链表二.链表的分类三.单链表的实现总结 前言 上一节,我们介绍了顺序表的实现与一些经典算法。 但是顺序表这个数据结构依然有不少缺陷: 1.顺序表指定…

导航页配置服务Dashy本地部署并实现公网远程访问

文章目录 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航…

基于springboot宠物领养系统

摘要 随着社会的不断发展和人们生活水平的提高,宠物在家庭中的地位逐渐上升,宠物领养成为一种流行的社会现象。为了更好地管理和促进宠物领养的过程,本文基于Spring Boot框架设计和实现了一套宠物领养系统。该系统以用户友好的界面为特点&…

时序分析中的去趋势化方法

时序分析中的去趋势化方法 时序分析是研究随时间变化的数据模式的一门学科。在时序数据中,趋势是一种随着时间推移而呈现的长期变化趋势,去趋势化是为了消除或减弱这种趋势,使数据更具平稳性。本文将简单介绍时序分析中常用的去趋势化方法&a…

跟着cherno手搓游戏引擎【13】着色器(shader)

创建着色器类&#xff1a; shader.h:初始化、绑定和解绑方法&#xff1a; #pragma once #include <string> namespace YOTO {class Shader {public:Shader(const std::string& vertexSrc, const std::string& fragmentSrc);~Shader();void Bind()const;void Un…

怎样自行搭建幻兽帕鲁游戏联机服务器?

幻兽帕鲁是一款深受玩家喜爱的多人在线游戏&#xff0c;为了获取更好的游戏体验&#xff0c;许多玩家希望能够自行搭建幻兽帕鲁游戏联机服务器&#xff0c;本文将指导大家如何自行搭建幻兽帕鲁游戏联机服务器。 自行搭建幻兽帕鲁游戏联机服务器&#xff0c;阿里云是一个不错的选…

结构体的增删查改

结构体&#xff0c;是为了解决生活中的一些不方便利用c语言自带数据类型来表示的问题。例如表示一个学生&#xff0c;那么学生这个个体假如用c语言自带数据类型怎么表示呢。可以使用名字&#xff0c;也就是字符数组&#xff1b;也可以使用学号&#xff0c;也就是int类型。但是这…

iOS 面试 Swift基础题

一、Swift 存储属性和计算属性比较&#xff1a; 存储型属性:用于存储一个常量或者变量 计算型属性: 计算性属性不直接存储值,而是用 get / set 来取值 和 赋值,可以操作其他属性的变化. 计算属性可以用于类、结构体和枚举&#xff0c;存储属性只能用于类和结构体。存储属性可…