diff --git a/Artist/PixelArtist.py b/Artist/PixelArtist.py index e0c706a..3ac6b25 100644 --- a/Artist/PixelArtist.py +++ b/Artist/PixelArtist.py @@ -2,6 +2,7 @@ from PIL import Image, ImageDraw, ImageOps, ImageFont from GridSystem import GridSystem from Settings import colors +from Life import Plant @attr.s class PixelArtist(object): @@ -12,7 +13,7 @@ def drawPlantGeneration(self, lifeforms, filename, columns): gridedForms = [] for lifeform in lifeforms: - gridedForms.append(self.grids.arrayToGrid(lifeform, columns)) + gridedForms.append(self.grids.arrayToGrid(lifeform.dna, columns)) lifeFormWidth = len(gridedForms[0][0]) lifeFormHeight = len(gridedForms[0]) diff --git a/God/God.py b/God/God.py index 2a64740..9834482 100644 --- a/God/God.py +++ b/God/God.py @@ -1,6 +1,7 @@ import attr from random import randint, shuffle from Artist import GridSystem +from Life import Plant @attr.s class God(object): @@ -56,7 +57,7 @@ def breed(self, lifeforms): print "Breeding..." nextGen = [] - segments = self.pickRandomDivisor_(len(lifeforms[0])) + segments = self.pickRandomDivisor_(len(lifeforms[0].dna)) print "DNA Splice length: ", segments segmentedPlants = self.sliceToSegments_(lifeforms, segments) @@ -69,13 +70,14 @@ def breed(self, lifeforms): parent2 = segmentedPlants[randint(0, len(segmentedPlants)-1)]#segmentedPlants[(i+1) % len(segmentedPlants)] breeders = [parent1, parent2] - newPlant = [] + newPlantDNA = [] for j in range(0, len(segmentedPlants[i])): side = randint(0, 1) - newPlant += breeders[side][j] + newPlantDNA += breeders[side][j] - nextGen.append(newPlant) + plant = Plant(newPlantDNA) + nextGen.append(plant) print len(nextGen), " offspring produced." return nextGen @@ -85,8 +87,8 @@ def sliceToSegments_(self, lifeforms, segments): for plant in lifeforms: plantSegments = [] - for i in range(0, len(plant), segments): - plantSegments.append(plant[i:i + segments]) + for i in range(0, len(plant.dna), segments): + plantSegments.append(plant.dna[i:i + segments]) segmentedPlants.append(plantSegments) return segmentedPlants @@ -120,7 +122,7 @@ def mutate(self, lifeforms): else: for i in range(0, numMutations): newVal = hex(randint(0, 15) )[2:] - lifeform[randint(0, len(lifeform))-1] = newVal + lifeform.dna[randint(0, len(lifeform.dna))-1] = newVal mutateLifeforms.append(lifeform) @@ -132,7 +134,7 @@ def trimDeadCells(self, lifeforms): for lifeform in lifeforms: fixedLifeform = [] - lifeFormGrid = self.grids.arrayToGrid(lifeform, self.lifeFormWidth) + lifeFormGrid = self.grids.arrayToGrid(lifeform.dna, self.lifeFormWidth) # All energy is calculated by checking all cells for y in range(0, self.lifeFormHeight): @@ -144,7 +146,9 @@ def trimDeadCells(self, lifeforms): for row in lifeFormGrid: fixedLifeform += row - trimmedLifeforms.append(fixedLifeform) + plant = Plant(fixedLifeform) + + trimmedLifeforms.append(plant) return trimmedLifeforms @@ -152,12 +156,15 @@ def trimDeadCells(self, lifeforms): Calculates the score for a lifeform. Args: - lifeFormArray (Array) : lifeform DNA + lifeform (Plant) : Plant lifeform Returns: int: score for how successful a lifeform is """ - def judgeLifeform(self, lifeFormArray): - lifeFormGrid = self.grids.arrayToGrid(lifeFormArray, self.lifeFormWidth) + def judgeLifeform(self, lifeform): + if lifeform.fitness: + return lifeform.fitness + + lifeFormGrid = self.grids.arrayToGrid(lifeform.dna, self.lifeFormWidth) # Base values of resources needed for any lifeform energyNeeded = 100 @@ -188,6 +195,8 @@ def judgeLifeform(self, lifeFormArray): # bonus for living cells score += self.countRealCells_(lifeFormGrid) + lifeform.fitness = score + return score @@ -348,13 +357,15 @@ def createLife(self): def createRandomLifeform(self, size): - lifeForm = [] + lifeFormDNA = [] for i in range(0, size[0]*size[1]): # Favors some empty space for starting generation if randint(0, 1) > 0: - lifeForm.append('0') + lifeFormDNA.append('0') else: - lifeForm.append(hex(randint(0, 15) )[2:]) + lifeFormDNA.append(hex(randint(0, 15) )[2:]) + + plant = Plant(lifeFormDNA) - return lifeForm + return plant diff --git a/Life/Plant.py b/Life/Plant.py new file mode 100644 index 0000000..4861eff --- /dev/null +++ b/Life/Plant.py @@ -0,0 +1,15 @@ +import attr + +@attr.s +class Plant(object): + dna = attr.ib() + fitness = attr.ib() + _fitness = False + + @property + def fitness(self): + return self._fitness + + @fitness.setter + def fitness(self, newFitness): + self._fitness = newFitness diff --git a/Life/__init__.py b/Life/__init__.py new file mode 100644 index 0000000..38b2394 --- /dev/null +++ b/Life/__init__.py @@ -0,0 +1 @@ +from Plant import Plant diff --git a/art/rendered/.DS_Store b/art/rendered/.DS_Store index 5008ddf..34be848 100644 Binary files a/art/rendered/.DS_Store and b/art/rendered/.DS_Store differ diff --git a/art/rendered/untouched_parents_squared_success_gen_0.png b/art/rendered/untouched_parents_squared_success_gen_0.png index f8abfdd..8ad4b26 100644 Binary files a/art/rendered/untouched_parents_squared_success_gen_0.png and b/art/rendered/untouched_parents_squared_success_gen_0.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_10.png b/art/rendered/untouched_parents_squared_success_gen_10.png index b821fab..04277d8 100644 Binary files a/art/rendered/untouched_parents_squared_success_gen_10.png and b/art/rendered/untouched_parents_squared_success_gen_10.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_19.png b/art/rendered/untouched_parents_squared_success_gen_19.png index 21253b4..67567fe 100644 Binary files a/art/rendered/untouched_parents_squared_success_gen_19.png and b/art/rendered/untouched_parents_squared_success_gen_19.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_20.png b/art/rendered/untouched_parents_squared_success_gen_20.png new file mode 100644 index 0000000..5969c6d Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_20.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_30.png b/art/rendered/untouched_parents_squared_success_gen_30.png new file mode 100644 index 0000000..072bf55 Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_30.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_40.png b/art/rendered/untouched_parents_squared_success_gen_40.png new file mode 100644 index 0000000..665a6be Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_40.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_50.png b/art/rendered/untouched_parents_squared_success_gen_50.png new file mode 100644 index 0000000..afa5060 Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_50.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_60.png b/art/rendered/untouched_parents_squared_success_gen_60.png new file mode 100644 index 0000000..b41c85e Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_60.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_70.png b/art/rendered/untouched_parents_squared_success_gen_70.png new file mode 100644 index 0000000..9b98b0b Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_70.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_80.png b/art/rendered/untouched_parents_squared_success_gen_80.png new file mode 100644 index 0000000..89bb817 Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_80.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_90.png b/art/rendered/untouched_parents_squared_success_gen_90.png new file mode 100644 index 0000000..001d67f Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_90.png differ diff --git a/art/rendered/untouched_parents_squared_success_gen_99.png b/art/rendered/untouched_parents_squared_success_gen_99.png new file mode 100644 index 0000000..10cbb20 Binary files /dev/null and b/art/rendered/untouched_parents_squared_success_gen_99.png differ diff --git a/main.py b/main.py index c321e98..c3154a5 100644 --- a/main.py +++ b/main.py @@ -16,8 +16,8 @@ # Default settings generations = 20 -initialPopSize = 20 -survivalSize = 8 +initialPopSize = 50 +survivalSize = 10 plantWidth = 16 plantHeight = 32 rootStart = 0.8