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

📄 func.cpp

📁 使用VC。NET2005串行实现著名的细胞自动机程序:生命游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "Life.h"

void SeaInit(Cell &matrix,int rows,int cols)   //随机初始化海域生物
{
	srand( (unsigned)time( NULL ) );   //设置随机种子
//    system("cls");  //清空屏幕
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
            int RAND_SPAN=rand()%10;  //获得随机数
			if((RAND_SPAN>=0)&&(RAND_SPAN<5))  //如果随机数在范围一中
			{
				(&matrix+(i*cols+j))->Type=FISH_TYPE;  //设置细胞为小鱼类型
				(&matrix+(i*cols+j))->Age=0;
				(&matrix+(i*cols+j))->StarvationTime=0;
			}
			else if((RAND_SPAN>=5)&&(RAND_SPAN<7))  //如果随机数在范围二中
			{
				(&matrix+(i*cols+j))->Type=SHARK_TYPE; //设置细胞为鲨鱼类型
				(&matrix+(i*cols+j))->Age=0;
				(&matrix+(i*cols+j))->StarvationTime=0;
			}
			else                               //其余情况
			{
				(&matrix+(i*cols+j))->Type=EMPTY;   //设置细胞为空白区域
				(&matrix+(i*cols+j))->Age=0;
				(&matrix+(i*cols+j))->StarvationTime=0;
			}
		}
	}
}

void OutPutSea(Cell &matrix,int rows,int cols)   //输出海域的状态
{
	  //输出细胞状态
 //   for(int i=0;i<rows;i++)
	//{
	//	for(int j=0;j<cols;j++)
	//	{
	//		if(IN_WORKFIELD==InBoundary(rows,i))
	//		cout<<"["<<(&matrix+(i*cols+j))->Type<<","<<(&matrix+(i*cols+j))->Age<<","<<(&matrix+(i*cols+j))->StarvationTime<<"]";
	//		else if(IN_UP_BOUNDARY==InBoundary(rows,i))
	//		    cout<<"<"<<(&matrix+(i*cols+j))->Type<<","<<(&matrix+(i*cols+j))->Age<<","<<(&matrix+(i*cols+j))->StarvationTime<<">";
 //           else if(IN_BOTTOM_BOUNDARY==InBoundary(rows,i))
	//			cout<<"{"<<(&matrix+(i*cols+j))->Type<<","<<(&matrix+(i*cols+j))->Age<<","<<(&matrix+(i*cols+j))->StarvationTime<<"}";
	//	}
	//	cout<<endl;
	//}

			for(int i=0;i<rows;i++)   //图形输出鲨鱼和小鱼的状态
	{
		for(int j=0;j<cols;j++)
		{
			if((&matrix+(i*cols+j))->Type==SHARK_TYPE)  //用 ■ 表示鲨鱼
			    cout<<"■";
			else if((&matrix+(i*cols+j))->Type==FISH_TYPE)  //用 ⊙ 表示小鱼
			    cout<<"⊙";
			else
				cout<<"  ";  //用空格表示空白区域
		}
		cout<<endl;
	}
}

int GetCellListLen(struct CellNode *ListHead)  //获得细胞链表的长度
{
	struct CellNode *p=ListHead;  //获得链表头
	int lenth=0;  //初始化长度
	while(p!=NULL)  //指针非空进行循环
	{   
		lenth++;    //长度加一
		p=p->next;  //链表指针向后移动
	}
	return lenth;   //返回链表长度
}

struct CellNode *InsertCellList(struct CellNode *ListHead,Cell* CellElem,int x,int y)  //将细胞随机插入链表
{
	struct CellNode *p=ListHead;  //获得链表头
	struct CellNode *s=NULL;      //定义TEMP节点指针
	int j=0;  //定义位置循环变量
	srand( (unsigned)time( NULL ) );  //设置随机种子   
	int index=rand()%GetCellListLen(ListHead);  //产生随机插入位置

	while(p&&j<index-1){p=p->next;++j;}  //查找随机插入位置

       s=(struct CellNode *)malloc(sizeof(CellNode));  //为TEMP节点分配空间
	   s->NodeElem=CellElem;   //为TEMP节点附值
	   s->x=x;
	   s->y=y;
	   s->next=p->next;  //将TEMP节点插入指定位置
	   p->next=s;

	return ListHead;  //返回细胞链表头
}

struct CellNode *CreatCellList(struct CellNode *ListHead,Cell &matrix,int rows,int cols,int TYPE)
{   //创建细胞链表
	ListHead=(struct CellNode *)malloc(sizeof(CellNode)); //产生表头节点空间
	ListHead->next=NULL;  

