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

news2024/11/18 17:21:14
  • 实验目的

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

  • 实验内容

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

  • 分析与设计

设计棋盘:使用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;
			}
			else
			    cout << "该点已经下过,请您重新下谢谢" << 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;
			}
			else
			    cout << "该点已经下过,请您重新下谢谢" << 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;
			}
			else
			    cout << "该点已经下过,请您重新下谢谢" << 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;
			}
			else
			    cout << "该点已经下过,请您重新下谢谢" << 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.coloradmin.cn/o/1514863.html

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

相关文章

S4 Hana SD -信贷管理 - 02

2.3 给信贷控制范围分配公司代码 TCODE: SPRO 配置路径:IMG > 企业结构 > 分配 > 财务会计 > 给信贷控制区分配公司代码 配置路径截图: 公司:被分配的公司代码。 公司名称&城市:已在公司代码数据中维护。 CCAR:分配的信贷控制范围。 覆盖CC范围:如…

InstantID Zero-shot Identity-Preserving Generation in Seconds

InstantID: Zero-shot Identity-Preserving Generation in Seconds TL; DR&#xff1a;InstantID IP-Adapter (Face) ControlNet&#xff0c;实现了具有较高保真度的人脸 ID 生成。 方法 InstantID 想做到的事情是&#xff1a;给定一张参考人脸 ID 图片&#xff0c;生成该…

专升本 C语言笔记-07 逗号运算符

1.逗号表达式的用法 就是用逗号隔开的多个表达式。逗号表达式&#xff0c;从左向右依次执行。 2.逗号表达式的特性 2.1.当没有括号时&#xff0c;第一个表达式为整个表达式的值。 代码 int x 3,y 5,a 0; a x,y; printf("a %d",a); 说明:因为逗号优先级最低,会…

利用Python进行网络爬虫:Beautiful Soup和Requests的应用【第131篇—Beautiful Soup】

利用Python进行网络爬虫&#xff1a;Beautiful Soup和Requests的应用 在网络数据变得日益丰富和重要的今天&#xff0c;网络爬虫成为了获取和分析数据的重要工具之一。Python作为一种强大而灵活的编程语言&#xff0c;在网络爬虫领域也拥有广泛的应用。本文将介绍如何使用Pyth…

【智能硬件、大模型、LLM 智能音箱】MBO:基于树莓派、ChatGPT 的桌面机器人

MAKER:David Packman/译:趣无尽(转载请注明出处) 这是国外 Maker David Packman 制作的基于树莓派机器人 MBO,该机器人的外观设计灵感来自动漫 Adventure Time 中的机器人 MBO。它具有强大的交互功能,可实现脱机唤醒词检测、调用 ChatGPT 3.5 进行聊天、机器视觉对图像进…

解决Git:Author identity unknown Please tell me who you are.

报错信息&#xff1a; 意思&#xff1a; 作者身份未知 ***请告诉我你是谁。 解决办法&#xff1a; git config --global user.name "你的名字"git config --global user.email "你的邮箱"

Android 15 首个开发者预览版到来

作者 / 工程副总裁 Dave Burke Android 15 的首个开发者预览版现已发布&#xff0c;以便各位开发者能与我们通力协作&#xff0c;打造更优秀的 Android 平台。 在 Android 15 中&#xff0c;我们继续致力于打造一个既能提升工作效率&#xff0c;又能提供全新功能的平台。这些新…

蓝桥杯-模拟-4402. 刷题统计

题目 思路 代码 a,b,nmap(int,input().split()) sa*5b*2 resn//s*7 # 存在周期 d[a,a,a,a,a,b,b] n%s i0 while n>0: # 对剩余数量进行枚举&#xff0c;如果等于0&#xff0c;相当于还会再进去加一天n-d[i]i1res1 print(res)

es 聚合操作(一)

前言 Elasticsearch除搜索以外&#xff0c;提供了针对ES 数据进行统计分析的功能。聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 衣服品牌的受欢迎程度这些衣服的平均价格、最高价格、最低价格这些衣服的每天、每月销量如何 使用…

cpp qt 一个奇怪的bug

今天在用cpp qt的时候发现了一个奇怪的东西 这是我的源代码 #include "mywidget.h" #include <QPushButton>myWidget::myWidget(QWidget *parent): QWidget(parent) {QPushButton * btn1 new QPushButton;btn1->show();btn1->setParent(this);btn1-&g…

在集群模式下,Redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

目录 一、分布式寻址算法 1. hash 算法 2. 一致性 hash 算法 3. Redis cluster 的 hash slot 算法 二、Redis cluster 的高可用与主备切换原理 1. 判断节点宕机 2. 从节点过滤 3. 从节点选举 4. 与哨兵比较 一、分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash…

【代码随想录 | 链表 02】反转链表

文章目录 2.反转链表2.1题目2.2解法2.2.1双指针法2.2.2递归法 2.反转链表 2.1题目 206.反转链表——力扣链接 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例一&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;…

重建大师出现图中密集匹配失败的情况,是什么原因导致的?

可以检查瓦块是否位于测区边缘&#xff0c;边缘瓦块可以忽略&#xff1b;如果是中间区域的话&#xff0c;可能中间文件有异常&#xff0c;可以新建个reconstruction&#xff0c;然后单独提交失败的瓦块。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&…

数据结构:7、队列

一、队列的概念与结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾 出队列&#xff1a;进行删除操作的一端称为队头…

Cisco Packet Tracer模拟器实现路由器的路由配置及网络的安全配置

1. 内容 1. 配置路由器实现多个不同网络间的通信&#xff0c;路由器提供的路由协议包括静态路由协议、RIP动态路由、OSPF动态路由协议等等&#xff0c;训练内容包括路由器的静态路由配置、路由器的RIP动态路由配置、路由器的OSPF动态路由配置以及路由器的路由重分布配置。 2.…

Css基础——溢出文字省略号表达

1. 单行文本溢出显示省略号&#xff1a; 1.1、方法&#xff1a; 1. 先强制一行内显示文本*/ white-space: nowrap; &#xff08; 默认 normal 自动换行&#xff09; 2. 超出的部分隐藏*/ overflow: hidden; 3. 文字用省略号替代超出的部分*/ text-overflow: ellipsis; 1.2、代…

实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)

导 读 本文主要介绍使用YOLOv9和OpenCV实现车辆跟踪计数&#xff08;步骤 源码&#xff09;。 实现步骤 监控摄像头可以有效地用于各种场景下的车辆计数和交通流量统计。先进的计算机视觉技术&#xff08;例如对象检测和跟踪&#xff09;可应用于监控录像&#xff0c;…

单调队列 维护区间最值(板子+两道练手)

1.P1886 滑动窗口 /【模板】单调队列https://www.luogu.com.cn/problem/P1886 板子题&#xff0c;传送门在上方 // Problem: // P1886 滑动窗口 /【模板】单调队列 // // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P1886 // Memory Limit: 500 MB //…

Zookeeper3.5.9源码编译和启动

目录 参考链接1. 下载源码2. 准备更高版本的JDK和Maven环境Java 8Maven 3.6.3 3. 用IDEA打开项目进行编译和启动3.1. 设置maven版本3.2. 设置JDK版本为1.83.3. 切换 Maven profiles 选项到 java-build3.4. 执行 Ant build 生成和编译Java文件3.4.1. 执行ant build-generated而非…

微信小程序之vue按钮切换内容变化

效果图如下&#xff1b; 上代码 <template><view class"content"><view class"searchDiv"><view class"paytab"><view class"buttab" v-for"(t,index) in tabList" :key"index" clic…