[FreedomAI]第八周——算法具体实现和运行结果

public class AntPopulationSystem:USystem
	{
		
		public override void Init ()
		{
			base.Init ();
			this.AddRequestComponent (typeof(AntPopulationComponent));
		}

		public override void Update (UEntity uEntity)
		{
		//	Debug.Log ("UpdateAntSystem");

			base.Update (uEntity);



		//	InfluenceMap.getInstance ().Show (4);
			List<AntPopulation> tList = uEntity.GetComponent<AntPopulationComponent> ().mAntPopulationSet;
			for (int i = 0; i < AntPopulation.mNowListCount; i++)
			{
				if (tList [i].isStartFind)
				{
					UpdateAntPopulation (tList [i]);
				}	
			}
		}

		private void UpdateAntPopulation(AntPopulation pAntPopulation)
		{
		//	Debug.Log ("UpdateAntPopulation");
			Ant[] tAnts = pAntPopulation.mAnts;
			for (int i = 0; i < tAnts.Length; i++)
			{
				tAnts [i].mPositionIndex = InfluenceMap.getInstance ().getTilefromPosition (new Vector2(tAnts[i].mAIRT.transform.position.x,tAnts[i].mAIRT.transform.position.z));
				tAnts [i].Add (tAnts[i].mPositionIndex);
				if (tAnts [i].mInfoFood > 0.0f)
					tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.green;
				else if (tAnts [i].mInfoHome > 0.0f)
					tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.blue;
				else
					tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.red;
				
				if (tAnts [i].mNowTarget == NowTarget.FOOD)
				{
					OnFood (tAnts[i],pAntPopulation);
				}
				else if (tAnts [i].mNowTarget == NowTarget.HOME) 
				{
					OnHome (tAnts[i],pAntPopulation);
				}
			}
		}

		private void OnFood(Ant pAnt,AntPopulation ap)
		{
			Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z);
			Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z);

			float dis = Vector2.Distance (v1,v2);

			if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f) 
			{
				if(pAnt.mInfoHome>0.0f)
					UpdatePheromone (ap.mInfluenceHomeTag,pAnt.mInfoHome,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count);
				GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination);
				GameObject g_home =  FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome);
				if(g_target != null)
				{
					pAnt.mInfoHome = -1.0f;
					pAnt.mInfoFood = 200.0f;
					pAnt.mNowTarget = NowTarget.HOME;
					pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
					pAnt.mClosedArray.Clear ();
					pAnt.mLastDir = Vector2.zero;
					return;
				}

				if (g_home != null) 
				{
					pAnt.mInfoFood = -1.0f;
					pAnt.mInfoHome = 200.0f;
				}

				pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
				//Debug.Log (pAnt.mNowPositionTarget.ToString());
			}
			else
			{
				Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position;
				offset.Normalize ();
				offset.y = 0;
				pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6);
			}
		}

		private void OnHome(Ant pAnt,AntPopulation ap)
		{
			Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z);
			Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z);

			float dis = Vector2.Distance (v1,v2);

			//Debug.Log ("OnHome");
			if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f) 
			{
				if(pAnt.mInfoFood>0.0f)
					UpdatePheromone (ap.mInfluenceDistinationTag,pAnt.mInfoFood,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count);
				GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination);
				GameObject g_home =  FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome);
				if (g_home != null)
				{
					pAnt.mInfoFood = -1.0f;
					pAnt.mInfoHome = 200.0f;
					pAnt.mNowTarget = NowTarget.FOOD;
					pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
					pAnt.mClosedArray.Clear ();
					pAnt.mLastDir = Vector2.zero;
					return;
				}

				if (g_target != null)
				{
					pAnt.mInfoFood = 200.0f;
					pAnt.mInfoHome = -1.0f;
				}

				pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
			}
			else
			{
				Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position;
				offset.Normalize ();
				offset.y = 0;
				pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6);
			}
		}

		private GameObject FindTarget(Vector3 mCenter,float riaus,string code)
		{
			Collider[] tAllCollider = Physics.OverlapSphere (mCenter,riaus);
			GameObject tg = null;
			foreach (Collider c in tAllCollider)
			{
				if (c.tag == code)
				{
					tg = c.transform.gameObject;
					break;
				}
			}
			return tg;
		}

		private float Gauss(Vector2 v)
		{
			return Mathf.Exp(-(v.x*v.x/2.0f+v.y*v.y/2.0f));		
		}

		private void UpdatePheromone(string code,float f,int radioriaus,Vector2 center,float max,int pGoingTile)
		{
			int index = InfluenceMap.getInstance ().mDictionary [code];
			int ti = Mathf.Clamp ((int)center.x,0,InfluenceMap.getInstance ().wtileCount-1);
			int tj = Mathf.Clamp ((int)center.y,0,InfluenceMap.getInstance ().htileCount-1);
			if(pGoingTile<radioriaus)
				InfluenceMap.getInstance ().IMData [index] [ti] [tj] += f * (1-(float)pGoingTile/(float)radioriaus);
			
			if (InfluenceMap.getInstance ().IMData [index] [ti] [tj] > max)
				InfluenceMap.getInstance ().IMData [index] [ti] [tj] = max;
	
		}

		private Vector3 ComputeDirction(Ant pAnt,AntPopulation ap)
		{
			
			Vector3 result = Vector3.zero;

			Vector2 resultNineGrid = Vector2.zero;

			int index = -1;

			if (pAnt.mNowTarget == NowTarget.FOOD)
				index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceDistinationTag];
			else
				index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceHomeTag];
			
			float tMax = InfluenceMap.getInstance ().getMax (pAnt.mPositionIndex,1,index);


			if (tMax > 0.0f) 
			{
				//Debug.Log (pAnt.mNowTarget.ToString()+" "+tMax+" infoFood:"+pAnt.mInfoFood+" infoHome"+pAnt.mInfoHome);

				float minusRate = 0.02f;
				if (Random.Range (0.0f, 1.0f) < minusRate) 
				{
					
					int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);

					resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];

					if (pAnt.mLastDir != Vector2.zero)
						resultNineGrid = pAnt.mLastDir;

					float minusRate_ = 0.2f;

					if (Random.Range (0.0f, 1.0f) < minusRate_)
					{
						RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
						resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
					}

					int count = 0;

					while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10) 
					{
						RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
						resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
						count++;
					}
						
				}
				else
				{
	

					float sum = 0.0f;
					for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++)
					{
						Vector2 delta = InfluenceMap.getInstance ().NineGrid [i];
						Vector2 real = pAnt.mPositionIndex + delta;
						if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount)
							sum += InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y];
					}

					for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++)
					{
						Vector2 delta = InfluenceMap.getInstance ().NineGrid [i];
						Vector2 real = pAnt.mPositionIndex + delta;
						float tRate = 0.0f;

						if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount)
							tRate = InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y] / sum;
						
						if (Random.Range (0.0f, 1.0f) < tRate&&!pAnt.Contains(delta+pAnt.mPositionIndex)&&!InfluenceMap.getInstance().isWall(delta+pAnt.mPositionIndex))
						{
							resultNineGrid = new Vector2 (delta.x,delta.y);
						//	Debug.Log (pAnt.Contains(delta+pAnt.mPositionIndex));
							break;
						}

					}

				
				}
			}
			else
			{
				int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);

				resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];

				if (pAnt.mLastDir != Vector2.zero)
					resultNineGrid = pAnt.mLastDir;

				float minusRate_ = 0.2f;

				if (Random.Range (0.0f, 1.0f) < minusRate_)
				{
					RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
					resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
				}

				int count = 0;

				while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10) 
				{
					RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
					resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
					count++;
				}
				//Debug.Log (pAnt.Contains(resultNineGrid+pAnt.mPositionIndex));
			}

			pAnt.mLastDir = new Vector2 (resultNineGrid.x,resultNineGrid.y);

		
			float tx = pAnt.mPositionIndex.x + resultNineGrid.x;
			float ty = pAnt.mPositionIndex.y + resultNineGrid.y;

			tx = Mathf.Clamp (tx,0,InfluenceMap.getInstance().wtileCount-1);
			ty = Mathf.Clamp (ty,0,InfluenceMap.getInstance().htileCount-1);

			Vector2 tile = new Vector2 (tx,ty);

		//	Debug.Log (pAnt.Contains(tile));

			result = InfluenceMap.getInstance ().GetPositionByTile (tile);

			return result;
		}

	}

一开始的结果:


经过一段时间,开始往浅蓝和那个绿色箱子中间聚拢。


再过一段时间,已经是几乎所有都在一起聚拢。




猜你喜欢

转载自blog.csdn.net/qq_33999892/article/details/80542937