五子棋小游戏(sut实验报告)

  • 实验目的

实现人与人或人与电脑进行五子棋对弈

  • 实验内容

启动游戏,显示游戏参数设置界面,用户输入参数后进入游戏界面,显示棋盘及双方博弈过程,游戏过程中可选择退出游戏。判定一方获胜后结束本局游戏,可选择继续下一局或者退出游戏。

  • 分析与设计

设计棋盘:使用for循环的嵌套并定义一个二维数组存储棋子

void create_board(char board[N][N] , int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){cout << ' ' << board[i][j] << ' ';//" %c "if(j < n - 1)cout << '|';}cout << endl;if(i < n - 1){for(int j = 0;j < n;j++){cout << "---";if(j < n - 1)cout << '|';}}cout << endl;}
}

下棋:下棋是有先后顺序,为了保持顺序以及判断是否胜利,定义一个game函数来设置下棋流程。下棋者可以是人也可以是电脑,先对人下棋设置一个函数play_game和play_game_2,来定义双方下棋的位置与不同棋子,

//玩家下棋
bool play_game(char board[N][N] , int n)
{int x,y;cout << "请玩家1下棋->" << endl;while(1){cin >> x >> y;if(x >= 0 && x < n && y >= 0 && y < n){if(board[x][y] == ' '){board[x][y] = '*';return check_game(board,n);break;}elsecout << "该点已经下过,请您重新下谢谢" << endl;}else{cout << "坐标越界,请重新输入" << endl;}	}
}
bool play_game_2(char board[N][N] , int n)
{int x,y;cout << "请玩家2下棋->" << endl;while(1){cin >> x >> y;if(x >= 0 && x < n && y >= 0 && y < n){if(board[x][y] == ' '){board[x][y] = '#';return check_game(board,n);break;}elsecout << "该点已经下过,请您重新下谢谢" << endl;}else{cout << "坐标越界,请重新输入" << endl;}	}
}

         而电脑下棋就定义一个种子srand使电脑随机性下棋。

//电脑下棋
bool computer_game(char board[N][N],int n)
{srand((unsigned int)time(NULL)); //设置随机生成的数字cout << "电脑1下棋->";int x,y;while(1){x = rand() % n;y = rand() % n;if(board[x][y] == ' '){board[x][y] = '#';cout << x << ',' << y << endl;return check_game(board,n);break;}	}
}

判断胜利:五子棋胜利条件是五个子横着竖着斜着相连,这个时候就要判断其连通性,判断连通性最好办法就是使用DFS,首先利用两个for循环嵌套遍历当前board数组,随后对四个可能的联通方向通过DFS递归探索,如果五子确实相连,这个时候返回true,不相连则返回false。

//判断是否胜利
int dx[N] = { 1, 1, 0, 1 };
int dy[N] = { 0, 1, 1,-1 };
//判断直线是否能走
bool dfs(int x,int y,char a,int i,int res)
{if(board[x][y] != a)//五个子不全连return false;else if(res == 5)  return true; //五个子全连return dfs(x + dx[i], y + dy[i],a,i,res+1);
}
//遍历四种途径
bool check(char board[N][N],int x,int y)
{	for(int i = 0;i <= 3;i++)//四种胜利的路径判断一遍{if(dfs(x,y,board[x][y],i,1) == true){return true;}}return false;
}
bool check_game(char board[N][N],int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){if(board[i][j] != ' ')if(check(board,i,j) == true)return true;}}return false;
}

最后主函数利用while循环的嵌套判断玩家选择方式,如果其输入错误的数字,那么就会循环,直到输入正确。

另外这里也需要判断是否棋盘全满:

//判断棋盘是否填满
bool is_full(char board[N][N],int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){if(board[i][j] == ' '){return false;}}}return true;
}

完整代码如下:

