//--------------------------------------------------------------------------- // Description: Highlights the routes with the heigher pheromone intesity // starting from the Nest. If the Food source is not reached // after a given number of tries, stop the search and draw the // result. bool __fastcall Civilization::FindMainRoads(int Ntries, TImage *ImageBox, const int RWidth, const float Scale) { // Start from the Anthill... City *CurrentCity = Nest; TList *MainRoads = new TList(); while(CurrentCity!=FoodSourceCity && Ntries>0) { int PheroLevel = -MAXINT; Route *CurrentRoad = NULL; City* NextCity; Route* thisRoad; // the following loop select the best road acording to the pheromone level for(int j=0; j<Roads->Count; j++) { thisRoad = (Route*)Roads->Items[j]; // if the road has a conection with the current city... NextCity = thisRoad->GetConection(CurrentCity); // Test the highest Pheromone level among the possible roads... // if 'thisRoad' was not used before... if(NextCity!=NULL && MainRoads->IndexOf(thisRoad)==-1) { if(thisRoad->GetPheromone() > PheroLevel) { CurrentRoad = thisRoad; PheroLevel = thisRoad->GetPheromone(); } } } // Go to next city using the selected road... if(CurrentCity!=NULL && CurrentRoad!=NULL) { CurrentCity = CurrentRoad->GetConection(CurrentCity); MainRoads->Add(CurrentRoad); } Ntries--; } // Draw the MainRoad Rebuild(ImageBox,Scale); // Draw all the roads for(int i=0; i<MainRoads->Count; i++) { ImageBox->Canvas->Pen->Width = RWidth; ((Route*)MainRoads->Items[i])->DrawRoad(ImageBox,clRed,Scale); ImageBox->Canvas->Pen->Width = 1; } return (Ntries>0)?true:false; }
//--------------------------------------------------------------------------- // Description: Evaluates the next move of all agents in the population. // // For all ants in the colony... // - if traveling, walk one more step // - if in the food source not carrying food, pick food // - if in the nest carrying food, leave food // - else (in another city), choose next route int Civilization::NextTurn() { TurnsRemaining--; if(TurnsRemaining==0) // If it's time to evolve the population... { NaturalSelection(); // ...perform Natural Selection } Epoch++; // Update next turn number // For all ants in the colony... for(int i=0; i<Ants->Count; i++) { // Select an Ant... Ant* thisAnt = (Ant*)Ants->Items[i]; // If it's traveling, walk a little more... if(thisAnt->IsOnTheRoad()) thisAnt->Walk(); else { //... else, if the ant is on a city, ... // See if the ant reached the Civilization's Food Souce... if( (thisAnt->TargetCity==FoodSourceCity) && !thisAnt->CarryingFood() ) { thisAnt->PickFood(); thisAnt->PrepareTrail(); } else // ... or in the Nest carrying food, ... if( (thisAnt->TargetCity==Nest) && thisAnt->CarryingFood() ) { thisAnt->LeaveFood(); // ... leave food FoodCollected++; // ... add one more food to the colony thisAnt->RememberCity(); // ... start again ... int *ThisYear = new int; *ThisYear = Epoch; DeliveryTime->Add(ThisYear); } else // if the ant is carring food, follow its own trail back to the Anthill if( thisAnt->CarryingFood() ) { City *CurrentCity = thisAnt->TargetCity; City *BackCity = thisAnt->GetNextCity(); for(int j=0; j<Roads->Count; j++) { Route* thisRoad = (Route*)Roads->Items[j]; // if the road has a conection with the current city... City* NextCity = thisRoad->GetConection(CurrentCity); if(NextCity!=NULL && NextCity==BackCity) { thisAnt->SetDistance((int)NextCity->GetDistance(CurrentCity)); thisAnt->TargetCity = NextCity; thisAnt->Road = thisRoad; if(thisAnt->Road!=NULL) thisAnt->PutPheromone(); break; } } } else { // ... or select a new way to go. // Search all cities that have a road to this one float CurrentLevel = -MaxInt; // Save the TargetCity for comparisons... City *CurrentCity = thisAnt->TargetCity; for(int j=0; j<Roads->Count; j++) { Route* thisRoad = (Route*)Roads->Items[j]; // if the road has a conection with the current city... City* NextCity = thisRoad->GetConection(CurrentCity); // ... test the Will Level if(NextCity!=NULL) { float Level = thisAnt->GetTendency(thisRoad->GetPheromone()); if(Level > CurrentLevel) { CurrentLevel = Level; // Set the distance to the next target city thisAnt->SetDistance((int)NextCity->GetDistance(CurrentCity)); // Select a new Target City and Route: thisAnt->TargetCity = NextCity; thisAnt->Road = thisRoad; } } thisRoad->UpdateStatusInfo(); } // end of Road Search if(thisAnt->Road!=NULL) thisAnt->PutPheromone(); // After a target city was selected, remember it... thisAnt->RememberCity(); } // end of new path selection } // Draw Ants... thisAnt->DrawAnt(VirtualCiv); } // end of Ants Movements // Pheromone Evaporation... for(int j=0; j<Roads->Count; j++) { ((Route*)Roads->Items[j])->EvaporatePheromone(); } // Show Current Status on the main window LabelEpoch->Caption = "Turn: " + IntToStr(Epoch) + '\n' + "Population: " + IntToStr(Ants->Count) + '\n' + "Food Collected: " + IntToStr(FoodCollected); return Epoch; }