/*捕食者与被捕食者求大神解题C++.*/


创建简单的二维“捕食者-被捕食者”模拟。在这个模拟中,被捕食者是蚂蚁(ant),捕食者是狮蚁(doodlebug)。这些小生物生活在20×20的网格中。每个单元格每次只能由一个个体占据。网格是封闭的,所以个体不允许离开世界边缘。时间以time step为单位。个体在每个time step里面都要采取某项行动。
蚂蚁的行为像下面这样建模。
Move(移动):在每个time step中,都随机向上、向下、向左或者向右移动。假如所选方向上的邻居单元格被占据,或者会造成蚂蚁移动到网格的边缘之外,那么蚂蚁就停留在当前的单元格中。
Breed(繁殖):如果一只蚂蚁在3个time step中保存存活,在第3个time step结束之后(也就是在移动之后),该蚂蚁会繁殖。为了模拟繁殖,需要在相邻(上、下、左或者右)的一个空单元格中创建一只新蚂蚁。没有可用的空单元格,就不会繁殖。一旦成功繁殖出后代,除非再次经历3个time step,否则不能繁殖另一个后代。


狮蚁的行为像下面这样建模。
Move(移动):在每个time step中,假如有一只相邻的蚂蚁(上、下、左或者右),就移动到那个单元格,吃掉蚂蚁。否则,狮蚁就按照和蚂蚁相同的规则移动。注意,狮蚁不能吃掉狮蚁。
Breed(繁殖):假如一只狮蚁在8个time step中保持存活,在第8个time step结束之后,会按照与蚂蚁相同的方式繁殖出一只新狮蚁。
Starve(饥饿):假如一只狮蚁在连续3个time step中没有吃掉一只蚂蚁,在第3个time step结束之后,它会感到饥饿并死亡。该狮蚁应从网格中拿掉。
 在一轮中,所有狮蚁都应该先于蚂蚁移动。
 
写程序来实现这个模拟,使用ASCII字符“o”表示蚂蚁,“x”表示狮蚁。创建名为Organism(有机生物)的类,它封装了通用于蚂蚁和狮蚁的基本数据。该类应该有一个名为Move的virtual函数,它要在派生类Ant和Doodlebug中进行具体的定义。可能需要额外的数据结构来跟踪已移动的生物。
 使用5只狮蚁和100只蚂蚁初始化这个世界。在每个time step后,都提示用户按Enter键移动到下一个time step。应该看到狮蚁和蚂蚁数量的循环变化——虽然一些随机性的混乱可能造成一种或两种生物的毁灭。


/*无论多复杂的问题都从最简单最容易想到的地方下手:
	1.首先创建二维数组表示世界动物类容器 世界[20][20] = {};
	2.struct 蚁类{char 名称 int 繁殖; int 饥饿; bool 移标 = false; };
	3.初始化两种动物随机分布,需要随机产生2个数表示数组维度序号int a = rand() % 20,b = rand() % 20;同时检测是否已经赋值以完成初始化随机分布。
	4.移动判断:如果数组元素不等于空,则固定二维中的一维并使另一维序++或--交替去完成或二维各+1或-1形成八个方向移动,四方或八方选择int 八方[8][2]={{0,1},{1,0},{1,1},{0,-1},{-1,0},{-1,-1},{1,-1},{-1,1}}rand() % 4。
	5.狮蚁生存判断:5.1吃蚂蚁判断:有吃则饥饿为0, 5.2饥饿判断:取值判断
	6.繁殖判断:时间步判断
	其实对写游戏没兴趣,不过消磨时间倒是玩别人写的游戏,哈哈;这是第一次对这种题目有点兴趣,所以,还是花费了点时间和精力进行构思和调试,以上基本实现从初步分析和后来推敲来写这个程序,注释掉的繁殖语句,还没写的狮蚁处理函数,或许什么时候有心情了会补充完整,发布在博客中。
	*/
	void 随机种子()
{
	time_t now;
	time(&now);
	srand((unsigned int)now);
}
int *方向(int 维)
{
	static int 八方[8][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 }, { 1, 1 }, { -1, -1 }, { 1, -1 }, { -1, 1 } };
	return 八方[维];
}
struct 蚁类{ char 名称 = '.'; int 繁殖 = 0; int 饥饿 = 0; bool 移标 = false; };
void 随即分布数组(蚁类 数组[20][20], int 数量, char 名称 = '!')
{
	随机种子();
	do
	{
		int 一维 = rand() % 20, 二维 = rand() % 20;
		if (数组[一维][二维].名称 == '.')
		{
			数组[一维][二维].名称 = 名称;
			数量--;
		}
	} while (数量);
}
void 显示蚁数组(蚁类 数组[20][20])
{
	int 一维(0), 二维(0);
	do
	{
		std::cout << 数组[一维][二维++].名称;
		if (二维 > 19)
		{
			二维 = 0;
			一维++;
			std::cout << endl;
		}
	} while (一维 < 20);
}
void 蚂蚁动作(蚁类 数组[20][20], bool 移动判断)
{
	随机种子();
	int 一维(0), 二维(0);
	do
	{
		int 移动 = rand() % 8, 移向1 = 一维 + 方向(移动)[0], 移向2 = 二维 + 方向(移动)[1];
		蚁类 移点 = 数组[一维][二维], 移格;
		if (移向1 >= 0 && 移向1 < 20)if (移向2 >= 0 && 移向2 < 20)/*移动在界内*/
		{
			移格 = 数组[移向1][移向2];
			if (移点.名称 == '|')/*蚂蚁*/
			{
				if (移格.名称 == '!')/*被吃掉*/
				{
					数组[一维][二维] = 蚁类();
					数组[移向1][移向2].饥饿 = 0;
					移点.移标 = 移动判断 ? false : true;
					//continue;
				}
				if (移格.名称 == '.' && 移动判断 == 移点.移标)/*移动*/
				{
					数组[移向1][移向2] = 移点;
					数组[移向1][移向2].繁殖++;
					数组[移向1][移向2].移标 = 移动判断 ? false : true;
					if (数组[移向1][移向2].繁殖 >= 3)/*新生*/
					{
						数组[一维][二维].繁殖 = 0;
						数组[一维][二维].移标 = 移动判断 ? false : true;
						数组[移向1][移向2].繁殖 = 0;
					}
					else
						数组[一维][二维] = 蚁类();
				}
			}
		}
		else
		{
			数组[一维][二维].繁殖++;
			数组[一维][二维].饥饿++;
			数组[一维][二维].移标 = 移动判断 ? false : true;
		}
		if (移点.名称 == '!')/*狮蚁*/
		{
			if (移动判断 == 移点.移标)
			{
				int 周围(8);
				do
				{
					移向1 = 一维 + 方向(周围 - 1)[0], 移向2 = 二维 + 方向(周围 - 1)[1];
					if (移向1 >= 0 && 移向1 < 20)if (移向2 >= 0 && 移向2 < 20)/*移动在界内*/
						移格 = 数组[移向1][移向2];
					else continue;
					if (移格.名称 == '|')/*吃+繁殖*/
					{
						数组[移向1][移向2] = 移点;
						数组[移向1][移向2].繁殖++;
						数组[移向1][移向2].饥饿 = 0;
						数组[移向1][移向2].移标 = 移动判断 ? false : true;
						if (数组[移向1][移向2].繁殖 >= 8)
						{
							数组[一维][二维].繁殖 = 0;
							数组[一维][二维].饥饿 = 0;
							数组[一维][二维].移标 = 移动判断 ? false : true;
							数组[移向1][移向2].繁殖 = 0;
						}
						else
							数组[一维][二维] = 蚁类();
						移点.移标 = 移动判断 ? false : true;
						break;
					}
				} while (--周围);
			}
			if (移动判断 == 移点.移标)
			{
				移动 = rand() % 8, 移向1 = 一维 + 方向(移动)[0], 移向2 = 二维 + 方向(移动)[1];
				if (移向1 >= 0 && 移向1 < 20)if (移向2 >= 0 && 移向2 < 20)/*移动在界内*/
				{
					移格 = 数组[移向1][移向2];
					if (移格.名称 == '.')/*移动+繁殖*/
					{
						数组[移向1][移向2] = 移点;
						数组[移向1][移向2].繁殖++;
						数组[移向1][移向2].饥饿++;
						数组[移向1][移向2].移标 = 移动判断 ? false : true;
						if (移格.繁殖 >= 8)
						{
							数组[一维][二维].繁殖 = 0;
							数组[一维][二维].饥饿 = 0;
							数组[一维][二维].移标 = 移动判断 ? false : true;
							数组[移向1][移向2].繁殖 = 0;
						}
						else
							数组[一维][二维] = 蚁类();
					}
				}
				else
				{
					数组[一维][二维].繁殖++;
					数组[一维][二维].饥饿++;
					数组[一维][二维].移标 = 移动判断 ? false : true;
				}
			}
			if (数组[移向1][移向2].饥饿 >= 3)/*饥饿并死亡*/
				数组[移向1][移向2] = 蚁类();
			if (数组[一维][二维].饥饿 >= 3)/*饥饿并死亡*/
				数组[一维][二维] = 蚁类();
		}
		if (++二维 > 19){ 二维 = 0; ++一维; }
	} while (一维 < 20);
	std::cout << endl;/*基本实现题目功能,没更细节去调试逻辑,看得眼花;如果对逻辑有怀疑,可以单独生成1只蚂蚁进行调试移动 繁殖 被吃,正确后生成1只狮蚁进行调试移动 繁殖 吃蚂蚁 饥饿等.*/
}


	蚁类 蚁[20][20];
	随即分布数组(蚁,100, '|');
	随即分布数组(蚁, 5);
	显示蚁数组(蚁);


	int 步伐(2000); bool 移动判断 = false;
	do
	{
		蚂蚁动作(蚁, 移动判断);
		移动判断 = 移动判断 ? false : true;
		system("cls");
		显示蚁数组(蚁);
		Sleep(1000);
	} while (--步伐);


  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值