#include <iostream>
#include <time.h>
using namespace std;
const int N = 100;
char board[N][N];
void menu()
{cout << "*******************************" << endl;cout << "************menu***************" << endl;cout << "**(请输入对应的数字进行选择)***" << endl;cout << "*********1.玩家对弈************" << endl;cout << "*********2.电脑下棋************" << endl;cout << "*********3.结束游戏************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;}
void choose()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "******请玩家输入棋盘大小*******" << endl;cout << "*********(注:6-100)************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
void win_1()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "********恭喜玩家1胜利**********" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
void win_2()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "********恭喜玩家2胜利**********" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
void win_computer()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "***********电脑胜利************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
void choose_3()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*************BYE***************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
void end()
{cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******是否重新开始游戏********" << endl;cout << "*********1.continue************" << endl;cout << "***********2.end***************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;cout << "*******************************" << endl;
}
//初始化棋盘
void error_board(char board[N][N] , int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){board[i][j] = ' ';}}
}
//创建棋盘
void create_board(char board[N][N] , int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){cout << ' ' << board[i][j] << ' ';//" %c "if(j < n - 1)cout << '|';}cout << endl;if(i < n - 1){for(int j = 0;j < n;j++){cout << "---";if(j < n - 1)cout << '|';}}cout << endl;}
}//判断是否胜利
int dx[N] = { 1, 1, 0, 1 };
int dy[N] = { 0, 1, 1,-1 };
//判断直线是否能走
bool dfs(int x,int y,char a,int i,int res)
{if(board[x][y] != a)//五个子不全连return false;else if(res == 5)  return true; //五个子全连return dfs(x + dx[i], y + dy[i],a,i,res+1);
}
//遍历四种途径
bool check(char board[N][N],int x,int y)
{	for(int i = 0;i <= 3;i++)//四种胜利的路径判断一遍{if(dfs(x,y,board[x][y],i,1) == true){return true;}}return false;
}
bool check_game(char board[N][N],int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){if(board[i][j] != ' ')if(check(board,i,j) == true)return true;}}return false;
}
//玩家下棋
bool play_game(char board[N][N] , int n)
{int x,y;cout << "请玩家1下棋->" << endl;while(1){cin >> x >> y;if(x >= 0 && x < n && y >= 0 && y < n){if(board[x][y] == ' '){board[x][y] = '*';return check_game(board,n);break;}elsecout << "该点已经下过,请您重新下谢谢" << endl;}else{cout << "坐标越界,请重新输入" << endl;}	}
}
bool play_game_2(char board[N][N] , int n)
{int x,y;cout << "请玩家2下棋->" << endl;while(1){cin >> x >> y;if(x >= 0 && x < n && y >= 0 && y < n){if(board[x][y] == ' '){board[x][y] = '#';return check_game(board,n);break;}elsecout << "该点已经下过,请您重新下谢谢" << endl;}else{cout << "坐标越界,请重新输入" << endl;}	}
}
//电脑下棋
bool computer_game(char board[N][N],int n)
{srand((unsigned int)time(NULL)); //设置随机生成的数字cout << "电脑1下棋->";int x,y;while(1){x = rand() % n;y = rand() % n;if(board[x][y] == ' '){board[x][y] = '#';cout << x << ',' << y << endl;return check_game(board,n);break;}	}
}
//判断棋盘是否填满
bool is_full(char board[N][N],int n)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){if(board[i][j] == ' '){return false;}}}return true;
}
void game_1(char board[N][N] , int n)
{bool res = false;//初始化棋盘error_board(board,n);//初始化create_board(board,n);//打印棋盘//下棋while(1){res = play_game(board,n);//玩家下棋create_board(board,n);//打印棋盘if(res == true){create_board(board,n);win_1();break;	}    res = play_game_2(board,n);//电脑下棋create_board(board,n);//打印棋盘if(res == true){create_board(board,n);win_2();break;}else if(is_full(board,n)){cout << "棋盘已经被填满,本局平局" << endl;break;}}
}
//游戏流程循环
void game_2(char board[N][N] , int n)
{bool res = false;//初始化棋盘error_board(board,n);//初始化create_board(board,n);//打印棋盘//下棋while(1){cout << "请在0-n之间输入数据" << endl;res = play_game(board,n);//玩家下棋create_board(board,n);//打印棋盘if(res == true){create_board(board,n);win_1();break;	}    res = computer_game(board,n);//电脑下棋create_board(board,n);//打印棋盘if(res == true){create_board(board,n);win_computer();break;}else if(is_full(board,n)){cout << "棋盘已经被填满,本局平局" << endl;break;}}
}
int main()
{menu();while(1){int a;int res;cin >> a;//输入模式if(a == 1)//玩家对弈{while(1){choose();int n;cin >> n;if(n < 6 || n > 100){cout << "请重新输入棋盘大小" << endl;}else{game_1(board,n);end();int res;cin >> res;if(res == 2)break;}	}	if(res == 2){choose_3();break;}}else if(a == 2)//电脑对弈{while(1){choose();int n;cin >> n;if(n < 6 || n > 100){cout << "请重新输入棋盘大小" << endl;}else{game_2(board,n);end();cin >> res;if(res == 2)break;					}	}	if(res == 2){choose_3();break;}}else if(a == 3)//退出{choose_3();break;}else {cout << "不满足,请重新输入" << endl;}}return 0;	
}

 

  • 运行结果

 

  • 结果分析与结论

这套程序有很多不足的地方

  1. 棋盘的画法不够美观,可以利用Turbo c的图形库画图
  2. 电脑下棋不够难度,随机性强,可以通过DFS判断当连通性为3的情况进行补位
  3. 判断胜利不够高效,时间复杂度很高,n^2的递归暴搜非常慢

可以适当的利用graphics.h以及conio.h头文件画图并加入一些更为高效的算法优化判断

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

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

相关文章

Fiddler抓不到包

fiddler该设置的设置好之后&#xff0c;为啥就是抓不到包 以下都是以谷歌浏览器为例子 方法一&#xff1a; 将fidder证书导入到浏览器&#xff0c;设置搜索证书-->安全-->管理证书 这里可以看到将证书导入之后样子&#xff0c;名字为&#xff1a;DO_NOT_TRUST_Fiddler…

Linux操作系统裸机开发-环境搭建

一、配置SSH服务 1、下载安装ssh服务输入以下命令 sudo apt-get install nfs-kernel-server portmap2、建立一个供SSH服务使用的文件夹如以下命令 mkdir linux 3、完成前两步之后需要将其文件路径放到/etc/exports文件里输入以下命令&#xff1a; sudo vi /etc/esports 4.打…

线性回归 quickstart

构建一元一次方程 100个&#xff08;X, y &#xff09;&#xff0c;大概是’y3x4’ import numpy as npnp.random.seed(42) # to make this code example reproducible m 100 # number of instances X 2 * np.random.rand(m, 1) # column vector y 4 3 * X np.random…

最详细数据仓库项目实现:从0到1的电商数仓建设(数仓部分)

1、数仓 数据仓库是一个为数据分析而设计的企业级数据管理系统&#xff0c;它是一个系统&#xff0c;不是一个框架。可以独立运行的&#xff0c;不需要你参与&#xff0c;只要运行起来就可以自己运行。 数据仓库不是为了存储&#xff08;但是能存&#xff09;&#xff0c;而是…

创业板指399006行情数据API接口

# 测试&#xff1a;返回不超过10条数据&#xff08;2年历史&#xff09; https://tsanghi.com/api/fin/index/CHN/daily?tokendemo&ticker399006&order2Python示例 import requestsurl f"https://tsanghi.com/api/fin/index/CHN/daily?tokendemo&ticker399…

EtherCAT 开源主站 IGH 在 linux 开发板的移植和伺服通信测试

手边有一套正点原子linux开发板imax6ul&#xff0c;一直在吃灰&#xff0c;周末业余时间无聊&#xff0c;把EtherCAT的开源IGH主站移植到开发板上玩玩儿&#xff0c;搞点事情做。顺便学习研究下EtherCAT总线协议及其对伺服驱动器的运动控制过程。实验很有意思&#xff0c;这里总…

【JDBC编程】 Java程序操作数据库

目录 一、数据库编程的必备条件 二、什么是JDBC&#xff1f; 三、JDBC的使用 1. 准备工作 2. 建立数据库连接 2.1 加载驱动程序 2.2 数据库连接池技术 3. 正式操作 四、JDBC的局限性与MyBatis的优势 一、数据库编程的必备条件 编程语言&#xff0c;如Java&#xff0…

创业新手看过来!四招助你开启成功之旅

如果你每个月的薪资仅有几千块&#xff0c;还背负着债务的重担&#xff0c;家中的老少都期盼着你为他们撑起一片天&#xff0c;那么&#xff0c;你每日都可能为了如何打破这一困境而焦虑不安。不过&#xff0c;请稍安勿躁&#xff0c;今天我将为你提供四个建议&#xff0c;或许…

Transformer学习笔记(二)

一、文本嵌入层Embedding 1、作用&#xff1a; 无论是源文本嵌入还是目标文本嵌入&#xff0c;都是为了将文本中词汇的数字表示转变为向量表示&#xff0c;希望在这样的高维空间捕捉词汇间的关系。 二、位置编码器Positional Encoding 1、作用&#xff1a; 因为在Transformer…

解锁区块链游戏数据解决方案

作者&#xff1a;stellafootprint.network 随着区块链技术的日新月异&#xff0c;游戏行业正迎来一场革命&#xff0c;催生了区块链游戏的崛起。这一变革不仅为用户带来了全新的互动体验&#xff0c;也开辟了全新的盈利渠道。然而&#xff0c;在这一新兴领域&#xff0c;数据的…

html--花瓣

代码 <!DOCTYPE html> <html lang"en" ><head> <meta charset"UTF-8"> <title>Petals</title><link rel"stylesheet" href"css/style.css"></head><body><div class"…

Jpg图片变gif怎么操作?1分钟教你在线生成

jpg是一种常见的图像文件格式&#xff0c;它使用有损压缩算法来减小文件大小。这意味着JPG图像可以在保持较高质量的同时减小文件大小&#xff0c;但会导致一些细节的损失。JPG图像适用于存储照片和其他需要高质量图像的场景。而GIF是一种支持动画的图像文件格式。与JPG不同&am…

【类脑智能】脑网络通信模型分类及量化指标(附思维导图)

脑网络通信模型分类及量化指标(附思维导图) 参考论文&#xff1a;Brain network communication_ concepts, models and applications 概念 脑网络通信模型是一种使用图论和网络科学概念来描述和量化大脑结构中信息传递的模型。这种模型可以帮助研究人员理解神经信号在大脑内…

管理类联考–复试–政治--二十大--记忆宫殿

文章目录 整体记忆宫殿门床头柜床书桌阳台 口诀记忆法 整体 记忆宫殿 要有逻辑的放到房间了 何为逻辑&#xff0c;如下大佬总结的便是&#xff0c;或者可自行总结&#xff0c;有前后顺序&#xff0c;做事逻辑即可 第一步&#xff1a;将逻辑的点放到房间里的点&#xff0c;…

CASA模型在陆地生态系统碳循环研究中的应用探讨

植被&#xff0c;作为陆地生态系统的重要基石&#xff0c;对维护生态环境功能具有不可替代的作用。其中&#xff0c;植被净初级生产力&#xff08;NPP&#xff09;是衡量植被生态系统健康与功能的关键指标。它反映了单位面积上绿色植被通过光合作用生产的有机质总量在扣除自养呼…

基于springboot实现房源出租信息系统项目【项目源码+论文说明】

基于springboot实现房源出租信息系统演示 摘要 近些年来在一线城市的房子需求量在逐步递增&#xff0c;其中租房子和出租房子的需求业务不断增加。那么租房对于我们一线二线城市来说是一个非常大&#xff0c;而且具有经济提升能力的业务场景。那么信息技术在此行业的加持早已是…

SwiftUI自定义ButtonStyle

SwiftUI自定义ButtonStyle 记录一下如何通过自定义SwiftUI自定义ButtonStyle&#xff0c;来给按钮设计一个点击样式 import SwiftUI /*本文章 通过创建ButtonStyle&#xff0c;来自定义按钮的点击动画*/struct PressButtonStyle: ButtonStyle {func makeBody(configuration: …

2024-03-14 Android app runOnUiThread 函数,它的作用是让一个Runnable对象在主线程(UI线程)上运行。

一、看到别人app有这么一个runOnUiThread 函数用法。 二、在Android中&#xff0c;runOnUiThread 是一个非常重要的方法&#xff0c;它的作用是让一个Runnable对象在主线程&#xff08;UI线程&#xff09;上运行。在Android中&#xff0c;主线程是负责更新UI的线程&#xff0c;…

【JVM】GCRoot

GC root原理 通过对枚举GCroot对象做引用可达性分析&#xff0c;即从GC root对象开始&#xff0c;向下搜索&#xff0c;形成的路径称之为 引用链。如果一个对象到GC roots对象没有任何引用&#xff0c;没有形成引用链&#xff0c;那么该对象等待GC回收。 可以作为GC Roots的对…

基于SSM SpringBoot vue办公自动化计划管理系统

基于SSM SpringBoot vue办公自动化计划管理系统 系统功能 登录注册 个人中心 员工信息管理 部门信息管理 会议管理 计划管理 行程安排管理 行程进度管理 管理员管理 开发环境和技术 开发语言&#xff1a;Java 使用框架: SSM(Spring SpringMVC Mybaits)或SpringBoot 前端…