用c++实现五子棋小游戏
五子棋是一款经典小游戏,今天我们就用c++实现简单的五子棋小游戏
目录
用到的算法:
思路分析
定义变量
开始写代码
完整代码
结果图:
用到的算法:
合法移动的判断:
isValidMove函数通过检查指定位置是否在棋盘范围内,并且该位置是否为空位来确定是否为合法的移动。获胜条件的检查:
checkWin函数通过遍历四个方向(水平、垂直、两个对角线)来检查是否存在连续的五个相同类型的棋子。它使用两个 while 循环,一个向一个方向移动,另一个向相反方向移动,以统计横向、纵向和对角线上相同类型棋子的数量。棋盘状态的打印:
printBoard函数使用嵌套的 for 循环来遍历棋盘的每个位置,并输出相应的符号来表示该位置的状态。棋盘是否已满的检查:
isBoardFull函数使用嵌套的 for 循环来遍历棋盘的每个位置,检查是否存在空位。如果不存在空位,则棋盘已满
思路分析
-
初始化:创建一个空的棋盘,大小为15x15,用二维向量表示。初始时所有位置都是空位。
-
循环游戏:进入一个无限循环,在每一轮中依次执行以下步骤:
- 打印当前棋盘状态;
- 根据当前轮到的玩家,提示玩家输入下子位置;
- 检查输入的下子位置是否合法,即在棋盘范围内且为空位,如果不合法则提示重新输入;
- 在棋盘上下子,并判断是否获胜或棋盘已满;
- 如果获胜或棋盘已满,根据情况打印相应的信息,并结束游戏。
-
判断获胜和棋盘是否已满:
- 每次下子后,调用
checkWin函数来检查当前位置是否连成五子,如果是则返回获胜; - 如果没有获胜,则调用
isBoardFull函数来判断棋盘是否已满,如果棋盘已满则返回平局。
- 每次下子后,调用
-
输出棋盘状态:
printBoard函数使用嵌套的 for 循环遍历棋盘的每个位置,根据该位置的状态输出相应的符号,用于展示当前棋盘状态
定义变量
BOARD_SIZE定义了棋盘的大小,这里设置为15x15。EMPTY、BLACK和WHITE定义了棋盘上的三种状态:空位、黑棋和白棋。board是一个二维向量,表示棋盘,初始时所有位置都是空位。isValidMove函数用于判断某个位置是否可以下子。合法的位置必须在棋盘范围内,并且为空位。checkWin函数用于判断某个位置下子后是否获胜。它检查当前位置在四个方向上(水平、垂直、两个对角线)是否有连续的连续的五个相同类型棋子。如果有则返回 true,否则返回 false。printBoard函数用于打印当前棋盘的状态。isBoardFull函数用于判断棋盘是否已经满了(即没有空位),如果棋盘已满,则返回 true,否则返回 false。main函数是程序的入口。它使用一个无限循环,每次循环轮流让玩家下子,然后判断是否游戏结束。如果有一方获胜或者棋盘已满,则打印相应的信息,并结束游戏。
开始写代码
void printBoard() {for (int i = 0; i < BOARD_SIZE; i++) {for (int j = 0; j < BOARD_SIZE; j++) {cout << board[i][j] << " ";}cout << endl;}cout << endl;
}
这段代码为打印棋盘状态的函数
printBoard(),使用了嵌套的循环来遍历棋盘,并输出每个位置的状态。具体的实现逻辑如下:
- 外层循环
for (int i = 0; i < BOARD_SIZE; i++)遍历棋盘的行数,从第一行开始到最后一行。- 内层循环
for (int j = 0; j < BOARD_SIZE; j++)遍历棋盘的列数,从第一列开始到最后一列。- 在内层循环中,通过
board[i][j]获取当前位置的状态值,并使用cout输出该状态值。- 输出一个空格,以分隔不同位置的状态值。
- 内层循环结束后,通过
cout << endl;输出换行符,以换行显示下一行的棋盘状态。- 外层循环结束后,通过
cout << endl;再次输出一个换行符,以在棋盘状态的输出之间添加空行。这样,调用
printBoard()函数可以按照指定格式输出当前棋盘的状态。每个位置上的状态值可以是空格、X或O等字符,表示空位、玩家1和玩家2的棋子。通过这个函数,可以直观地展示游戏棋盘的状态给玩家。
bool isValidMove(int row, int col) {return (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && board[row][col] == EMPTY);
}
这段代码是用于判断玩家落子是否合法的函数
isValidMove(row, col),其中row和col分别表示玩家输入的坐标值。具体的实现逻辑如下:
- 首先,通过
row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE判断玩家输入的坐标值是否在棋盘范围内。如果超出了棋盘范围,则此次落子不合法。- 否则,通过
board[row][col] == EMPTY判断该位置是否已有棋子(即状态值是否为EMPTY)。如果该位置上没有棋子,则此次落子合法,返回true。- 如果该位置上已经有棋子,则此次落子不合法,返回
false。通过这个函数,可以快速判断玩家输入的坐标是否合法。如果不合法,则需要提示玩家重新输入坐标;如果合法,则可以继续进行游戏。
bool checkWin(int row, int col, char player) {int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}};for (int i = 0; i < 4; i++) {int count = 1;int dx = directions[i][0], dy = directions[i][1];int r = row + dx, c = col + dy;while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {count++;r += dx;c += dy;}dx = -dx, dy = -dy;r = row + dx, c = col + dy;while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {count++;r += dx;c += dy;}if (count >= 5)return true;}return false;
}
这段代码是用于检查玩家是否取得胜利的函数
checkWin(row, col, player),其中row和col表示最后一次落子的坐标,player表示当前玩家的符号。具体的实现逻辑如下:
- 首先,定义一个二维数组
directions[4][2]来表示四个方向,分别为向下、向右、右下、左下。每个方向由两个元素组成,分别表示在行方向和列方向上的增量。- 使用一个循环遍历四个方向。
- 在循环内部,初始化一个计数器
count为1,表示已经有一颗当前玩家的棋子。- 根据当前方向的增量
(dx, dy),计算下一个检查的位置(r, c),并检查该位置是否在棋盘范围内且值等于当前玩家的符号。- 如果满足条件,将计数器
count加1,并更新下一个位置(r, c)为当前位置加上增量(dx, dy)。- 重复步骤4和步骤5,直到碰到越界或者不是当前玩家的棋子。
- 然后,将增量
(dx, dy)取相反数,即改变方向。- 再次计算下一个检查的位置
(r, c),并检查该位置是否在棋盘范围内且值等于当前玩家的符号。- 如果满足条件,将计数器
count加1,并更新下一个位置(r, c)为当前位置加上增量(dx, dy)。- 重复步骤8和步骤9,直到碰到越界或者不是当前玩家的棋子。
- 检查计数器
count是否大于等于5,如果是,则表示当前玩家在其中一个方向上取得了胜利,返回true。- 如果四个方向都遍历完毕,仍未满足取胜条件,则返回
false。通过这个函数,可以判断当前玩家是否在最后一次落子后取得了胜利。根据游戏规则,只有当任意一方在横、竖、斜对角线方向上连续五个棋子时才算获胜。
完整代码
#include <iostream>
#include <vector>using namespace std;const int BOARD_SIZE = 15;
const char EMPTY = '-';
const char BLACK = 'X';
const char WHITE = 'O';vector<vector<char> > board(BOARD_SIZE, vector<char>(BOARD_SIZE, EMPTY));bool isValidMove(int row, int col) {return (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && board[row][col] == EMPTY);
}bool checkWin(int row, int col, char player) {int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}};for (int i = 0; i < 4; i++) {int count = 1;int dx = directions[i][0], dy = directions[i][1];int r = row + dx, c = col + dy;while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {count++;r += dx;c += dy;}dx = -dx, dy = -dy;r = row + dx, c = col + dy;while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {count++;r += dx;c += dy;}if (count >= 5)return true;}return false;
}void printBoard() {for (int i = 0; i < BOARD_SIZE; i++) {for (int j = 0; j < BOARD_SIZE; j++) {cout << board[i][j] << " ";}cout << endl;}cout << endl;
}bool isBoardFull() {for (int i = 0; i < BOARD_SIZE; i++) {for (int j = 0; j < BOARD_SIZE; j++) {if (board[i][j] == EMPTY)return false;}}return true;
}int main() {int row, col;char currentPlayer = BLACK;while (true) {printBoard();cout << "Player " << currentPlayer << ", enter your move (row col): ";cin >> row >> col;if (!isValidMove(row, col)) {cout << "Invalid move! Try again." << endl;continue;}board[row][col] = currentPlayer;if (checkWin(row, col, currentPlayer)) {cout << "Player " << currentPlayer << " wins!" << endl;break;} else if (isBoardFull()) {cout << "It's a draw!" << endl;break;}currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK;}printBoard();return 0;
}
在这个五子棋游戏代码中,可以通过以下方式进行输入和输出:
输入:
- 玩家输入下子位置:可以通过命令行提示玩家输入坐标,例如,要求玩家输入行和列的数字,表示下子位置的坐标。
- 其他玩家操作:例如,要求玩家输入指令来选择重新开始游戏或退出游戏。
输出:
- 打印当前棋盘状态:使用嵌套的循环遍历棋盘,根据棋盘上每个位置的状态输出相应的符号,可以使用空格、X和O等字符来表示空位、玩家1和玩家2的棋子。
- 提示玩家操作:例如,提示玩家输入坐标来下子,或者提示玩家输入指令以进行其他操作。
- 游戏结果输出:当游戏结束时,根据游戏结果输出胜利者或者平局信息。
- 错误提示:如果玩家输入了无效的指令或下子位置,可以输出错误提示信息,要求玩家重新输入。
在代码中,可以使用适当的输入函数,如input()来接收玩家输入,并使用适当的输出函数,如print()来输出信息到控制台。通过合理地组织输入和输出,可以实现与玩家的有效交互,并提供友好的游戏体验。
结果图:

