Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /************************************************************************************************************************/
- constexpr char DEPTH = 3;
- constexpr char POOL_SIZE = 50;
- constexpr char GENERATIONS = 50;
- constexpr int MAX_MOVES = 360;
- constexpr int THRUST_LIMIT = 300;
- constexpr char PLAYERS = 3;
- constexpr char CARS_PER_PLAYER = 3;
- constexpr char MAX_DATA = 2;
- class DNA;
- class Population;
- class DNA
- {
- public:
- int genes[PLAYERS][DEPTH][MAX_DATA];
- float fitness;
- inline void randomizeGenes(int ourShips){
- //srand (time(NULL));
- int move = 0;
- for(int ii = 0;ii < CARS_PER_PLAYER;ii++)
- {
- for(int i = 0;i < DEPTH;i++)
- {
- move = rnd(37) * 10;
- if(move == 360){
- genes[ii][i][0] = -1;
- genes[ii][i][1] = 0;
- }else{
- genes[ii][i][0] = move;
- genes[ii][i][1] = 300;
- }
- //cerr << "Gene " << i << " is: " << returnMove(genes[i]) << endl;cerr << "RNG " << rand() % 8 << endl;
- }
- }
- }
- inline void copy(DNA dna){
- for(int ii = 0;ii < CARS_PER_PLAYER;ii++)
- {
- for(int i = 0;i < DEPTH;i++)
- {
- genes[ii][i][0] = dna.genes[ii][i][0];
- genes[ii][i][1] = dna.genes[ii][i][1];
- }
- }
- }
- void debugDNA(int ourShips){
- for(int ii = 0;ii < ourShips;ii++)
- {
- for(int i = 0;i < DEPTH;i++)
- {
- cerr << " " << (int)genes[ii][i][0] << " " << (int)genes[ii][i][1] << " | ";
- //cerr << "Gene " << i << " is: " << returnMove(genes[i]) << endl;cerr << "RNG " << rand() % 8 << endl;
- }
- cerr << " & ";
- }
- cerr << endl;
- }
- inline static Point transformToPoint(int x,int y,int moveN){
- if(moveN == -1)return NULL_TARGET;
- int xDir = cosines[moveN];
- int yDir = sines[moveN];
- return Point(x+xDir, y+yDir);
- }
- };
- class Population
- {
- public:
- DNA pool[POOL_SIZE];
- DNA bestDNA;
- inline void debugPop(int ourShips){
- for(int i = 0;i < POOL_SIZE;i++)
- {
- pool[i].debugDNA(ourShips);//cerr << "Gene 1 " << pool[i].dna.genes[0] << endl;
- }
- }
- Population()
- {
- }
- inline void init(int ourShips)
- {
- for(int i = 0;i < POOL_SIZE;i++)
- {
- pool[i].randomizeGenes(CARS_PER_PLAYER);
- //cerr << "Gene 1 " << pool[i].dna.genes[0] << endl;
- }
- }
- inline DNA findBest()
- {
- bestDNA = pool[0];
- for(int i = 1;i < POOL_SIZE;i++)
- {
- if(pool[i].fitness > bestDNA.fitness) bestDNA = pool[i];
- }
- return bestDNA;
- }
- };
- class GA{
- public:
- Population pop,newPop;
- int elitismOffset,generations;
- const int MAX_PERCENT = 100;
- const int crossoverRate = 50;
- const int mutationRate = 10;
- const int tournamentK = 10;
- vector<Wreck>wrecksC;
- vector<SkillEffect>skillEffectsC;
- GA(){
- elitismOffset = 1;
- generations = 0;
- }
- inline void initParams(int eliOffset){
- elitismOffset = eliOffset;
- generations = 0;
- }
- inline double getFitness(int owner,int round){
- double fitness = 0;
- double destroyerScore = 0;
- double reaperScore = 0;
- double doofScore = 0;
- double totalDist = 0;
- double bestDist = 12000.0;
- //Destroyer score------------------------------------------------
- for(int i = 0;i < tankers.size();i++){
- //if(tankers[i]->distance(WATERTOWN) > 6000.0 || tankers[i]->water < 2 )continue;
- if(tankers[i]->dead == true)continue;
- double tempDist = players[owner].getDestroyer()->distance(tankers[i]) / (tankers[i]->water);
- if(tempDist < bestDist)bestDist = tempDist;
- }
- destroyerScore += - bestDist / 12000.0;
- //destroyerScore += (players[owner].getDestroyer()->destroyedTanks);
- //Reaper score---------------------------------------------------
- bestDist = 12000.0;
- reaperScore += -players[owner].getReaper()->distance(players[owner].getDestroyer()) / 12000.0;
- //Doof score-----------------------------------------------------
- bestDist = 12000.0;
- doofScore += -bestDist / 12000.0;
- //General Score--------------------------------------------------
- fitness += players[owner].score * 100.0;
- fitness += destroyerScore ;
- // fitness += doofScore;
- fitness += reaperScore;
- //for(int i = 0;i < MAX_PLAYERS;i++)if(i != owner)fitness += -(players[owner].score) * 20.0;
- return fitness;
- }
- inline void copyData(){
- skillEffectsC.clear();
- wrecksC.clear();
- //cerr<< "LOOTERS" << endl;
- for(int i = 0;i < 9;i++){
- looters[i]->save();
- }
- //cerr<< "TANKERS" << endl;
- for(int i = 0;i < tankers.size();i++){
- tankers[i]->save();
- }
- // cerr << "Saving" << endl;
- //cerr<< "PLAYERS" << endl;
- for(int i = 0;i < MAX_PLAYERS;i++){
- players[i].save();
- }
- //cerr<< "WRECKS" << endl;
- wrecksC = wrecks;
- //cerr<< "SKILLEFFECT" << endl;
- skillEffectsC = skillEffects;
- }
- inline void copyData2(){
- wrecks = wrecksC;
- skillEffects = skillEffectsC;
- for(int i = 0;i < 9;i++){
- looters[i]->load();
- }
- for(int i = 0;i < tankers.size();i++){
- tankers[i]->load();
- }
- // cerr << "Loading" << endl;
- for(int i = 0;i < MAX_PLAYERS;i++){
- players[i].load();
- }
- }
- inline void evolvePopulation(int owner,DNA dummy[2]){
- if(generations != 0){
- selectionTourny();
- // if(rounds > 1)cerr << "2";
- }
- copyData2();
- int index = 0;
- for(int i = 0;i < POOL_SIZE;i++)
- {
- pop.pool[i].fitness = 0;
- for(int rounds = 0;rounds < DEPTH;rounds++){
- //Assign actions
- for(int a = 0;a < 3;a++){
- if(owner == a){
- for(int b = 0;b < 3;b++){
- looters[players[a].lootersI[b]]->wantedThrustTarget = DNA::transformToPoint(looters[players[a].lootersI[b]]->x,looters[players[a].lootersI[b]]->y,pop.pool[i].genes[b][rounds][0]);
- looters[players[a].lootersI[b]]->wantedThrustPower = pop.pool[i].genes[b][rounds][1];
- }
- }else{
- for(int b = 0;b < 3;b++){
- //cerr << "PLAYER " << a << " DUMMY " << index << " MOVE " << dummy[index].genes[b][rounds][0] << "|" << dummy[index].genes[b][rounds][1] << endl;
- looters[players[a].lootersI[b]]->wantedThrustTarget = DNA::transformToPoint(looters[players[a].lootersI[b]]->x,looters[players[a].lootersI[b]]->y,dummy[index].genes[b][rounds][0]);
- looters[players[a].lootersI[b]]->wantedThrustPower = dummy[index].genes[b][rounds][1];
- }
- index++;
- }
- }
- index = 0;
- updateGame(rounds);
- }pop.pool[i].fitness += getFitness(owner,rounds);
- //Reset simulator
- copyData2();
- }
- generations++;
- }
- inline void mutate(DNA& dna1)
- {
- for(int ii = 0;ii < CARS_PER_PLAYER;ii++)
- {
- int index1;
- int index2;
- int firstIndex;
- int secondIndex;
- do
- {
- index1 = rnd(DEPTH);
- index2 = rnd(DEPTH);
- }while(index1 == index2);
- int gene[2] ;
- for(int i = 0;i < MAX_DATA;i++)gene[i] = dna1.genes[ii][index1][i];
- for(int i = 0;i < MAX_DATA;i++)dna1.genes[ii][index1][i] = dna1.genes[ii][index2][i];
- for(int i = 0;i < MAX_DATA;i++)dna1.genes[ii][index2][i] = gene[i];
- //if(dna1.genes[ii][index2] > MAX_MOVES || dna1.genes[ii][index1] > MAX_MOVES )cerr << "ERROR IN MUTATION GENERATION " << generations << endl;
- }
- }
- inline void selectionTourny()
- {
- //srand (time(NULL));
- newPop.pool[0] = pop.findBest();
- for(int i = elitismOffset;i < POOL_SIZE;i++)
- {
- int index1 = 0;
- int index2 = 0;
- int firstIndex;
- int secondIndex;
- for(int k = 0;k < tournamentK;k++){
- do
- {
- index2 = rnd(POOL_SIZE);
- }while(index1 == index2);
- index1 = pop.pool[index1].fitness > pop.pool[index2].fitness ? index1 : index2;
- }
- firstIndex = index1;
- for(int k = 0;k < tournamentK;k++){
- do
- {
- index2 = rnd(POOL_SIZE);
- }while(index1 == index2);
- index1 = pop.pool[index1].fitness > pop.pool[index2].fitness ? index1 : index2;
- }
- secondIndex = index1;
- if(rnd(MAX_PERCENT) < crossoverRate)
- newPop.pool[i] = crossoverUniform(pop.pool[firstIndex],pop.pool[secondIndex]);
- else
- newPop.pool[i] = pop.pool[i];
- if(rnd(MAX_PERCENT) < mutationRate)
- mutate(newPop.pool[i]);
- }
- for(int i = 0;i < POOL_SIZE;i++)
- {
- pop.pool[i] = newPop.pool[i];
- }
- // cerr << "Populated 1" << endl;
- for(int i = 0;i < POOL_SIZE;i++)
- {
- pop.pool[rnd(POOL_SIZE -1) + 1].randomizeGenes(CARS_PER_PLAYER);
- }
- // cerr << "Populated 2" << endl;
- }
- inline DNA crossoverOnePoint(DNA& dna1,DNA& dna2){
- // srand (time(NULL));
- int limit = DEPTH / 2;
- DNA newDNA;
- for(int ii = 0;ii < CARS_PER_PLAYER;ii++)
- {
- for(int i = 0;i < limit;i++)
- {
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[ii][i][a] = dna1.genes[ii][i][a];
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[ii][DEPTH - 1 - i][a] = dna2.genes[ii][DEPTH -1 - i][a];
- }
- }
- return newDNA;
- }
- inline DNA crossoverMultiPoint(DNA& dna1,DNA& dna2){
- int index1;
- int index2;
- DNA newDNA;
- int threshold = DEPTH > 2 ? 0 : -1;
- do{
- index1 = rnd(DEPTH);
- index2 = rnd(DEPTH);
- }while((index1 == threshold)||(index2 == threshold)||(index1 == index2));
- for(int s = 0;s < CARS_PER_PLAYER;s++)
- {
- for(int i = 0;i < index1;i++){
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[s][i][a] = dna1.genes[s][i][a];
- }
- }
- for(int s = 0;s < CARS_PER_PLAYER;s++)
- {
- for(int i = index1;i < index2;i++){
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[s][i][a] = dna2.genes[s][i][a];
- }
- }
- for(int s = 0;s < CARS_PER_PLAYER;s++)
- {
- for(int i = index2;i < DEPTH;i++){
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[s][i][a] = dna1.genes[s][i][a];
- }
- }
- return newDNA;
- }
- inline DNA crossoverUniform(DNA& dna1,DNA& dna2){
- int coin;
- DNA newDNA;
- for(int i = 0;i < DEPTH;i++){
- coin = rnd(2);
- for(int s = 0;s < CARS_PER_PLAYER;s++)
- {
- for(int a = 0;a < MAX_DATA;a++)newDNA.genes[s][i][a] = coin == 0 ? dna1.genes[s][i][a] : dna2.genes[s][i][a]; //if(dna2.genes[s][i] > MAX_MOVES||dna1.genes[s][i] > MAX_MOVES)cerr << "ERROR IN GENERATION CROSSOVER" << generations << endl;
- }
- }
- return newDNA;
- }
- inline void printMoves(DNA dummy){
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement