【C语言】三子棋游戏实现代码
目录
1.三子棋代码功能介绍
2.三子棋游戏实现步骤
①打印菜单栏
②判断是否进入三子棋游戏
③三子棋游戏基本函数实现
(1)清空(初始化)棋盘函数实现
(2)打印棋盘函数实现
(3)玩家下棋函数实现
(4)电脑下棋函数实现
(5)判断输赢函数
(6)判断平局函数
④整个游戏算法实现(实现逻辑)
3.三子棋游戏完整代码实现
①game.h头文件
②progress.c源文件
③game.c源文件
4.结语

1.三子棋代码功能介绍
①用坐标代替点位来下棋
②与电脑进行对局
③输赢的判断
2.三子棋游戏实现步骤
①打印菜单栏
void menu()//打印三子棋菜单栏
{printf("*************************\n");printf("*******THREECHESS********\n");printf("#####1.PLAY 0.EXIT#####\n");printf("*************************\n");}
②判断是否进入三子棋游戏
通过scanf函数来获取用户输入;
再使用switch语句来判断是否进入或退出三子棋游戏;
void progress()//判断是否进入游戏
{int input = 0;do{menu();printf("请输入>:");scanf_s("%d", &input);switch (input){case 1://如果用户输入1就进入游戏printf("进入游戏\n");game();//三子棋游戏实现函数printf("\n\n\n");//打印空行使得排版更好看break;case 0:printf("退出游戏\n");break;default://输入不为1或0的情况处理printf("输入错误\n");break;}}while (input);//如果input不为0则一直进入循环判断是否进入三子棋
}
如图所示:

③三子棋游戏基本函数实现
注:首先要知道我们用二维字符数组(char board[ROW][COL])来抽象实现三子棋;
ROW,COL宏定义为3;
col,rol传给函数的内容也是3;
(1)清空(初始化)棋盘函数实现
初始化棋盘实际就是将二维数组的各个元素全都初始化为空格,用嵌套for循环来实现
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘,这里ROW,COL是宏定义值是3
{int i = 0;int j = 0;for (i = 0; i < row; i++)//用for循环来逐一初始化{for (j = 0; j < col; j++){board[i][j] = ' ';//初始化为空格}}
}
(2)打印棋盘函数实现
类似于初始化棋盘函数打印棋盘函数也使用嵌套的for循环语句;
并借用键盘上的字符‘|’和‘-’来分割棋盘形状
void DisPlayBoard(char board[ROW][COL], int row, int col)//打印棋盘,ROW,COL宏定义为3,col,
//rol传的内容也是3
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)//for循环来逐一打印{printf(" %c ",board[i][j]);if (j < col - 1){printf("|");//打印‘|’来分割每个格子} }if(i < row - 1)printf("\n---|---|---\n");//一行打印完用横线分割下一行,进行下一行的打印}
}
运行结果如下:

(3)玩家下棋函数实现
注:玩家下棋用‘*’, 电脑下棋用‘#’;
要用if语句判断玩家输入的坐标是否在3*3棋盘内;
还要用if语句判断玩家输入的坐标是否被占用(是否已经下过);
void PlayerMove(char board[ROW][COL], int row, int col)//玩家下棋
{int x = 0;int y = 0;printf("\n玩家下棋>>");//提示玩家下棋while (1)//如果输入坐标不正确就多次输入{printf("\n请输入坐标:\n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col)//判断坐标是否在3*3棋盘内{if (board[x - 1][y - 1] == ' ')//判断该格子是否被占用{board[x - 1][y - 1] = '*';//没有占用就放字符‘*’作为玩家下过的标志break;//玩家已经下过一次后跳出循环进行下一轮}elseprintf("该坐标已被占用,请重新输入.\n");//如果坐标被占用进行提示重新输入}elseprintf("坐标输入非法,请重新输入.\n");//如果坐标非法提示重新输入}
}
运行结果如下:

(4)电脑下棋函数实现
注:使用随机数生成函数(rand)来获得电脑要下的坐标;
获得的随机数除以3取余数就可以获得大于等于0小于3的整数以此来作为电脑下棋的坐标;
同时也要判断随机生成的坐标是否合法;
如果坐标合法且未被占用就标记‘#’;
void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{printf("\n电脑下棋>>\n");//提示电脑下棋int x = 0;int y = 0;while (1)//如果坐标非法就重新输入{x = rand() % row;//使用随机数生成函数生成随机数,并除以3得余数获得0~2的数y = rand() % col;{if (board[x][y] == ' ')//判断该坐标在棋盘上是否被占用{board[x][y] = '#';//没被占用就标记‘#’break;} }}
}

(5)判断输赢函数
注:判断输赢函数多增加了一个参数tmp来传入玩家和电脑代表的字符,一旦一列或一行或从左往右或从右往左的直线有三个相同的字符并且等于tmp的就返回字符tmp,通过tmp就可以判断出玩家赢了还是电脑赢了
char IsWin(char board[ROW][COL], int row, int col, char tmp)//判断输赢,返回字符
{int i = 0;int j = 0;int count = 0;for (i = 0; i < ROW; i++)//判断一是否有三个字符相同{int count = 0;for (j = 0; j < COL; j++){if (board[i][j] != tmp)//有一个不同就break跳出本次循环break;elsecount++;//有一个相同count就+1if (count == 3)//当count等于3时就代表一行中有三个相同return tmp;//当一行中有三个相同的字符时就代表该字符所对应的赢了返回该字符}}for (j = 0; j < COL; j++)//同理判断一列中是否有三个字符相同{int count = 0;for (i = 0; i < ROW; i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (count = 0,i = 0; i < ROW; i++)//判断从左往右的直线三个字符是否相同{if (board[i][i] != tmp)break;elsecount++;if (count == 3)return tmp; }for (count = 0,j = COL - 1,i =0; j >= 0,i <ROW; j--,i++)//判断从左往右的直线{if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}return 0;
}
(6)判断平局函数
注:除了判断输赢还要记得判断是否有平局的情况;
用嵌套for循环来逐一判断二位数组是否有空格;
没有空格代表平局,返回字符‘Q’;
char IsFull(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++)//使用for循环逐一判断棋盘是否有空格{if (board[i][j] == ' ')return 0;//有空格也就是还没下完返回0}}return 'Q';//没有空格平局了返回字符‘Q’
}
④整个游戏算法实现(实现逻辑)
void game()//游戏的整个算法实现
{char ret = 0;char bian = 0;char board[ROW][COL] = { 0 };InitBoard(board, ROW, COL);//清空棋盘DisPlayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '*');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '*'){printf("\n玩家赢啦~");break;}if (bian == 'Q'){printf("\n平局");break;}ComputerMove(board, ROW, COL);//电脑下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '#');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '#'){printf("\n太可惜了,电脑赢了");break;}if (bian == 'Q'){printf("\n平局");break;}}
}
运行结果如下:

3.三子棋游戏完整代码实现
注:有些注释上文标注但在完整代码中未标注
①game.h头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
constexpr auto ROW = 3;
constexpr auto COL = 3;
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘函数
void DisPlayBoard(char board[ROW][COL], int row, int col);//打印棋盘函数
void PlayerMove(char board[ROW][COL], int row, int col);//玩家下棋函数
void ComputerMove(char board[ROW][COL], int row, int col);//电脑下棋函数
char IsWin(char board[ROW][COL], int row, int col, char tmp);//判断输赢函数
char IsFull(char board[ROW][COL], int row, int col);//判断平局函数
②progress.c源文件
#include"game.h"
void menu()//打印菜单栏
{printf("*************************\n");printf("*******THREECHESS********\n");printf("#####1.PLAY 0.EXIT#####\n");printf("*************************\n");}
void game()//游戏的整个算法实现
{char ret = 0;char bian = 0;char board[ROW][COL] = { 0 };InitBoard(board, ROW, COL);//清空棋盘DisPlayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '*');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '*'){printf("\n玩家赢啦~");break;}if (bian == 'Q'){printf("\n平局");break;}ComputerMove(board, ROW, COL);//电脑下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '#');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '#'){printf("\n太可惜了,电脑赢了");break;}if (bian == 'Q'){printf("\n平局");break;}}
}void progress()//判断是否进入游戏
{int input = 0;do{menu();printf("请输入>:");scanf_s("%d", &input);switch (input){case 1:printf("进入游戏\n");game();printf("\n\n\n");break;case 0:printf("退出游戏\n");break;default:printf("输入错误\n");break;}}while (input);}int main()
{int row = ROW;int col = COL;srand((unsigned int)time(NULL));//设置随机数的生成起点progress();return 0;}
③game.c源文件
#include"game.h"
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] = ' ';}}
}
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("|");} }if(i < row - 1)printf("\n---|---|---\n");}
}void PlayerMove(char board[ROW][COL], int row, int col)//玩家下棋
{int x = 0;int y = 0;printf("\n玩家下棋>>");while (1){printf("\n请输入坐标:\n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}elseprintf("该坐标已被占用,请重新输入.\n");}elseprintf("坐标输入非法,请重新输入.\n");}
}
void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{printf("\n电脑下棋>>\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;{if (board[x][y] == ' '){board[x][y] = '#';break;} }}
}char IsWin(char board[ROW][COL], int row, int col, char tmp)//判断输赢
{int i = 0;int j = 0;int count = 0;for (i = 0; i < ROW; i++){int count = 0;for (j = 0; j < COL; j++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (j = 0; j < COL; j++){int count = 0;for (i = 0; i < ROW; i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (count = 0,i = 0; i < ROW; i++){if (board[i][i] != tmp)break;elsecount++;if (count == 3)return tmp; }for (count = 0,j = COL - 1,i =0; j >= 0,i <ROW; j--,i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}return 0;
}char IsFull(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 'Q';
}
4.结语
以上就是C语言实现简单三子棋游戏完整代码以及过程实现啦,我们也可以通过三子棋的代码思考五子棋游戏的实现,以及对于随机数生成来作为电脑下棋的坐标似乎有点愚笨,我们或许可以试着写一些让电脑选择坐标更聪明一点的函数,让玩家拥有更好的游戏体验哦,希望能和大家一起学习进步。
相关文章:
【C语言】三子棋游戏实现代码
目录 1.三子棋代码功能介绍 2.三子棋游戏实现步骤 ①打印菜单栏 ②判断是否进入三子棋游戏 ③三子棋游戏基本函数实现 (1)清空(初始化)棋盘函数实现 (2)打印棋盘函数实现 (3࿰…...
docker常用10条容器操作命令
Docker 中一些常用的容器操作命令,我们可以根据需要使用这些命令来管理和操作 Docker 容器。我们这次以Hell-world这个镜像为例来说明: 1. docker pull hello-world #拉取hell-world镜像 2. docker images # 查看本地拉取的镜像 或者可以用 docker im…...
《MySQL 简易速速上手小册》第2章:数据库设计最佳实践(2024 最新版)
文章目录 2.1 规划高效的数据库架构2.1.1 基础知识2.1.2 重点案例:在线电商平台2.1.3 拓展案例 1:博客系统2.1.4 拓展案例 2:库存管理系统 2.2 数据类型和表设计2.2.1 基础知识2.2.2 重点案例:个人健康记录应用2.2.3 拓展案例 1&a…...
利用YOLOv8 pose estimation 进行 人的 头部等马赛克
文章大纲 马赛克几种OpenCV 实现马赛克的方法高斯模糊pose estimation 定位并模糊:三角形的外接圆与膨胀系数实现实现代码实现效果参考文献与学习路径之前写过一个文章记录,怎么对人进行目标检测后打码,但是人脸识别有个问题是,很多人的背影,或者侧面无法识别出来人脸,那…...
【Python 千题 —— 基础篇】查找年龄
Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 班级中有 Tom、Alan、Bob、Candy、Sandy 五个人,他们组成字典 {Tom: 23, Alan: 24, Bob: 21, Candy: 22, Sandy: 21},字典的键是姓名,字典的…...
前后端通讯:前端调用后端接口的五种方式,优劣势和场景
Hi,我是贝格前端工场,专注前端开发8年了,前端始终绕不开的一个话题就是如何和后端交换数据(通讯),本文先从最基础的通讯方式讲起。 一、什么是前后端通讯 前后端通讯(Frontend-Backend Commun…...
Mysql大表添加字段失败解决方案
背景 最近遇到一个问题,需要在user用户表千万级别数据中添加两个字段,发现老是加不上去,一直卡死。表数据量不仅大,而且是一个热点表,访问频率特别高,而且该表的访问是在一个大事务中。加字段的时候一直在…...
(52)只出现一次的数字III
文章目录 每日一言题目解题思路代码结语 每日一言 十年磨一剑,风雨未曾阻挡;愿你乘风破浪,不负韶华时光。 题目 题目链接:只出现一次的数字 给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现…...
Linux增删ip
Linux手动增删IP by: 铁乐猫 日期:2022.03.17 这里主要是记录手动临时添加和删除ip。 ifconfig方式 例,添加: ifconfig eth0:1 192.168.0.101/24移除 ifconfig eth0:1 downip addr方式 添加 ip addr add 192.168.0.102/24 dev eth0 …...
【计算机网络】时延,丢包,吞吐量(分组交换网络
时延 结点处理时延(nodal processing delay) dproc 排队时延(queuing delay) dqueue 传输时延(transmission delay) dtrans 路由器将分组推出所需要的时间,是分组长度和链路传输速率的函数 传播时…...
张楠辞任抖音集团CEO;东方甄选将开服饰号;小红书新增“附近”一级入口;华为分红770亿元
今日精选 • 张楠辞任抖音集团CEO,未来将聚焦剪映发展• 东方甄选将开服饰号 主打自营服饰• 小红书新增“附近”一级入口• 华为分红770亿元 大厂人事变动 • 上村健一出任中国U-16国家男子足球队主教练 投融资与企业动态 • 阿里大模型「通义千问」推出春节新…...
ES监控方法以及核心指标
文章目录 1. 监控指标采集1.1 部署elasticsearch_exporter1.2 prometheus采集elasticsearch_exporter的暴露指标1.3 promethues配置告警规则或者配置grafana大盘 2. 核心告警指标2.1 es核心指标2.2 es容量模型建议 3. 参考文章 探讨es的监控数据采集方式以及需要关注的核心指标…...
无人机应用场景和发展趋势,无人机技术的未来发展趋势分析
随着科技的不断发展,无人机技术也逐渐走进了人们的生活和工作中。无人机被广泛应用于很多领域,例如遥感、民用、军事等等。本文将围绕无人机技术的应用场景和发展趋势,从多角度展开分析。 无人机技术的应用场景 无人机在遥感方面的应用&…...
JavaGuide
JavaGuide(Java学习&面试指南) | JavaGuide JavaGuide 是一个面向 Java 开发者的知识整合平台,它提供了 Java 相关的学习资源、面试题、开发工具、框架和库等内容。JavaGuide 的目标是帮助 Java 开发者更好地学习和应用 Java 技术。 Ja…...
IDEA创建SpringBoot+Mybatis-Plus项目
IDEA创建SpringBootMybatis-Plus项目 一、配置Maven apache-maven-3.6.3的下载与安装(详细教程) 二、创建SpringBoot项目 在菜单栏选择File->new->project->Spring Initializr,然后修改Server URL为start.aliyun.com,…...
第9章 SpringBoot综合项目实战——个人博客系统
学习目标 了解博客系统的系统功能和文件组织结构 熟悉博客系统数据库相关表及字段的设计 熟悉系统环境搭建的步骤及相关配置 掌握前后台管理模块功能的实现 掌握用户登录,定时邮件发送功能的实现 通过前面章节的学习,读者应该已经掌握了SpringBoot框架的基本知识,并学会了与…...
怎么理解 Redis 事务
背景 在面试中经常会被问到,redis支持事务吗?事务是怎么实现的?事务会回滚吗?又是一键三连,我下面分析下,看看能不能吊打面试官 什么是Redis事务 事务是一个单独的隔离操作:事务中的所有命令…...
react中的diff算法
diff算法 对于React团队发现在日常开发中对于更新组件的频率,会比新增和删除的频率更高,所以在diff算法里,判断更新的优先级会更高。对于Vue2的diff算法使用了双指针,React的diff算法没有使用双指针,是因为更新的jsx对…...
【医学大模型 尘肺病】PneumoLLM:少样本大模型诊断尘肺病新方法
PneumoLLM:少样本大模型诊断尘肺病新方法 提出背景PneumoLLM 框架效果 提出背景 论文:https://arxiv.org/pdf/2312.03490.pdf 代码:https://github.com/CodeMonsterPHD/PneumoLLM/tree/main 历史问题及其背景: 数据稀缺性问题&a…...
【SpringBootStarter】自定义全局加解密组件
【SpringBootStarter】 目的 了解SpringBoot Starter相关概念以及开发流程实现自定义SpringBoot Starter(全局加解密)了解测试流程优化 最终引用的效果: <dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...
前端打包工具简单介绍
前端打包工具简单介绍 一、Webpack 架构与插件机制 1. Webpack 架构核心组成 Entry(入口) 指定应用的起点文件,比如 src/index.js。 Module(模块) Webpack 把项目当作模块图,模块可以是 JS、CSS、图片等…...
