初阶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)安装配置、环境变量配置及卸载操作
前言: 摊牌了,本来就有点喜新厌旧的我,特意把系统和开发环境都拉到比较高,想试验一下兼容性和某些新特性,探索了一下新大陆,也见识了各种光怪陆离的妖魔鬼怪。 因为要着手云平台项目的重构改版和新系统的架…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...
PLC入门【4】基本指令2(SET RST)
04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C),从 文件 - 主画面,“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...
ubuntu系统 | docker+dify+ollama+deepseek搭建本地应用
1、docker 介绍与安装 docker安装:1、Ubuntu系统安装docker_ubuntu docker run-CSDN博客 docker介绍及镜像源配置:2、ubuntu系统docker介绍及镜像源和仓库配置-CSDN博客 docker常用命令:3、ubuntu系统docker常用命令-CSDN博客 docker compose安装:4、docker compose-CS…...
