/* * update all the ant operator * */ private void UpdateAntPopulation(AntPopulation pAntPopulation) { 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; } // update ant with finding food logic or finding home logic if (tAnts [i].mNowTarget == NowTarget.FOOD) { OnFood(tAnts[i], pAntPopulation); } else if (tAnts [i].mNowTarget == NowTarget.HOME) { OnHome(tAnts[i], pAntPopulation); } } }
// finding food logic 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) { // update Pheromone if (pAnt.mInfoHome > 0.0f) { UpdatePheromone(ap.mInfluenceHomeTag, pAnt.mInfoHome, ap.mRadiationRiaus, pAnt.mPositionIndex, 1600, 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); // find the food if (g_target != null) { pAnt.mInfoHome = -1.0f; pAnt.mInfoFood = 200.0f; pAnt.mNowTarget = NowTarget.HOME; pAnt.mNowPositionTarget = g_target.transform.position; pAnt.mClosedArray.Clear(); pAnt.mLastDir = Vector2.zero; return; } if (g_home != null) { pAnt.mInfoFood = -1.0f; pAnt.mInfoHome = 200.0f; } // compute the new dirction pAnt.mNowPositionTarget = ComputeDirction(pAnt, ap); } else { // move the ant Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position; offset.Normalize(); offset.y = 0; pAnt.mAIRT.transform.Translate(offset * Time.deltaTime * 6); } }
// compute new dirction 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); // find the information if (tMax > 0.0f) { //Debug.Log (pAnt.mNowTarget.ToString()+" "+tMax+" infoFood:"+pAnt.mInfoFood+" infoHome"+pAnt.mInfoHome); float minusRate = 0.0002f; if (Random.Range(0.0f, 1.0f) < minusRate) { // just a little rate for random dir 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 { // compute the new dir by RW with rate float sum = 0.0f; float max = -1.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]; } } int index1 = Random.Range(0, InfluenceMap.getInstance().NineGrid.Length); for (int i = 0; i < InfluenceMap.getInstance().NineGrid.Length; i++) { int realI = (i + index1) % InfluenceMap.getInstance().NineGrid.Length; Vector2 delta = InfluenceMap.getInstance().NineGrid [realI]; 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 && !InfluenceMap.getInstance().isWall(delta + pAnt.mPositionIndex)) { resultNineGrid = new Vector2(delta.x, delta.y); break; } } } } else { // no find the information so the new dirtion is a random dir 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); }