如果想要更加华丽美观的代码,关注博主赞赏2元回复“五子棋华丽代码”即可。
相关文章:
用c++实现五子棋小游戏
五子棋是一款经典小游戏,今天我们就用c实现简单的五子棋小游戏 目录 用到的算法: 思路分析 定义变量 开始写代码 完整代码 结果图: 用到的算法: 合法移动的判断:isValidMove 函数通过检查指定位置是否在棋盘范…...
Android 12.0 SystemUI下拉状态栏定制化之隐藏下拉通知栏布局功能实现(二)
1.前言 在12.0的系统定制化开发中,由于从12.0开始SystemUI下拉状态栏和11.0的变化比较大,所以可以说需要从新分析相关的SystemUI的 布局,然后做分析来实现不同的功能,今天就开始实现关于隐藏SystemUI下拉状态栏中的通知栏布局系列二,去掉下拉状态栏中 通知栏部分 白色的…...
通过finalshell快速在ubuntu上安装jdk1.8
这篇文章主要介绍一下怎么通过finalshell连接ubuntu,然后在ubuntu上安装jdk1.8,让不熟悉linux操作系统的童鞋也能快速地完成安装。 目录 一、准备一台虚拟机 二、安装finalshell远程连接工具 三、获取ubuntu虚拟机的ip地址 四、通过finalshell连接u…...
【Linux从入门到精通】多线程 | 线程互斥(互斥锁)
上篇文章我们对线程 | 线程介绍&线程控制介绍后,本篇文章将会对多线程中的线程互斥与互斥锁的概念进行详解。同时结合实际例子解释了可重入与不被重入函数、临界资源与临界区和原子性的概念。希望本篇文章会对你有所帮助。 文章目录 引入 一、重入与临界 1、1 可…...
Echarts 散点图的详细配置过程
文章目录 散点图 简介配置步骤简易示例 散点图 简介 Echarts散点图是一种常用的数据可视化图表类型,用于展示两个或多个维度的数据分布情况。散点图通过在坐标系中绘制数据点的位置来表示数据的关系。 Echarts散点图的特点如下: 二维数据展示ÿ…...
Nginx详解 五:反向代理
文章目录 1. 正向代理和反向代理1.1 正向代理概述1.1.1 什么是正向代理1.1.2 正向代理的作用1.1.3 正向代理的基本格式 1.2 反向代理概述1.2.1 什么是反向代理1.2.2 反向代理可实现的功能1.2.3 反向代理的可用模块 2. 配置反向代理2.1 反向代理配置参数2.1.1 proxy_pass2.1.2 其…...
【PDF密码】PDF文件打开之后不能打印,怎么解决?
正常的PDF文件是可以打印的,如果PDF文件打开之后发现文件不能打印,我们需要先查看一下自己的打印机是否能够正常运行,如果打印机是正常的,我们再查看一下,文件中的打印功能按钮是否是灰色的状态。 如果PDF中的大多数功…...
深入解析 qsort 函数(下),用冒泡排序模拟实现 qsort 函数
前言:对于库函数有适当了解的朋友们,对于 qsort 函数想必是有认知的,因为他可以对任意数据类型进行排序的功能属实是有点厉害的,本次分享,笔者就给大家带来 qsort 函数的全面的解读 本次知识的分享笔者分为上下俩卷文章…...
Azure + React + ASP.NET Core 项目笔记一:项目环境搭建(二)
有意义的标题 pnpm 安装umi4 脚手架搭建打包语句变更Visual Studio调试Azure 设置变更发布 pnpm 安装 参考官网,或者直接使用npm安装 npm install -g pnpmumi4 脚手架搭建 我这里用的umi4,官网已附上 这里需要把clientapp清空,之后 cd Cl…...
Vmware通过VMware tools设置共享文件夹
步骤说明: 先安装VMware tools,再设置共享文件夹即可。 写在前面: 刚安装虚拟机时,窗口可能显得太小,这是窗口分辨率没有调整导致的。 点击设置->显示->分辨率调整即可 一、安装VMware tools 1.1 点击虚拟机…...
RPA机器人流程自动化专题培训大纲 (针对大学生的版本)
一、课程简介 RPA机器人流程自动化是一种新兴的技术,它通过软件机器人模拟人类操作计算机完成重复性任务,从而实现业务流程的自动化。本课程旨在介绍RPA机器人流程自动化的基本概念、原理和应用,并通过实践案例演示如何应用RPA机器人流程自动…...
数据在内存中的存储——练习4
题目: int main() {char a[1000];int i;for(i0; i<1000; i){a[i] -1-i;}printf("%d",strlen(a));return 0; }思路分析: 已知条件: 通过循环遍历,我们得到的结果是 -1、-2、-3、-4等等。这些是数组内部的存储的元…...
Python 06 之面向对象基础
😀前言 在日常编程和软件开发中,我们通常会遇到各种各样的问题,其中很多问题都可以通过面向对象的程序设计方法来解决。面向对象编程不仅可以使代码更加组织化和系统化,而且还可以提高代码的重用性和可维护性。 . 在本教程中&…...
去除pdf/word的水印艺术字
对于pdf中的水印如果无法去除水印,则先另存为word,然后再按下面办法处理即可: 查看宏,创建:删除艺术字 添加内容: Sub 删除艺术字()Dim sh As ShapeFor Each sh In ActiveDocument.ShapesIf sh.Type msoT…...
【Linux】使用 Alist 实现阿里云盘4K播放
一、安装 Alist 官方文档 默认安装在 /opt/alist 中 curl -fsSL "https://alist.nn.ci/v3.sh" | bash -s install自定义安装路径,将安装路径作为第二个参数添加,必须是绝对路径,如果路径以 alist 结尾,则直接安装到给定…...
Gof23设计模式之状态模式
1.概述 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能…...
如何免费下载RunWayML产生的视频文件
问题: 首先没有下载的按钮。 其次如果直接“视频另存为”菜单,报错。 解决方案: 1)复制视频链接。 2)新开chrome,在url中粘贴上一步的url路径。 3)当看到视频后,在视频上面右键“…...
9.14 C++作业
仿照vector手动实现自己的myVector,最主要实现二倍扩容功能 #include <iostream>using namespace std;template <typename T> class Myvector {T *data; //存储数据的数组int len; //当前数组的长度int mycapa; //容纳数据的总容量public://…...
java关于文件记录篇章之文件夹创建篇
今天,创建一个文件夹目录的时候,创建多级目录的时候发现,自己老是创建失败,但是系统显示文件夹创建成功,但是你去找文件夹的时候,又发现创建失败,这里在我成功之后封装了一个创建文件夹的创建对…...
显示器显示的画面突然偏红色如何解决
显示器显示的画面突然偏红色如何解决 1. 概述2. 解决方法结束语 1. 概述 显示器显示的画面突然偏红色 ,使用向日葵远程电脑,看到的画面是正常的,但是显示器上的画面确还是骗红的,这时候就需要看一下是不是开启了系统也夜间模式&a…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
