⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.cpp

📁 使用VC。NET2005串行实现著名的细胞自动机程序:生命游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			NewCell=(&matrix+(i*cols+(j-1+COLUMN)%COLUMN));
			break;
		case UP:    //上侧
			NewCell=(&matrix+((i-1)*cols+j));
			break;
		}
        *NewCell=*OrientCell;  //改变选定的细胞

		OrientCell->Type=0;  //清空原来鲨鱼的空间
		OrientCell->Age=0;
		OrientCell->StarvationTime=0;
	}
	else   //鲨鱼没有鱼吃
	{
		(&matrix+(i*cols+j))->StarvationTime++;  //饥饿时间增加一
		if((&matrix+(i*cols+j))->StarvationTime==SHARK_STARVE_SPAN)  //如果鲨鱼的饥饿时间到达生命极限
		{
			(&matrix+(i*cols+j))->Type=0;;  //清空原来鲨鱼的空间
			(&matrix+(i*cols+j))->Age=0;
			(&matrix+(i*cols+j))->StarvationTime=0;  //鲨鱼由于没有食物而被饿死
		}
	}
	return SUCCEED;
}

void Move(Cell &matrix,int rows,int cols,int i,int j,int MoveDirection,MPI_Datatype MsgType,MPI_Datatype CellType)  //细胞进行移动
{
    if(MoveDirection!=NOWHERE_TO_MOVE)  //有方向可以移动
	{	
		Cell* OrientCell=(&matrix+(i*cols+j));//定义旧细胞位置的地址,并赋予现在细胞的地址
		Cell* NewCell; //定义新细胞位置的地址,用于后面的操作

		switch(MoveDirection)  //查找所选的移动方向
		{
		case RIGHT:   //向右移动
			NewCell=(&matrix+(i*cols+(j+1)%COLUMN));  //获取需要修改的细胞空间的地址
			break;
		case DOWN:    //向下移动
			NewCell=(&matrix+((i+1)*cols+j));
			break;
		case LEFT:    //向左移动
			NewCell=(&matrix+(i*cols+(j-1+COLUMN)%COLUMN));
			break;
		case UP:      //向上移动
			NewCell=(&matrix+((i-1)*cols+j));
			break;
		}
        *NewCell=*OrientCell;  //改变选定的细胞
                                           //在不同情况下处理原来的细胞,例如生育问题
		if(OrientCell->Type==SHARK_TYPE)   //移动的是一条鲨鱼,在移动中处理生育问题
		{
			if((OrientCell->Age!=0)&&((OrientCell->Age%SHARK_BORN_AGE)==0))
			{    //鲨鱼到了生育年龄
				OrientCell->Type=0;;  //清空原来鲨鱼的空间
				OrientCell->Age=0;
				OrientCell->StarvationTime=0;
				OrientCell->Type=SHARK_TYPE; //设置新的鲨鱼属性
			}
			else
			{    //如果没有到达生育年龄
				OrientCell->Type=0;;  //清空原来鲨鱼的空间
				OrientCell->Age=0;
				OrientCell->StarvationTime=0; 
			}
		}
		else if(OrientCell->Type==FISH_TYPE)  //移动的是一条小鱼,在移动中处理生育问题
		{
			if((OrientCell->Age!=0)&&((OrientCell->Age%FISH_BORN_AGE)==0))
			{    //小鱼到达生育年龄
				OrientCell->Type=0;;  //清空原来鱼的空间
				OrientCell->Age=0;
				OrientCell->StarvationTime=0;
                OrientCell->Type=FISH_TYPE;   //设置新的小鱼属性
			}
			else
			{    //如果没有到达生育年龄
				OrientCell->Type=0;;  //清空原来鱼的空间
				OrientCell->Age=0;
				OrientCell->StarvationTime=0;
			}
		}

	}
}
void Action(struct CellNode* List,Cell &matrix,int rows,int cols,int TYPE,MPI_Datatype MsgType,MPI_Datatype CellType)  //海洋生物的行动
{
	Cell* CurrentCell;
	if(TYPE==SHARK_TYPE)  //如果是鲨鱼类型
	{
		struct CellNode* SharkNode=GetCell(List);  //获得第一个鲨鱼节点
	    while(SharkNode)  //当节点非空则进行循环
		{
			int i=SharkNode->x; //获得鲨鱼节点位置信息
			int j=SharkNode->y;
			SharkNode->NodeElem->Age++;  //鲨鱼年龄增长一个时间单位
			CurrentCell=(&matrix+(i*cols+j));//获取现在正在操作的细胞地址

			if(SharkNode->NodeElem->Age==SHARK_LIFE_SPAN)  //如果鲨鱼到达生命极限
			{
				CurrentCell->Type=0;;  //清空原来鲨鱼的空间
				CurrentCell->Age=0;
				CurrentCell->StarvationTime=0;  //鲨鱼死亡
			}
			int EatDirection=RandEatDiretion(matrix,rows,cols,i,j);  //获得可以吃的鱼
			EatFish(matrix,rows,cols,i,j,EatDirection,MsgType,CellType);  //吃所选择的鱼
			if(EatDirection==NOTHING_TO_EAT)  //如果没有鱼可以吃
			{
				int MoveDirection=RandMoveDiretion(matrix,rows,cols,i,j); //选择可以移动的方向
				if(NOWHERE_TO_MOVE!=MoveDirection)  //如果有空间进行移动
					Move(matrix,rows,cols,i,j,MoveDirection,MsgType,CellType);  //鲨鱼按照所选方向移动
				else   //没有空间移动
				{
					CurrentCell->Type=0;;  //清空原来鲨鱼的空间
					CurrentCell->Age=0;
					CurrentCell->StarvationTime=0;  //鲨鱼由于密度太大而死
				}
			}
			SharkNode=GetCell(List); //获得下一个细胞节点
		}
	}
	else if(TYPE==FISH_TYPE)  //如果是小鱼类型
	{
        struct CellNode* FishNode=GetCell(List);  //获得第一个小鱼节点信息
	    while(FishNode)    //当节点非空则进行循环
		{
			if(FishNode->NodeElem->Type==FISH_TYPE)  //《注意》原来存储的小鱼节点可能已经
			{                                 //被鲨鱼吃掉而换成了鲨鱼类型,这里处理没有改变的节点
				int i=FishNode->x;  //获得节点位置信息
				int j=FishNode->y;
				FishNode->NodeElem->Age++;  //小鱼年龄增加一个时间单位
				CurrentCell=(&matrix+(i*cols+j));//获取现在正在操作的细胞地址

				if(FishNode->NodeElem->Age==FISH_LIFE_SPAN)  //如果小鱼到达生命极限
				{
					CurrentCell->Type=0;;  //清空原来的空间
					CurrentCell->Age=0;
					CurrentCell->StarvationTime=0;  //小鱼死亡
				}
				int MoveDirection=RandMoveDiretion(matrix,rows,cols,i,j);  //随机选择移动的方向
				if(NOWHERE_TO_MOVE!=MoveDirection)  //如果有空间可以移动
					Move(matrix,rows,cols,i,j,MoveDirection,MsgType,CellType);  //移动到新的位置
				else   //没有空间移动
				{
					CurrentCell->Type=0;;  //清空原来鱼的空间
					CurrentCell->Age=0;
					CurrentCell->StarvationTime=0;  //小鱼由于密度太大而死亡
				}
			}
			FishNode=GetCell(List);  //获得下一个细胞节点
		}
	}

}

