Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Windows.Forms;
- using System.Collections;
- using System.Media;
- namespace MakeLand
- {
- public class Population
- {
- public int generation = 0;
- public int bestScore = 0;
- public int bestIndex = 0;
- public int numInPop = 0;
- public int[] listOfLiving;
- public int countOfLiving;
- public Phenotype[] maps = null;
- public Population(int numInPopZ, Random r)
- {
- numInPop = numInPopZ;
- maps = new Phenotype[numInPop];
- for (int i = 0; i < numInPop; i++)
- {
- Genotype g = new Genotype(r);
- Phenotype p = new Phenotype(g,0);
- p.createPheno();
- p.setScore();
- maps[i] = p;
- }
- }
- /// <summary>
- /// Returns the index of the best individual and updates bestScore
- /// </summary>
- /// <returns></returns>
- public int findBest()
- {
- Phenotype p = maps[0];
- bestScore = p.score;
- bestIndex = 0;
- for (int i = 1; i < numInPop; i++)
- {
- p = maps[i];
- if (p.score > bestScore)
- {
- bestIndex = i;
- bestScore = p.score;
- }
- }
- return bestIndex;
- }
- /// <summary>
- /// Finds the worst individual thats actually alive
- /// </summary>
- /// <returns></returns>
- public int findWorstAlive()
- {
- bool first = true;
- int worstScore = 0;
- int worstIndex = 0;
- for (int i = 1; i < numInPop; i++)
- {
- Phenotype p = maps[i];
- if (p.alive && first)
- {
- first = false;
- worstScore = p.score;
- worstIndex = i;
- continue;
- }
- if (p.alive && p.score < worstScore)
- {
- worstScore = p.score;
- worstIndex = i;
- }
- }
- return worstIndex;
- }
- /// <summary>
- /// Just a standard getter
- /// </summary>
- /// <param name="i"></param>
- /// <returns></returns>
- public Phenotype getPhenotype(int i)
- {
- return maps[i];
- }
- /// <summary>
- /// Unsets the newborn flag for the entire population
- /// </summary>
- public void unsetNewborn()
- {
- for (int i = 1; i < numInPop; i++)
- {
- getPhenotype(i).newborn = false;
- }
- }
- /// <summary>
- /// Kills the weakest
- /// </summary>
- /// <param name="n"></param>
- public void killThisMany(int n)
- {
- for (int i = 0; i <n; i++)
- {
- int k = findWorstAlive();
- getPhenotype(k).alive = false;
- }
- }
- /// <summary>
- /// Search for dead individuals - replace them with living newborn ones
- /// </summary>
- public void breedPopulation(Random r)
- {
- listOfLiving = new int[Params.populationCnt];
- countOfLiving=0;
- for (int i = 0; i < Params.populationCnt; i++)
- {
- if (getPhenotype(i).alive && (!getPhenotype(i).newborn))
- {
- listOfLiving[i] = i;
- countOfLiving++;
- }
- }
- for (int i = 0; i < Params.populationCnt; i++)
- {
- if (!getPhenotype(i).alive)
- {
- int mum = r.Next(0, countOfLiving);
- int dad = r.Next(0, countOfLiving);
- mum = listOfLiving[mum];
- dad = listOfLiving[dad];
- Phenotype mumP = getPhenotype(mum);
- Phenotype dadP = getPhenotype(dad);
- Genotype ggg = makeGenome(mumP.genotype,dadP.genotype);
- if (Params.mutationPercent > r.Next(0,100)) mutate(ggg, r);
- //int b = generation;
- maps[i] = new Phenotype(ggg, G.pop.generation);
- }
- }
- if (generation % 20 == 0)
- checkDuplicateGenotypes();
- }
- public bool checkDuplicateGenes(Genotype ggg)
- {
- bool retv = false;
- for (int i = 0; i < Params.genotypeSize; i++)
- for (int k = i+1; k < Params.genotypeSize; k++)
- {
- if(ggg.genes[i].equal(ggg.genes[k]))
- {
- G.dupGeneCount++;
- ggg.genes[i] = new Gene(G.rnd);
- retv = true;
- }
- }
- return retv;
- }
- public void mutate(Genotype g, Random r)
- {
- G.mutationCount++;
- //g.genes[0] = new Gene();
- int mutationType = 0;
- int numAttributes = 5;
- int rndPercent = r.Next(0, 100);
- if (rndPercent < 25)
- mutationType = 0;
- else if (rndPercent < 50)
- mutationType = 1;
- else if (rndPercent < 75)
- mutationType = 2;
- else
- mutationType = 3;
- int a, b;
- int creepVal = 80; ;
- switch (mutationType) {
- case 0:
- // Mutate ng new genes
- int ng = r.Next(0, Params.genotypeSize);
- for (int i = 0; i < ng; i++)
- {
- a = r.Next(0, Params.genotypeSize);
- g.genes[a] = new Gene(r);
- }
- break;
- case 1:
- // Swap Genes
- a = r.Next(0, Params.genotypeSize);
- b = r.Next(0, Params.genotypeSize);
- Gene temp = g.genes[a];
- g.genes[a] = g.genes[b];
- g.genes[b] = temp;
- break;
- case 2:
- // Copy one gene randomly and mutate it
- a = r.Next(0, Params.genotypeSize);
- Gene newGene = g.genes[a];
- a = r.Next(0, Params.genotypeSize);
- g.genes[a] = newGene;
- // Now mutate it
- int attributeMutate = r.Next(0, numAttributes);
- for (int i = 0; i < attributeMutate; i++)
- {
- // Creep the value
- int mutVal = 0;
- switch (attributeMutate)
- {
- case 0:
- mutVal = (r.Next(0, creepVal * 2 + 1) - creepVal) + g.genes[a].repeatX;
- mutVal = clamp(mutVal, 0, Params.maxRepeat);
- g.genes[a].repeatX = mutVal;
- break;
- case 1:
- mutVal = (r.Next(0, creepVal * 2 + 1) - creepVal) + g.genes[a].repeatY;
- mutVal = clamp(mutVal, 0, Params.maxRepeat);
- g.genes[a].repeatY = mutVal;
- break;
- case 2:
- mutVal = (r.Next(0, creepVal * 2 + 1) - creepVal) + g.genes[a].x;
- mutVal = clamp(mutVal, 0, Params.dimX);
- g.genes[a].x = mutVal;
- break;
- case 3:
- mutVal = (r.Next(0, creepVal * 2 + 1) - creepVal) + g.genes[a].y;
- mutVal = clamp(mutVal, 0, Params.dimY);
- g.genes[a].y = mutVal;
- break;
- case 4:
- mutVal = (r.Next(0, creepVal * 2 + 1) - creepVal) + g.genes[a].terrain;
- if (mutVal < 0)
- mutVal = 0;
- else if (mutVal > 3)
- mutVal = 1;
- g.genes[a].terrain = mutVal;
- break;
- }
- }
- break;
- case 3:
- break;
- }
- }
- private int clamp(int val, int min, int max)
- {
- if (val < min)
- return min;
- else if (val > max)
- return max;
- else
- return val;
- }
- /// <summary>
- /// create a new geneome from mum and dad
- /// </summary>
- /// <param name="g1"></param>
- /// <param name="g2"></param>
- /// <returns></returns>
- public Genotype makeGenome(Genotype g1, Genotype g2)
- {
- Genotype retv = new Genotype();
- for (int i = 0; i < Params.genotypeSize; i++)
- {
- if (G.rnd.NextDouble()<0.5)
- {
- retv.genes[i] = new Gene(g1.genes[i]);
- }
- else
- {
- retv.genes[i] = new Gene(g2.genes[i]);
- }
- }
- return retv;
- }
- public void checkDuplicateGenotypes()
- {
- for (int i = 0; i < Params.populationCnt; i++)
- {
- Genotype g = getPhenotype(i).genotype;
- if (checkDuplicateGenes(g)) continue;
- for (int k = i + 1; k < Params.populationCnt; k++)
- {
- Genotype kk = getPhenotype(k).genotype;
- if (kk.equal(g))
- {
- mutate(g, G.rnd);
- G.dupGeneomeCount++;
- }
- }
- }
- }
- /// <summary>
- /// what it sounds like
- /// </summary>
- public void do1Generation()
- {
- G.pop.generation++;
- unsetNewborn();
- killThisMany(Params.populationCnt / 2);
- breedPopulation(G.rnd);
- //if (Params.checkDuplicateGenomes != -1 && G.pop.generation % Params.checkDuplicateGenomes == 0) checkDuplicateGenotypes();
- Application.DoEvents();
- }
- }
- public class Genotype
- {
- public Gene[] genes = new Gene[Params.genotypeSize];
- public Genotype(Random r)
- {
- for (int i = 0; i < Params.genotypeSize; i++)
- genes[i] = new Gene(r);
- }
- public Genotype()
- {
- for (int i = 0; i < Params.genotypeSize; i++)
- genes[i] = new Gene();
- }
- public bool equal(Genotype gg)
- {
- for (int i = 0; i < Params.genotypeSize; i++)
- {
- if (!(gg.genes[i].equal(genes[i]))) return false;
- }
- return true;
- }
- }
- public class Gene
- {
- public int terrain=0;
- public int x=0;
- public int y=0;
- public int repeatY = 0;
- public int repeatX = 0;
- public Gene()
- {
- }
- public Gene(int ter, int xx, int yy, int rptX, int rptY)
- {
- terrain = ter;
- x = xx;
- y = yy;
- repeatX = rptX;
- repeatY = rptY;
- }
- /// <summary>
- /// New Random Gene
- /// </summary>
- /// <param name="r"></param>
- public Gene(Random r)
- {
- terrain = r.Next(0,3);
- x = r.Next(0, Params.dimX);
- y = r.Next(0, Params.dimY);
- repeatX = r.Next(0, Params.maxRepeat);
- repeatY = r.Next(0, Params.maxRepeat);
- }
- /// <summary>
- /// Copy constructor
- /// </summary>
- /// <param name="gg"></param>
- public Gene(Gene gg) // copy constructor
- {
- terrain = gg.terrain;
- x = gg.x;
- y = gg.y;
- repeatX = gg.repeatX;
- repeatY = gg.repeatY;
- }
- public bool equal(Gene g)
- {
- if (g.x != x) return false;
- if (g.y != y) return false;
- if (g.repeatX != repeatX) return false;
- if (g.repeatY != repeatY) return false;
- if (g.terrain != terrain) return false;
- return true;
- }
- }
- public class Phenotype
- {
- public Genotype genotype=null; // reference class - this is a pointer not a copy
- int[,] pheno = null;
- Bitmap bitm = null;
- public int score = 0;
- public bool alive = true;
- public bool newborn = true;
- public int gen = 0;
- /// <summary>
- /// Default constructor probably not helpfull
- /// </summary>
- public Phenotype()
- {
- // default is all null - no need for code yet
- }
- /// <summary>
- /// This is the critical constructor it creates the pheno array for scoring
- /// </summary>
- /// <param name="gg"></param>
- public Phenotype(Genotype gg, int generationCount)
- {
- genotype = gg;
- createPheno();
- setScore();
- gen = generationCount;
- }
- /// <summary>
- /// create the pheno array
- /// </summary>
- public void createPheno()
- {
- pheno = new int[Params.dimX, Params.dimY];
- for (int x=0; x< Params.dimX;x++)
- for (int y=0; y< Params.dimY;y++) { pheno[x,y] = 0; } // initialise to 0
- for (int i = 0; i < Params.genotypeSize; i++)
- {
- Gene g = genotype.genes[i];
- for (int kx = 0; kx < g.repeatX; kx++)
- for (int ky = 0; ky < g.repeatY; ky++)
- {
- int x = g.x+kx;
- int y = g.y+ky;
- if (y< Params.dimY && x< Params.dimX) pheno[x, y] = g.terrain;
- }
- }
- }
- public int getTerrainSafe(int x, int y)
- {
- if (x < 0 || y < 0 || x >= Params.dimX || y >= Params.dimY) return 0;
- return pheno[x, y];
- }
- /// <summary>
- /// returns the score for selection - also stores it in Phenotype
- /// </summary>
- /// <returns></returns>
- public int setScore()
- {
- score = 0;
- float seaCount = 0;
- float landCount = 0;
- float mountainCount = 0;
- int yChange = 0;
- int xChange = 0;
- int xyChange = 0;
- int every = 1;
- for (int x = 0; x < Params.dimX; x = x + every) {
- for (int y = 0; y < Params.dimY; y = y + every) {
- switch (pheno[x, y]) {
- case 0:
- score += waterTerrain(x, y);
- seaCount++;
- break;
- case 1:
- score += landTerrain(x, y);
- landCount++;
- break;
- case 2:
- score += mountainTerrain(x, y);
- mountainCount++;
- break;
- }
- if (y < Params.dimY - 1)
- {
- if (pheno[x, y] == pheno[x, y + 1])
- yChange++;
- }
- if (x < Params.dimY - 1)
- {
- if (pheno[x, y] == pheno[x + 1, y])
- xChange++;
- }
- if (x < Params.dimY - 1 && y < Params.dimY - 1)
- {
- if (pheno[x, y] == pheno[x + 1, y + 1])
- xyChange++;
- }
- }
- if (yChange >= 7)
- score -= 500;
- else
- score += 500;
- if (xChange >= 7)
- score -= 500;
- else
- score += 500;
- if (xyChange >= 14)
- score -= 900;
- else
- score += 500;
- if (xyChange <= 7)
- score += 1500;
- xyChange = 0;
- xChange = 0;
- yChange = 0;
- }
- if (landCount / (Params.dimX * Params.dimY) <= Params.percentLand)
- score -= 100;
- else
- score += 100;
- if (mountainCount/(Params.dimX * Params.dimY) <= Params.percentFresh)
- score -= 100;
- else
- score += 100;
- return score;
- }
- private int waterTerrain(int x, int y) {
- int score = 0;
- if (x <= 3 || x >= Params.dimX - 3 || y <= 3 || y >= Params.dimY - 3)
- score += 5;
- else if (pheno[x, y + 1] == 0 && pheno[x, y - 1] == 0 &&
- pheno[x + 1, y] == 0 && pheno[x - 1, y] == 0 &&
- pheno[x + 1, y - 1] == 0 && pheno[x - 1, y + 1] == 0)
- {
- score += 5;
- } else
- {
- score -= 5;
- }
- return score;
- }
- private int landTerrain(int x, int y) {
- int score = 0;
- if (!(x <= 3 || x >= Params.dimX - 3 || y <= 3 || y >= Params.dimY - 3))
- {
- // If we are surrounded by more terrain
- if (pheno[x, y + 1] == 1 && pheno[x, y - 1] == 1 &&
- pheno[x + 1, y] == 1 && pheno[x - 1, y] == 1 &&
- pheno[x + 1, y - 1] == 1 && pheno[x - 1, y + 1] == 1)
- {
- score += 15;
- }
- // If we are surrounded by even more terrain
- if (pheno[x, y + 2] == 1 && pheno[x, y - 2] == 1 &&
- pheno[x + 2, y] == 1 && pheno[x - 2, y] == 1 &&
- pheno[x + 2, y - 2] == 1 && pheno[x - 2, y + 2] == 1)
- {
- score += 30;
- }
- // If we are surrounded by water
- if (pheno[x, y + 1] == 0 && pheno[x, y - 1] == 0 &&
- pheno[x + 1, y] == 0 && pheno[x - 1, y] == 0 &&
- pheno[x + 1, y - 1] == 0 && pheno[x - 1, y + 1] == 0)
- {
- score -= 15;
- }
- } else
- {
- //if (x <= 1 || x >= Params.dimX - 1 || y <= 1 || y >= Params.dimY - 31)
- score -= 350;
- }
- score += 5;
- return score;
- }
- private int mountainTerrain(int x, int y) {
- int score = 0;
- if (!(x <= 3 || x >= Params.dimX - 3 || y <= 3 || y >= Params.dimY - 3))
- {
- if (pheno[x, y + 1] == 2 && pheno[x, y - 1] == 2 &&
- pheno[x + 1, y] == 2 && pheno[x - 1, y] == 2 &&
- pheno[x + 1, y - 1] == 2 && pheno[x - 1, y + 1] == 2)
- {
- score += 5;
- }
- // If we are surrounded by even more terrain
- else if (pheno[x, y + 2] == 2 && pheno[x, y - 2] == 2 &&
- pheno[x + 2, y] == 2 && pheno[x - 2, y] == 2 &&
- pheno[x + 2, y - 2] == 2 && pheno[x - 2, y + 2] == 2)
- {
- score += 10;
- }
- if (pheno[x, y + 1] == 1 && pheno[x, y - 1] == 1 &&
- pheno[x + 1, y] == 1 && pheno[x - 1, y] == 1 &&
- pheno[x + 1, y - 1] == 1 && pheno[x - 1, y + 1] == 1)
- {
- score += 15;
- }
- // If we are surrounded by even more terrain
- else if (pheno[x, y + 2] == 1 && pheno[x, y - 2] == 1 &&
- pheno[x + 2, y] == 1 && pheno[x - 2, y] == 1 &&
- pheno[x + 2, y - 2] == 1 && pheno[x - 2, y + 2] == 1)
- {
- score += 30;
- }
- // If we are surrounded by water
- else if (pheno[x, y + 1] == 0 && pheno[x, y - 1] == 0 &&
- pheno[x + 1, y] == 0 && pheno[x - 1, y] == 0 &&
- pheno[x + 1, y - 1] == 0 && pheno[x - 1, y + 1] == 0)
- {
- score -= 90;
- }
- else
- score -= 15;
- } else
- {
- //if (x <= 1 || x >= Params.dimX - 1 || y <= 1 || y >= Params.dimY - 31)
- score -= 350;
- }
- return score;
- }
- /// <summary>
- /// Display the map in a picturebox
- /// </summary>
- public void show(PictureBox pb)
- {
- System.Drawing.SolidBrush myBrush;
- if (bitm == null)
- {
- bitm = new Bitmap(Params.dimX, Params.dimY);
- myBrush = new System.Drawing.SolidBrush(G.ca[0]);
- Graphics gra = Graphics.FromImage(bitm);
- gra.FillRectangle(myBrush,0,0, Params.dimX, Params.dimY); //this is your code for drawing rectangles
- for (int x=0; x< Params.dimX; x++)
- {
- for (int y = 0; y < Params.dimY; y++)
- {
- if (pheno[x,y] > 0)
- {
- bitm.SetPixel(x, y, G.ca[pheno[x,y]]);
- }
- }
- }
- }
- pb.Image = bitm;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement