C语言之三子棋小游戏的应用
文章目录
- 前言
- 一、前期准备
- 模块化设计
- 二、框架搭建
- 三、游戏实现
- 打印棋盘
- 代码优化
- 玩家下棋
- 电脑下棋
- 判断输赢
- 四、结束
前言
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。
本篇博客就来进行讲解这个三子棋小游戏,跟着我来一起看把!(本文使用的编译器是VS2022)
一、前期准备
模块化设计
在写三子棋的时候,我们先要了解一下什么事模块化设计:
模块化程序设计是指在进行程序设计时将一个大程序按照功能划分为若干小程序模块,每个小程序模块完成一个确定的功能,并在这些模块之间建立必要的联系,通过模块的互相协作完成整个功能的程序设计方法
- 上面是百度百科的介绍,可能有同学看不懂,简单来说就是份文件写
- 在我们写一些程序的时候就会遇到一个.c文件里写很多,会显得杂乱,可读性会变的非常差,那么我们就要使用份文件来写代码,这样就会变得条理清晰,可读性强,这样是一种良好的编程习惯,那么怎么做呢?接下来看~~
- 建立一个
game.h头文件:存储行列信息,包含函数库,对函数进行声明 - 建立一个
game.c文件:实现游戏中的函数 - 建立一个
test.c文件:实现函数主体逻辑,在书写时可用此函数进行测试 - 将
game.c和test.c文件中包含#include"game.h"

二、框架搭建
创建好文件后,将game.c和test.c引入game.h,头文件的包含和函数的声明就在这里面

游戏界面:

game.h
- 这里定义一个三行三列,并且初始化,当想要变成n行m列的只需要改一下这里define定义的就行
//行
#define ROW 3
//列
#define COL 3
//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);
- 玩家输入选择,switch处理对应逻辑,输入值顺便还可以作为循环结束的条件。
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"void menu()
{printf("\n");printf("**************************\n");printf("***** 1.play ******\n");printf("***** 0.exit ******\n");printf("**************************\n");printf("\n");
}void game()
{printf("玩游戏\n");
}int main()
{int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏!\n");break;default:printf("选择错误,请重新选择!\n");break;}} while (input);return 0;
}
game.h
- 在这里把需要引入的头文件写入
#pragma once
#include<stdio.h>
- 可以看到,游戏已经正常运行了,但是里面的game函数还没有实现,接下来就让我们继续往下看(完成一部分功能就运行一下看看,及时发现BUG,越早发现越容易找到BUG)
三、游戏实现
创建棋盘&初始化棋盘
game.h
void InitBoard(char board[ROW][COL],int row,int col);
test.c
void game()
{//创建棋盘char board[ROW][COL];//初始化棋盘InitBoard(board, ROW, COL);
}
game.c
- 初始化棋盘,将数组所有元素初始化为
空格
void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';//初始化为空格}}
}
打印棋盘
game.h
打印棋盘
void DisplayBoard(char board[ROW][COL], int row,int col);
test.c
DisplayBoard(board, ROW, COL);
game.c
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;for (i = 0; i < row; i++){printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);if (i < row - 1)printf("---|---|---\n");}
}

如果我们要修改棋盘大小,行是循环出来的,但是列就写死了
代码优化
- 首先打印
空格 空格和|,要打印row行col列,这里要注意的是当col列为col-1时才打印,也就是说打印了2列| - 打印
---也是一样的,同理
game.c
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)printf("|");}printf("\n");if (i < row - 1){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}printf("\n");}}
}
我们将ROW和COL修改成10也是可以打印的

玩家下棋
game.h
void PlayMove(char board[ROW][COL], int row, int col);
test.c
//玩家下棋
while (1)
{PlayMove(board, ROW, COL);DisplayBoard(board, ROW, COL);
}
- 玩家下棋是不是要输入坐标,那么我们就先定义x和y,首先判断玩家输入的xy坐标合法,在棋盘范围内,如果合法,就继续,否则提示
- 在玩家下棋时,需要判断是否要下的位置为
空格,是空格说明当前位置没有棋子,不是空格说明当前位置已被下棋,就提示重新下棋
game.c
void PlayMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋\n");while (1){printf("请输入坐标:>");scanf("%d%d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else {printf("该坐标被占用,请输入其他坐标\n");}}else {printf("坐标非法,请重新输入\n");}}
}
电脑下棋
- 电脑下棋要进行
game.h
#include<time.h>
#include<stdlib.h>
void ComputerMove(char board[ROW][COL], int row, int col);
test.c
在main函数里,调用srand
srand((unsigned int)time(NULL));
game函数
while (1)
{//玩家下棋PlayMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//电脑随机下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);
}
game.c
- 电脑下棋也是同理,调用rand函数随机生成一个数
- 检测要下棋的位置是否为空格,是空格才可以下,不是空格重新生成一个随机数,重新下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑下棋\n");int x = 0;int y = 0;x = rand() % row;y = rand() % col;while (1){if (board[x][y] == ' '){board[x][y] = '#';break;}}
}
这个时候就可以正常下棋了,但是:没有判断输赢,下完了也不会结束,而是死循环
判断输赢
判断输赢有四种状态
- 玩家赢
- 电脑赢
- 平局
- 游戏继续
玩家赢返回
*
电脑赢返回#
平局返回Q
游戏继续返回C
game.h
char IsWin(char board[ROW][COL], int row, int col);
- 这里判断输赢的时候首先玩家下棋,进行判断有没有输赢,然后电脑下棋,如果有一方输赢了,就进行返回
test.c
char ret = 0;
while (1)
{//玩家下棋PlayMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//判断输赢ret = IsWin(board,ROW,COL);if (ret != 'C'){break;}//电脑随机下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);ret = IsWin(board, ROW, COL);if (ret != 'C'){break;}
}
if (ret == '*')
{printf("玩家赢\n");
}
else if (ret == '#')
{printf("电脑赢\n");
}
else
{pprintf("平局\n");
}
- 这里是进行判断棋盘输赢的逻辑
game.c
int Is_Full(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0; // 棋盘没满}}}return 1; // 棋盘满了
}char IsWin(char board[ROW][COL], int row, int col)
{int i = 0;/* 判断三行 */for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}/* 判断三列 */for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' '){return board[1][i];}}/* 判断对角线 */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];}/* 判断平局 *///如果棋盘满了返回1, 不满返回0if (Is_Full(board, row, col)){return 'Q';}/* 继续 */return 'C';
}
四、结束
最后代码还是可以优化的,比如判断输赢这里是写死了,只能判断三行三列斜线,如果是多行就不能了,还有让电脑下棋智能一点,能判断玩家下棋的位置再进行下棋,这样更有可玩性!
好了,本文就到这里结束了,下一篇是扫雷小游戏!
相关文章:
C语言之三子棋小游戏的应用
文章目录 前言一、前期准备模块化设计 二、框架搭建三、游戏实现打印棋盘代码优化玩家下棋电脑下棋判断输赢 四、结束 前言 三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子&#…...
优雅处理并发:Java CompletableFuture最佳实践
第1章:引言 大家好,我是小黑,今天,小黑要和大家聊聊CompletableFuture,这个Java 8引入的强大工具。 在Java传统的Future模式里,咱们都知道,一旦开始了一个异步操作,就只能等它结束…...
熟悉HDFS常用操作
1. 利用Hadoop提供的Shell命令完成下列任务 (1)向HDFS中上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件。 #检查文件是否存在./bin/hdfs dfs -test -e text.txt echo $? #结果是1 代表已存在 #根据结果判断出文件已存…...
Adobe XD是什么?探索这款创新的用户体验设计工具
Adobexd是一种基于矢量的设计工具,主要用于设计移动和Web应用程序的用户界面(UI)。与Photoshop或ilustrator等其他Adobe产品相比,它相当轻。对于对快速设计和原型迭代感兴趣的界面设计师来说,轻量级并不是一件坏事。 在早期,Adob…...
java常用应用程序编程接口(API)——ArrayList概述及使用案例
前言: 学习了ArrayList,整理下ArrayList的常用功能及基本案例。打好基础,daydayup! 如果需要了解API是什么并如何使用,可以看这篇文章。 java常用应用程序编程接口(API)——String概述及使用案…...
2024年了,Layui再战三年有问题不?
v2.9.3 2023-12-31 2023 收官。 form 优化 input 组件圆角时后缀存在方框的问题 #1467 bxjt123优化 select 搜索面板打开逻辑,以适配文字直接粘贴触发搜索的情况 #1498 Sight-wcgtable 修复非常规列设置 field 表头选项时,导出 excel 出现合计行错位的…...
消息队列-RocketMQ-概览与搭建
RocketMQ 领域模型 RockeMQ整体结构预览 RocketMQ 中的一些概念 Topic:主题,可以理解为类别、分类的概念 MessageQueue:消息队列,存储数据的一个容器(队列索引数据),默认每个 Topic 下有 4 个队…...
Vue3技术解析(小册子)
随着 Vue 3 正式版本的发布,未来 Vue 3 将会成为前端的主流框架,这个毋庸置疑。Vue 3 在使用方面会兼容部分 Vue 2.x 的特性,比如 options API。 所以,究竟是要先学习 Vue 2 打好基础,还是直接学习 Vue 3 呢ÿ…...
即将消失的五种编程语言?
1. Ruby Ruby 在 1999 年发布后立即受到程序员们的热捧,它能够快速构建应用程序的特性给程序员留下了非常深刻的印象。紧随其后,备受欢迎的 Ruby on Rails 框架于 2004 年发布,由于 Ruby 和 Rails 这两个名称在当时几乎成为了同义词…...
c++学习:STL库(框架)+字符串模板类string+vector容器+list链表
目录 stl库 常用组件包括 字符串库 字符串模板类string 头文件 最常用的字符串模板类 字符串类型 模板原型 模板的成员数据类型 模板成员函数 有些函数会有重载,可以去下面网址查看std::basic_string - cppreference.comhttps://zh.cppreference.com/w/cp…...
2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷④
2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷4 目录 需要竞赛软件包环境以及备赛资源可私信博主!!! 2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷4 模块一 …...
使用Scikit Learn 进行识别手写数字
使用Scikit Learn 进行识别手写数字 作者:i阿极 作者简介:数据分析领域优质创作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏…...
GB/T 15036-2018 实木地板检测
实木地板是指未经拼接、覆贴的单块木材直接加工而成的地板,实木地板具有脚感舒适,环保等优良的性能,在家庭装修中被广泛使用,尤其是在国内很受欢迎。 GB/T 15036-2018 实木地板测试介绍: 测试项目 测试方法 外观 G…...
基于ElementUI封装的下拉树选择可搜索单选多选清空功能
效果: 组件代码 /*** 树形下拉选择组件,下拉框展示树形结构,提供选择某节点功能,方便其他模块调用* author wy* date 2024-01-03 * 调用示例:* <tree-select * :height"400" // 下拉框中树形高度* …...
计算机网络-各层协议
大家在搞嵌入式开发的时候基本都了解过七层网络协议、五层网络协议、四层网络协议,那么今天让我们更加的深入了解一下: 历史发展介绍 OSI七层模型由ISO国际标准化组织提出的通信标准。TCP/IP四层模型是OSI七层模型的简化版,OSI在它被官方完…...
LeetCode 84:柱状图中的最大矩形
一、题目描述 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heights [2,1,5,6,2,3] 输出:10 解释:…...
老生重谈:大模型的「幻觉」问题
一、什么是大模型「幻觉」 大模型的幻觉问题通常指的是模型在处理输入时可能会产生一些看似合理但实际上是错误的输出,这可能是因为模型在训练时过度拟合了训练数据,导致对噪声或特定样本的过度敏感。 "大数据幻觉"指的是在处理大规模数据时…...
golang实现skiplist 跳表
跳表 package mainimport ("errors""math""math/rand" )func main() {// 双向链表///**先理解查找过程Level 3: 1 6Level 2: 1 3 6Level 1: 1 2 3 4 6比如 查找2 ; 从高层往下找;如果查找的值比当前值小 说明没有可查找的值2比1大 往当前…...
尝试OmniverseFarm的最基础操作
目标 尝试OmniverseFarm的最基础操作。本地机器作为Queue和Agent,同时在本地提交任务。 主要参考了官方文档: Farm Queue — Omniverse Farm latest documentation Farm Agent — Omniverse Farm latest documentation Farm Examples — Omniverse Far…...
第28关 k8s监控实战之Prometheus(二)
------> 课程视频同步分享在今日头条和B站 大家好,我是博哥爱运维。 这节课我们用prometheus-operator来安装整套prometheus服务 https://github.com/prometheus-operator/kube-prometheus/releases 开始安装 1. 解压下载的代码包 wget https://github.com/…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
