初阶c语言:实战项目三子棋
前言
大家已经和博主学习有一段时间了,今天讲一个有趣的实战项目——三子棋
目录
前言
制作菜单
构建游戏选择框架
实现游戏功能
模块化编程
初始化棋盘
打印棋盘
玩家下棋
电脑下棋
时间戳:推荐一篇
C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客
判断输赢
游戏逻辑实现
制作菜单
在玩游戏时,我们在进入游戏都会有菜单选项,选择开始游戏,推出游戏等这些指令,说到选择,那么我们可以依据我们所学的循环和分支语句来先完成基本框架的设计。
首先我们进入游戏都是先显示选项,做出选择,并且在玩游戏时玩一局,还想玩怎么办(想一想我们前边的知识哪种结构符合先进入游戏出现菜单再循环这一需求)那肯定是do…while的循环结构更符合,那么我们就先使用函数来打印输出一个菜单选项
void menu()
{printf("*****************************\n");printf("*****************************\n");printf("**********1.play^************\n");printf("**********0.exit^************\n");//菜单printf("*****************************\n");printf("*****************************\n");
}int main()
{int a = 0;do{menu();printf("请选择:");scanf("%d",&a);}while();
return 0;
}
构建游戏选择框架
游戏菜单已在屏幕上显示完成,现在需要完成选择,并且在玩游戏时玩一局,还想玩怎么办。
这时候需要应用博主之前阐述的switch语句来实现:
int main()
{int input = 0;do{menu();printf("PLEASE SELECT:");scanf("%d", &input);switch(input){case 1:game(); //以上为界面的选择break;case 0:printf("Exit\n");break;default:printf("ERRO,PLEASE CHOOSE AGAIN\n");break;}} while (input);//while循环可以利用0为假,其余为来实现用户可反复选择
//直到选到合适为止return 0;
}
实现游戏功能
模块化编程
这里博主引入一个概念:模块化编程。方便引用,不会显得头重脚轻,而且转为静态库不易被盗用。这里需要创建三个文件:test.c game.c game.h
test.c:是用来实现游戏逻辑 game.c:用来实现游戏功能的函数 game.h:用来申明游戏功能函数(可引用)
传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。
模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等。
传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。
模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!
总的来说就是:当你代码比较多的时候,就可以采用模块化编程来完成这个程序。
三子棋,我们需要在棋盘中输入要下的位置,相当于是一个三乘三的数组(这里我们就用到了二维数组的知识),那么游戏开始前需要我们先对棋盘初始化(使数组中的元素都为空格),那么就是数组初始化赋值(只用循环遍历每一个元素并赋予空格就ok了)。
注意:这里设置函数的时候因为用到二维数组,所以函数的形参为数组名,行 ,列
void initboard(char board[row][col], int hang, int lie) {int i = 0;int j = 0;for (i = 0; i < hang; i++){for (j = 0; j <lie; j++){board[i][j] =' ';} printf("\n");} }
打印棋盘
将置空的二维数组用线隔开
void displayboard(char board[row][col], int hang, int lie) //可以随意控制棋盘大小
{int i = 0;for (i = 0; i <hang; i++){int j = 0;for (j = 0; j <lie; j++){printf(" %c ",board[i][j]);if (j < lie - 1)//为了不让最后一行打印‘|’printf("|");}printf("\n");if (i < hang - 1){int j = 0;for (j = 0; j < lie; j++){printf("---");if (j < lie - 1)printf("|");}printf("\n");}}
}
效果图
玩家下棋
玩家下棋的话使用*标志,利用坐标来将“空格”替换
void player(board[row][col],int hang,int lie)
{int x = 0;int y = 0;
printf("玩家开始下棋");
scanf("%d %d",&a,&b);
if(x>=1&&x<=3&&y>=1&&y<=3)
{ if(board[x-1][y-1]==' '){board[x-1][y-1]='*';}else
{printf("坐标已经被占用,请重新选择");}else
{printf("坐标非法请重新输入");}}
}
玩家下完棋需要有对立面,也就是我们的电脑
电脑下棋
时间戳:推荐一篇
C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客
void computer(char board[row][col], int hang, int lie)
{printf("电脑下棋\n");int x = 0;int y = 0;while(1){ x = rand() % hang;//0-2//模取余数不会超过这个数y = rand() % lie;if (board[x][y] ==' '){board[x][y] = '#';break;}}
}
判断输赢
输赢情况分析:行三连,列三连,对角线俩条。
char panduan(char board[row][col], int hang, int lie)
{int i = 0;for (i = 0; i < hang; i++)//行{if(board[i][0]==board[i][1]&&board[i][1]==board[i][2] && board[i][1] != ' '){return board[i][1];//电脑和玩家都可以用这一个判断}}int j = 0;for (j = 0; j< lie; j++)//列
{if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//平局if (isfull(board, hang, lie)){return 'q';//平局 else} return 'c';
}
游戏逻辑实现
创建菜单函数选择 进入游戏 以及 退出游戏。
首先,初始化 棋盘。
然后,再打印棋盘。注意:一定是要先进行 初始化 然后再 打印棋盘。
玩家下棋,并打印出棋盘(玩家输入行、列坐标方式进行落子,'x' = 玩家落子)
判断玩家是否 赢,判断是否 继续游戏。(字符'c'代表 继续游戏、字符'q'代表 游戏平局)
电脑进行落子下棋(随机位置进行落子,'o' = 电脑落子)
判断③种胜负方式!分别是:玩家赢、电脑赢、以及 平局。
然后,再回到步骤①,是否选择 进入游戏 以及 退出游戏。
void game()
{int key = 0;char board[row][col] = { 0 }; //不直接写成数字,利于改变棋盘大小//初始化棋盘的函数initboard(board,row,col);displayboard(board,row,col);while(1){player(board, row, col);key=panduan(board, row, col);if(key!='c'){break;}displayboard(board, row, col); computer(board, row, col);key = panduan(board, row, col);if (key != 'c'){break;}displayboard(board, row, col);} if (key == '*'){printf("玩家胜利\n");}else if(key=='#'){printf("电脑胜利\n");}else if(key=='p'){printf("平局\n");}
}
另外我们还需要将game.c以声明的形式放入game.h中:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>//这个全可以调用
#define row 3
#define col 3
//初始化棋盘
void initboard(char board[row][col], int hang, int lie);
//打印棋盘 难点
void displayboard(char board[row][col], int hang, int lie);
//玩家下棋
void player(char board[row][col], int hang, int lie);
//电脑下棋
void computer(char board[row][col], int hang, int lie);
//判断输赢 玩家赢 电脑赢 平 继续/
char panduan(char board[row][col], int hang, int lie);
int isfull(char board[row][col], int hang, int lie);
之后利用test.c来实现游戏逻辑(在编辑的开始需要加上#include''game.h'')
好了今天的文章到这里,希望对大家有帮助!
相关文章:
初阶c语言:实战项目三子棋
前言 大家已经和博主学习有一段时间了,今天讲一个有趣的实战项目——三子棋 目录 前言 制作菜单 构建游戏选择框架 实现游戏功能 模块化编程 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 时间戳:推荐一篇 C语言生成随机数的方法_c语言随机数_杯浅…...
计网第三章(数据链路层)(三)
一、点对点协议PPP 在第一篇里有提到数据链路层的信道分为两种:点对点信道和广播信道。 PPP协议就属于点对点信道上的协议。 如果对前面数据链路层的三个基本问题了解的比较透彻,那么这一块很多东西都很好理解。 从考试的角度来讲,PPP协议…...
蓝桥杯每日N题 (砝码称重)
大家好 我是寸铁 希望这篇题解对你有用,麻烦动动手指点个赞或关注,感谢您的关注 不清楚蓝桥杯考什么的点点下方👇 考点秘籍 想背纯享模版的伙伴们点点下方👇 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不…...
Opencv 视频的读取与写入
目录 前言 通过路径获取视频内容 获取视频内容 检查是否正确打开 循环播放 完整代码 从摄像头读取视频数据 获取视频设备 其他与直接读取视频一致 完整实例 录制视频 用于创建视频编解码器的四字符码(FourCC) cv2.VideoWriter() 将视频帧…...
LeetCode 833. Find And Replace in String【字符串,哈希表,模拟】1460
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
Cesium轨迹漫游及视角切换
飞行漫游,就是让Camera飞行。Camera有一些方法可以实现位置、视角的调整,比如flyTo,setView方法。但这些方法并不能沿着我们想要的路径调整,在通过插值的方法不停的调用setView,但这样会造成视图卡顿,而且计…...
构建去中心化微服务集群,满足高可用性和高并发需求的实践指南!
随着互联网技术的不断发展,微服务架构已经成为了开发和部署应用程序的一种主流方式。然而,当应用程序需要满足高可用性和高并发需求时,单一中心化的微服务架构可能无法满足性能和可靠性的要求。因此,构建一个去中心化的微服务集群…...
开集输出和开漏输出
首先指明一下以下8中GPIO输入输出模式: GPIO_Mode_AIN 模拟输入; GPIO_Mode_IN_FLOATING 浮空输入; GPIO_Mode_IPD 下拉输入; GPIO_Mode…...
解决内网GitLab 社区版 15.11.13项目拉取失败
问题描述 GitLab 社区版 发布不久,搭建在内网拉取项目报错,可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…...
【MySQL--->表的约束】
文章目录 [TOC](文章目录) 一、表的约束概念二、空属性约束三、default约束四、zerofill约束五、主键约束六、auto_increment(自增长)约束七、唯一键约束八、外键约束 一、表的约束概念 表通过约束可以保证插入数据的合法性,本质是通过技术手段,保证插入数据收约束,保证数据的…...
github中Keyless Google Maps API在网页中显示地图和标记 无需api key
使用Google Maps API在网页中显示地图和标记的示例博客。以下是一个简单的示例: C:\pythoncode\blog\google-map-markers-gh-pages\google-map-markers-gh-pages\index.html 介绍: 在本篇博客中,我们将学习如何使用Google Maps API在网页中…...
ComPDFKit PDF SDK for Windows Crack
ComPDFKit PDF SDK for Windows Crack 添加了在创建文本框时调整默认属性的支持。 增加了对调整PDF大小时调整宽度的支持。 添加了对编辑文本时更多快捷方式的支持。 优化了文本输入,并将字体样式与原始文本相匹配。 在内容编辑器模式下复制和粘贴时优化了UI交互。 …...
React+Typescript 状态管理
好 本文 我们来说说状态管理 也就是我们的 state 我们直接顺便写一个组件 参考代码如下 import * as React from "react";interface IProps {title: string,age: number }interface IState {count:number }export default class hello extends React.Component<I…...
stable diffusion 运行时报错: returned non-zero exit status 1.
运行sh run.sh安装stable diffusion时报错:ImportError: cannot import name builder from google.protobuf.internal (stable-diffusion-webui/venv/lib/python3.8/site-packages/google/protobuf/internal/__init__.py) 原因:python版本过低࿰…...
el-popover弹窗修改三角样式或者位置
el-popover中设置类名 popper-class"filepopver",我这位置是placement"top-start" <el-popover placement"top-start" popper-class"filepopver" class"filename" width"300" trigger"hover&q…...
Linux驱动开发之点亮三盏小灯
头文件 #ifndef __HEAD_H__ #define __HEAD_H__//LED1和LED3的硬件地址 #define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x50000A28 //LED2的硬件地址 #define PHY_LED2_MODER 0x50007000 #define PHY_LED2_ODR 0x50007014 #define…...
【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析
【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析 一、MIPI-DSI 接口介绍二、高通参考硬件原理图分析:ANX7625 桥接芯片方案2.1 高通参考设计:两路 4-Lane DSI 接口2.2 高通参考设计:DSI0 硬件原理图,将 4 Lane DSI数据通过 ANX7625 桥接芯…...
macOS(m1/m2)破解Sublime Text和Navicat16
破解Sublime Text 说明:全程使用的是终端操作 1. 下载Sublime Text,建议使用brew下载 2. 进入到下载的app的文件夹 cd "/Applications/Sublime Text.app/Contents/MacOS/"3. 执行以下操作以确认版本是否匹配 md5 -q sublime_text | grep -i…...
【排排站:探索数据结构中的队列奇象】
本章重点 队列的概念及结构 队列的实现方式 链表方式实现栈接口 队列面试题 一、队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列&#x…...
Mac OS 中JDK 环境(jdk 1.8.0_831)安装配置、环境变量配置及卸载操作
前言: 摊牌了,本来就有点喜新厌旧的我,特意把系统和开发环境都拉到比较高,想试验一下兼容性和某些新特性,探索了一下新大陆,也见识了各种光怪陆离的妖魔鬼怪。 因为要着手云平台项目的重构改版和新系统的架…...
[JAVAee]Tomcat - Servlet
目录 Tomcat Servlet的工作 创建Servlet ①项目 ②依赖 ③目录 ④代码 ⑤打包 ⑥部署 ⑦验证 Servlet的运行原理 Servlet API HttpServlet 方法 处理Get/POST请求 HttpServletRequest 方法 获取请求中的信息 获取GET请求中的参数 获取POST请求中的参数…...
MAC钓鱼并Root权限上线CS并权限维持,以及所有的坑如何解决
本文转载于:https://www.freebuf.com/articles/web/350592.html 作者:文鸯涂鸦智能安全实验室 制作MAC 一、下载工具 首先从github上下载CrossC2。链接:https://github.com/gloxec/CrossC2/releases/tag/v3.1.0。 根据你CS客户端的操作系统选…...
浅谈OCR中的David Shepard
在OCR(Optical Character Recognition,光学字符识别)中,David Shepard是一种早期的OCR技术,也被称为Shepards Method。 David Shepard是该OCR方法的原始作者。这种方法基于边界追踪算法,用于识别印刷体文本…...
draw.io导出矢量图到word报错text is not svg - cannot display
先参考https://blog.csdn.net/a625750076/article/details/126384831 如果不行,可能是转存的问题 解决方法:直接在draw.io上操作 第一步 第二步 然后再word中粘贴,依旧是矢量图哦!...
JVM加强
目录 JVM运行时的数据区(内存结构): 线程独享: 线程共享: 什么时候会内存溢出 JVM有哪些垃圾回收算法 GC如何判断对象可以被回收 典型的垃圾回收器 CMS: G1: 类加载器和双亲委派机制&a…...
解决Oracle中XML插入数据时的空格问题
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
微服务中间件--分布式事务
分布式事务 a.理论基础1) CAP定理2) BASE理论 b.Seata1) XA模式1.a) 实现XA模式 2) AT模式3) TCC模式3.a) 代码实现 4) Saga模式5) 四种模式对比6) TC的异地多机房容灾架构 a.理论基础 1) CAP定理 分布式系统有三个指标: Consistency(一致性ÿ…...
计算机网络(9) --- 数据链路层与MAC帧
计算机网络(8) --- IP与IP协议_哈里沃克的博客-CSDN博客IP与IP协议https://blog.csdn.net/m0_63488627/article/details/132155460?spm1001.2014.3001.5502 目录 1.MAC帧 1.MAC地址 2.MAC帧报头 3.资源碰撞 4.MTU 1.对IP协议的影响 2.对UDP协议…...
【学会动态规划】环绕字符串中唯一的子字符串(25)
目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…...
CNN卷积详解(三)
一、卷积层的计算 4 ∗ * ∗ 4的输入矩阵 I I I 和 3 ∗ * ∗ 3 的卷积核 K K K: 在步长(stride)为 1 时,输出的大小为 ( 4 − 3 1 ) ( 4 − 3 1) 计算公式: ● 输入图片矩阵 I I I 大小: w w w w ww ●…...
江门建设造价信息网站/枣庄网站建设制作
ldd命令用于判断某个可执行的 binary 档案含有什么动态函式库。 参数说明: --version 打印ldd的版本号 -v --verbose 打印所有信息,例如包括符号的版本信息 -d --data-relocs 执行符号重部署,并报告缺少的目标对象(只对ELF格式适用) -r --fun…...
互联在线app开发网站/seo还能赚钱吗
一 安装mysql mysql官网下载mysql的red hat linux安装包 下载地址为:http://dev.mysql.com/downloads/mysql/5.5.html#downloads 下载后的文件为:MySQL-5.5.53-1.el7.x86_64.rpm-bundle.tar 解压 tar 包 :tar -xvf MySQL-5.5.53-1.el7.x86_6…...
wordpress视频无法播放视频教程/北京外包seo公司
一、Kafka名词解释和工作方式1.1:Producer :消息生产者,就是向kafka broker发消息的客户端。1.2:Consumer :消息消费者,向kafka broker取消息的客户端1.3:Topic :可以理解为一个队列。1.4:Consumer Group (…...
公司做网站都咨询哪些问题/百度游戏中心
因为如果函数是一个新概念,那么我之前的评论可能有点难以理解。在我个人认为解决这个问题最好的方法是将相关代码包装在一个对象中。在Python在很大程度上基于对象的概念,可以将对象看作是使用对数据进行操作的函数对数据进行分组。一个对象可以表示一个…...
郑州做网站的公司msgg/如何制作一个自己的网页网站
我正在使用Apache Commons FTPClient上传大文件,但是传输速度只是使用WinSCP通过FTP传输速度的一小部分。如何加快转移速度?public boolean upload(String host, String user, String password, String directory,String sourcePath, String filename) t…...
网站开发平台/seo优化排名软件
用pycharm写python的时候,总会在def function()的那行出现如上问题。 “PEP 8: expected 2 blank lines, found 1” 具体原因就是呢,在声明函数的那一行的上方必须有两行的空行,否则便出现这个情况。 函数的注释可随函数为一体 # coding: u…...