用C++实现五子棋游戏

#include <iostream>
#include <vector>
#include <string>
#include <iomanip>  // 用于控制输出格式
#include <limits>   // 用于numeric_limitsusing namespace std;// 游戏常量定义
const int BOARD_SIZE = 15;  // 定义棋盘大小为15x15// 棋子类型枚举
enum class Piece { EMPTY,  // 空位置BLACK,  // 黑棋(先手)WHITE   // 白棋(后手)
};// 游戏状态枚举
enum class GameState { PLAYING,    // 游戏进行中BLACK_WIN,  // 黑方胜利WHITE_WIN,  // 白方胜利DRAW        // 平局
};/*** 棋盘类 - 管理棋盘状态和游戏规则*/
class Board {
private:vector<vector<Piece>> grid;  // 使用二维数组表示棋盘public:// 构造函数 - 初始化空棋盘Board() : grid(BOARD_SIZE, vector<Piece>(BOARD_SIZE, Piece::EMPTY)) {}/*** 重置棋盘 - 将所有位置设为空*/void reset() {// 遍历每一行for (auto& row : grid) {// 将每行的所有元素设为EMPTYfill(row.begin(), row.end(), Piece::EMPTY);}}/*** 在指定位置放置棋子* @param x 横坐标(0-14)* @param y 纵坐标(0-14)* @param piece 要放置的棋子类型* @return 放置是否成功*/bool placePiece(int x, int y, Piece piece) {// 检查坐标是否有效且该位置为空if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE || grid[x][y] != Piece::EMPTY) {return false;  // 无效移动}grid[x][y] = piece;  // 放置棋子return true;}/*** 获取指定位置的棋子* @param x 横坐标* @param y 纵坐标* @return 该位置的棋子类型(无效坐标返回EMPTY)*/Piece getPiece(int x, int y) const {// 检查坐标是否有效if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE) {return Piece::EMPTY;}return grid[x][y];}/*** 检查是否五子连珠* @param x 最后落子的横坐标* @param y 最后落子的纵坐标* @return 是否形成五子连珠*/bool checkFiveInARow(int x, int y) const {Piece current = grid[x][y];if (current == Piece::EMPTY) return false;  // 空位置不可能五连// 四个检查方向: 水平、垂直、主对角线、副对角线int directions[4][2] = { {1,0},  // 水平方向{0,1},   // 垂直方向{1,1},   // 主对角线{1,-1} }; // 副对角线// 检查每个方向for (auto& dir : directions) {int count = 1;  // 当前棋子已经算1个// 正向检查for (int i = 1; i < 5; i++) {int nx = x + dir[0] * i;int ny = y + dir[1] * i;if (getPiece(nx, ny) != current) break;  // 遇到不同颜色停止count++;}// 反向检查for (int i = 1; i < 5; i++) {int nx = x - dir[0] * i;int ny = y - dir[1] * i;if (getPiece(nx, ny) != current) break;count++;}// 如果同色棋子数达到5个或更多,返回trueif (count >= 5) return true;}return false;  // 没有找到五连}/*** 打印棋盘到控制台*/void print() const {// 打印列号(顶部坐标)cout << "   ";for (int i = 0; i < BOARD_SIZE; i++) {cout << setw(2) << i << " ";  // 格式化输出列号}cout << endl;// 打印每一行for (int i = 0; i < BOARD_SIZE; i++) {cout << setw(2) << i << " ";  // 打印行号for (int j = 0; j < BOARD_SIZE; j++) {// 根据棋子类型输出不同符号switch (grid[i][j]) {case Piece::EMPTY: cout << " . "; break;  // 空位case Piece::BLACK: cout << " ● "; break;  // 黑棋case Piece::WHITE: cout << " ○ "; break;  // 白棋}}cout << endl;  // 换行}}
};/*** 游戏主类 - 管理游戏流程和状态*/
class GomokuGame {
private:Board board;         // 棋盘对象GameState state;     // 当前游戏状态Piece currentPlayer; // 当前玩家public:/*** 构造函数 - 初始化新游戏*/GomokuGame() : state(GameState::PLAYING), currentPlayer(Piece::BLACK) {}/*** 开始新游戏 - 重置棋盘和游戏状态*/void startNewGame() {board.reset();  // 清空棋盘state = GameState::PLAYING;currentPlayer = Piece::BLACK;  // 黑棋先手}/*** 获取当前游戏状态* @return 当前游戏状态*/GameState getGameState() const {return state;}/*** 打印当前游戏状态*/void printStatus() const {board.print();  // 打印棋盘cout << endl;// 根据游戏状态显示不同信息switch (state) {case GameState::PLAYING:cout << "当前玩家: " << (currentPlayer == Piece::BLACK ? "黑方" : "白方") << endl;break;case GameState::BLACK_WIN:cout << "游戏结束! 黑方获胜!" << endl;break;case GameState::WHITE_WIN:cout << "游戏结束! 白方获胜!" << endl;break;case GameState::DRAW:cout << "游戏结束! 平局!" << endl;break;}}/*** 执行走棋操作* @param x 横坐标* @param y 纵坐标* @return 走棋是否成功*/bool makeMove(int x, int y) {// 检查游戏状态和走棋有效性if (state != GameState::PLAYING || !board.placePiece(x, y, currentPlayer)) {return false;  // 走棋失败}// 检查是否获胜if (board.checkFiveInARow(x, y)) {// 根据当前玩家设置胜利状态state = (currentPlayer == Piece::BLACK) ? GameState::BLACK_WIN : GameState::WHITE_WIN;return true;}// 切换玩家currentPlayer = (currentPlayer == Piece::BLACK) ? Piece::WHITE : Piece::BLACK;return true;}
};/*** 主函数 - 游戏入口*/
int main() {GomokuGame game;  // 创建游戏实例game.startNewGame(); // 初始化新游戏// 主游戏循环while (true) {game.printStatus();  // 显示当前游戏状态// 检查游戏是否结束if (game.getGameState() != GameState::PLAYING) {cout << "输入'r'重新开始,'q'退出: ";char cmd;cin >> cmd;if (cmd == 'r') {game.startNewGame();  // 重新开始游戏continue;}else if (cmd == 'q') {break;  // 退出游戏}}// 获取玩家输入cout << "输入坐标(x y): ";int x, y;cin >> x >> y;// 处理玩家走棋if (!game.makeMove(x, y)) {cout << "无效移动! 请重新输入。" << endl;// 清除错误输入cin.clear();cin.ignore(numeric_limits<streamsize>::max(), '\n');}}return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90175.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode 热题 100】73. 矩阵置零——(解法一)空间复杂度 O(M + N)

Problem: 73. 矩阵置零 题目&#xff1a;给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 文章目录整体思路完整代码时空复杂度时间复杂度&#xff1a;O(M * N)空间复杂度&#xff1a;O(M N)整体思路…

【深度学习新浪潮】国内零样本抗体设计的科研进展如何?

什么是AI零样本抗体设计? AI零样本抗体设计(Zero-shot AI Antibody Design)是指不依赖任何已知抗体序列或结构数据,仅根据靶点抗原信息,通过人工智能直接生成具有高亲和力、高特异性的全新抗体序列的技术。其核心在于突破传统抗体研发的“数据依赖瓶颈”,实现真正的“从…

【论文阅读】A Diffusion model for POI recommendation

论文出处&#xff1a;ACM Transactions on Information Systems (TOIS) SCI一区 CCF-A期刊 论文地址&#xff1a;[2304.07041] A Diffusion model for POI recommendation 论文代码&#xff1a;Yifang-Qin/Diff-POI: The official PyTorch implementation of Diff-POI. 目…

Rust实现FasterR-CNN目标检测全流程

使用 Rust 和 FasterR-CNN 进行目标检测 FasterR-CNN 是目标检测领域广泛使用的深度学习模型。Rust 生态中可以通过 tch-rs(Torch 绑定)调用预训练的 PyTorch 模型实现。以下为完整实现步骤: 环境准备 安装 Rust 和必要的依赖: cargo add tch cargo add anyhow # 错误…

Github 2025-07-03Go开源项目日报Top10

根据Github Trendings的统计,今日(2025-07-03统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10JavaScript项目2Go编程语言:构建简单、可靠和高效的软件 创建周期:3474 天开发语言:Go协议类型:BSD 3-Clause “New” or “Revise…

XML Schema 安装使用教程

一、XML Schema 简介 XML Schema&#xff08;XSD&#xff0c;全称 XML Schema Definition&#xff09;是用于定义 XML 文档结构、数据类型和数据约束的标准方式。它比 DTD 更加强大&#xff0c;支持数据类型、默认值、命名空间等&#xff0c;是企业级 XML 应用推荐的验证方式。…

【字节跳动】数据挖掘面试题0008:计算西瓜视频内容好评率

文章大纲题目描述题目描述 西瓜视频近期开展了”2020百大人气创作者”优质内容扶持项目&#xff0c;鼓励用户产出优质的视频内容。 现需要统计2020年11月01日至2020年11月30日期间创作的视频中&#xff0c; “科技”大类下“数码测评"子类的视频好评率&#xff08;好评率好…

Linux 进程控制:全面深入剖析进程创建、终止、替换与等待

文章目录引言一、进程创建&#xff1a;fork()系统调用的奥秘1.1 fork()的基本原理1.2 代码示例与解读1.3 写时复制&#xff08;COW&#xff09;优化二、进程终止&#xff1a;exit()与_exit()的抉择2.1 exit()和_exit()的区别2.2 代码示例与分析三、进程替换&#xff1a;exec()函…

PJSIP 中的 TCP 传输配置指南

PJSIP 支持通过 TCP 传输 SIP 消息&#xff0c;相比 UDP 提供了更可靠的传输机制。以下是关于在 PJSIP 中使用 TCP 的详细指南。1. 创建 TCP 传输基本 TCP 传输配置cpjsua_transport_config tcp_cfg; pjsua_transport_config_default(&tcp_cfg); tcp_cfg.port 5060; // SI…

小菜狗的云计算之旅,今天学习MySQL数据库基础知识及操作

目录 一、概述 数据库概念 数据库的类型 关系型数据库模型 关系数据库相关概念 二、安装 1、mariadb安装 2、mysql安装 3、启动并开机自启 4、本地连接&#xff08;本地登录&#xff09; 三、mysql数据库配置与命令 yum安装后生成的目录 mysql服务器的启动脚本 数…

为什么是直接在**原型(prototype)上**添加函数

这是一个非常经典、核心的 JavaScript 面向对象编程问题&#xff1a;> 为什么是直接在**原型&#xff08;prototype&#xff09;上**添加函数&#xff0c;而不是在类/构造函数内部直接添加&#xff1f;你提到的代码中&#xff1a;javascript function TopSearchComponent() …

深入理解 classnames:React 动态类名管理的最佳实践

在现代前端开发中&#xff0c;我们经常需要根据组件的状态、属性或用户交互来动态切换 CSS 类名。虽然 JavaScript 提供了多种方式来处理字符串拼接&#xff0c;但随着应用复杂性的增加&#xff0c;传统的类名管理方式很快就会变得混乱不堪。这时&#xff0c;classnames 库就像…

C++系列(七):深度探索C++内存 --- 分区、堆栈、new/delete与高效编程实践

引言 程序运行的本质是对数据的处理&#xff0c;而内存则是程序执行的核心舞台。理解内存的物理与逻辑分区&#xff0c;是掌握程序底层行为、编写高效可靠代码的关键基石。内存并非混沌一片&#xff0c;而是被严格划分为代码区、全局区、栈区和堆区。每个区域拥有独特的生命周…

微信小程序71~80

1.总结小程序生命周期 小程序冷启动&#xff0c;钩子函数执行的顺序保留当前页面&#xff0c;进入下一个页面&#xff0c;钩子函数执行的顺序销毁当前页面&#xff0c;进入下一个页面&#xff0c;钩子函数执行的顺序小程序热启动&#xff0c;钩子函数执行的顺序 2.使用Componen…

[Pytest][Part 3]检测python package状态

目录 实现需求1&#xff1a; 检查python package状态——pkg_resource hook实现自动检测包状态 conftest.py hook钩子函数 Part1: https://blog.csdn.net/x1987200567/article/details/144915315?spm1001.2014.3001.5501 从这里开始逐个实现Part1中的需求 实现需求1&a…

自定义时间范围选择组件使用教程(基于 Vue 3 + Element Plus)

&#x1f553; 自定义时间范围选择组件使用教程&#xff08;基于 Vue 3 Element Plus&#xff09;✅ 一个灵活实用的时间范围选择器&#xff0c;支持开始时间、结束时间、快捷时间选项、本地双向绑定、插槽扩展等功能。–&#x1f4d8; 一、功能介绍 该组件基于 Element Plus …

YOLOv8 模型转换 ONNX 后 C# 调用异常:一个参数引发的跨平台适配难题

一、问题背景&#xff1a;从 Python 训练到 C# 部署的跨平台需求 作为一名 C# 开发者&#xff0c;我在完成 YOLOv8 模型训练&#xff08;使用 Ultralytics 官方框架&#xff0c;训练数据为自定义目标检测数据集&#xff0c;输入尺寸 640x640&#xff0c;训练轮次 100 轮&#…

Apache Cloudberry 亮相 2025 IvorySQL 生态大会暨 PostgreSQL 高峰论坛

6 月 27 日至 28 日&#xff0c;IvorySQL 2025 生态大会暨 PostgreSQL 高峰论坛在泉城济南顺利召开。本届大会由 IvorySQL 开源数据库社区主办、瀚高基础软件股份有限公司承办&#xff0c;吸引了来自国内外的数据库技术专家、开发者与开源爱好者齐聚一堂&#xff0c;聚焦数据库…

CMake之CMakeLists.txt语法规则

本文主要参考正点原子的应用开发手册&#xff0c;仅作为本人学习笔记使用。 目录 cmake 的使用方法其实还是非常简单的&#xff0c;重点在于编写 CMakeLists.txt&#xff0c;CMakeLists.txt 的语法规则也简单&#xff0c;并没有 Makefile的语法规则那么复杂难以理解&#xff01…

Mysql专题复习

重点内容&#xff1a;1. Mysql架构&#xff1a;客户端 Server层 存储引擎2. 索引数据结构&#xff1a;B树4. 索引优化&#xff1a;覆盖索引、排序、JOIN、分页&#xff1b; COUNT; 索引下推&#xff1b;单/双路排序5. 数据库事务&#xff1b; 锁&#xff1b;隔离级别&#xff…