	for(int i=0;i<rows;i++)   //在海域内进行查找
	{
		for(int j=0;j<cols;j++)
		{
			if((&matrix+(i*cols+j))->Type==TYPE)  //在海域内查找指定细胞类型
		   {  
              ListHead=InsertCellList(ListHead,(&matrix+(i*cols+j)),i+1,j);//将指定的类型细胞插入相应链表(注意i+1的意义所在)
		   }                                               //用i+1来处理工作区域和全部获得区域的起始行差一的情况,便于后面处理
		}
	}

	return ListHead;  //返回链表头
}

void PrintList(struct CellNode *ListHead)  //输出细胞链表的元素信息
{
	struct CellNode *p=ListHead->next;  //定义节点指针
	while(p!=NULL)  //顺链表循环
	{   //输出节点信息
		cout<<"{"<<p->NodeElem->Type<<","<<p->NodeElem->Age<<","<<p->x<<","<<p->y<<"}"<<endl;
		p=p->next;  //向链表后步进
	}
}

struct CellNode *GetCell(struct CellNode *ListHead)  //获得链表头节点并在表中删除此节点
{
	struct CellNode *p=ListHead->next;  //定义节点指针

	if(p==NULL)  //如果指针空,则返回空指针
	{
		return NULL;
	}
	else     //若不空
	{
		ListHead->next=p->next;  //在节点中删除此节点
		return p;  //返回细胞节点
	}
}

int RandEatDiretion(Cell &matrix,int rows,int cols,int i,int j)  //鲨鱼随机选择一条鱼吃
{
	int EatAble[4]={0,0,0,0}; //存储可能的所有方向
    int k=0;   //可以吃的鱼的数量
	srand( (unsigned)time( NULL ) );  //产生随机种子   
	if((&matrix+(i*cols+(j+1)%COLUMN))->Type==FISH_TYPE)  //右侧有鱼吃
	{
        EatAble[k]=RIGHT;  //存储方向
		k++; //可选择的鱼数量加一
	}
	if((&matrix+((i+1)*cols+j))->Type==FISH_TYPE)  //下侧有鱼吃
	{
        EatAble[k]=DOWN;
		k++;
	}
    if((&matrix+(i*cols+(j-1+COLUMN)%COLUMN))->Type==FISH_TYPE)  //左侧有鱼吃
	{
        EatAble[k]=LEFT;
		k++;
	}
    if((&matrix+((i-1)*cols+j))->Type==FISH_TYPE)  //上侧有鱼吃
	{
        EatAble[k]=UP;
		k++;
	}
	if(k!=0)  //有鱼可以选择吃
	{
		return EatAble[rand()%k];  //随机选择一条鱼吃
	}
	return NOTHING_TO_EAT;  //没有鱼吃
}

int RandMoveDiretion(Cell &matrix,int rows,int cols,int i,int j)  //随机选择一个方向移动
{
	int MoveAble[4]={0,0,0,0};  //存储可以移动的方向
    int k=0;  //可以选择的方向数量
	srand( (unsigned)time( NULL ) );   //产生随机种子   
    if((&matrix+(i*cols+(j+1)%COLUMN))->Type==EMPTY)   //右侧可以移动
	{
        MoveAble[k]=RIGHT;  //存储可移动的方向
		k++;  //可选择的数量加一
	}
	if((&matrix+((i+1)*cols+j))->Type==EMPTY)     //下侧可以 移动
	{
        MoveAble[k]=DOWN;
		k++;
	}
    if((&matrix+(i*cols+(j-1+COLUMN)%COLUMN))->Type==EMPTY)  //左侧可以移动
	{
        MoveAble[k]=LEFT;
		k++;
	}
    if((&matrix+((i-1)*cols+j))->Type==EMPTY)   //上侧可以移动
	{
        MoveAble[k]=UP;
		k++;
	}
	if(k!=0)   //有方向可以选择移动
	{
		return MoveAble[rand()%k];  //在可选择的范围内随机移动
	}
	return NOWHERE_TO_MOVE;  //没有空间可以移动
}

int EatFish(Cell &matrix,int rows,int cols,int i,int j,int EatDirection,MPI_Datatype MsgType,MPI_Datatype CellType)  //鲨鱼吃小鱼
{
    if(EatDirection!=NOTHING_TO_EAT)   //有鱼可以选择吃
	{
		Cell* OrientCell=(&matrix+(i*cols+j));//定义旧细胞位置的地址,并赋予现在细胞的地址
		Cell* NewCell; //定义新细胞位置的地址,用于后面的操作

        OrientCell->StarvationTime=0;  //将鲨鱼的饥饿时间清空
		switch(EatDirection)  //查看所选择的小鱼在哪个方向
		{
		case RIGHT: //右侧
			NewCell=(&matrix+(i*cols+(j+1)%COLUMN));  //获取需要修改的细胞空间的地址
			break;
		case DOWN:  //下侧
			NewCell=(&matrix+((i+1)*cols+j));
			break; 
		case LEFT:  //左侧

⌨️ 快捷键说明

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