int InBoundary(int row,int x)   //判定细胞是否在边界区域,并确定返回所在区域编号
{
	if((x>1)&&(x<row-2))   //在获得的区域内从第三行到倒数第三行属于内部区域
	{
        return IN_WORKFIELD;  //返回工作区域编号
	}
    else if((x<=1)&&(x>=0))  //在获得区域的前两行属于上边界
	{
		return IN_UP_BOUNDARY;  //返回上边界的编号
	}
	else if((x>=row-2)&&(x<=row-1))  //在获得区域的最后两行属于下边界
	{
		return IN_BOTTOM_BOUNDARY;  //返回下边界的编号
	}

	return -1;  //错误!输入的坐标不在所获区域内!
}

void DealApplication(Cell & GotData,int x,int y,int rank,MPI_Datatype MsgType,MPI_Datatype CellType)
{
    MPI_Status status;//定义进程状态
    Msg msg; //定义消息变量
    int pos[2];  //定义索要数据的坐标
	pos[0]=x; //给坐标附值
	pos[1]=y;
	msg.Type=MSG_APPLICATION;  //子进程完成工作向主进程发送申请消息
	msg.Source=rank; //设置消息源
	MPI_Send(&msg,1,MsgType,0,rank,MPI_COMM_WORLD);//发送申请
	MPI_Recv(&msg,1,MsgType,0,0,MPI_COMM_WORLD,&status); //接收同意或拒绝的消息回复
	if(MSG_AGREE==msg.Type)//如果主进程同意发送
	{
	    MPI_Send(&pos,2,MPI_INT,0,rank,MPI_COMM_WORLD); //向主进程发送数据坐标
		MPI_Recv(&GotData,1,CellType,0,0,MPI_COMM_WORLD,&status);//接受主进程发来的数据信息
		cout<<"("<<GotData.Type<<","<<GotData.Age<<","<<GotData.StarvationTime<<")"<<"("<<pos[0]<<","<<pos[1]<<")"<<endl;
	}
}

void PosMap(int &x,int &y,int i,int j)//把子进程数据的坐标映射成主进程数据的坐标
{
	int rank,size,workAmount;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);//获得进程号
    MPI_Comm_size(MPI_COMM_WORLD, &size);//获得进程总数
	workAmount=(int)((double)ROW/(size-1)+.5); //平均分配子进程工作量(均分上取整)
	x=(rank-1)*workAmount+i; //映射坐标
	y=j;
}

bool SelfCheck(Cell &matrix,int rows,int cols,int i,int j,Cell &Self)
{
	if((&matrix+(i*cols+j))->Type==Self.Type)
		if((&matrix+(i*cols+j))->Age==Self.Age)
			if((&matrix+(i*cols+j))->StarvationTime==Self.StarvationTime)
				return true;
	return false;
}

void UpDateSubData(Cell &matrix,int rows,int cols,int i,int j,Cell &Self)
{
	(&matrix+(i*cols+j))->Type=Self.Type;
	(&matrix+(i*cols+j))->Age=Self.Age;
	(&matrix+(i*cols+j))->StarvationTime=Self.StarvationTime;
}

void UpDateMainData()
{

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -