| Class | Simulation |
| In: |
app/models/simulation.rb
|
| Parent: | ActiveRecord::Base |
Schema version: 2
Table name: simulations
id :integer(11) not null, primary key
baseline_image :string(255) default("heart")
maximum_births :integer(11) default(100000)
population_size :integer(11) default(100)
mutation_rate :integer(11) default(5)
mutation_strength :integer(11) default(20)
organism_complexity :integer(11) default(4)
fitness_threshold :float default(2.0)
stud_most_fit :boolean(1)
created_at :datetime
updated_at :datetime
choose three random Creatures, kill the weakest one, mate the remaining two
# File app/models/simulation.rb, line 80
80: def fight_and_mate
81: creatures = self.three_creatures
82:
83: # a lower fitness score is actually better
84: # a fitness score of 0.0 means that the image is a mirror image of the baseline
85: creatures.sort!{|a,b| a.fitness <=> b.fitness}
86:
87: # kill weakest one
88: creatures[2].kill_off
89:
90: # mate the remaining two
91: child = creatures[0].mate(creatures[1])
92:
93: if child
94: child.mutate
95: child.render
96: child.determine_fitness
97: end
98: end
run the Simulation
# File app/models/simulation.rb, line 55
55: def run_simulation
56: FileUtils.mkdir("public/images/simulation#{self.id.to_s}")
57:
58: Utility.create_life(self)
59:
60: until self.termination_conditions
61: self.fight_and_mate
62: end
63:
64: # return the best creature of the lot
65: Creature.find(:first, :order => "fitness ASC")
66: end
return true if it is time to stop the Simulation
# File app/models/simulation.rb, line 69
69: def termination_conditions
70: if self.creatures.size > self.maximum_births or Creature.find(:first, :conditions => ["fitness < ?", self.fitness_threshold])
71: true
72: else
73: false
74: end
75: end
find three living Creatures to use in fight_and_mate
# File app/models/simulation.rb, line 101
101: def three_creatures
102: living_things = Creature.find(:all, :conditions => ["killed_at is null and simulation_id = ?", self.id])
103:
104: # less than three living things? let's not create an infinite loop...
105: if living_things.size < 3
106: false
107: else
108: three = Array.new
109:
110: # if we're studding out the most fit Creature, let's grab the best and worst from the gene pool to speed things up
111: if self.stud_most_fit
112: three << self.creatures.most_fit
113: three << self.creatures.least_fit
114: end
115:
116: while three.size < 3
117: three << living_things[rand(living_things.size)]
118: three.uniq!
119: end
120: three
121: end
122: end
perform validations
# File app/models/simulation.rb, line 47
47: def validate
48: self.errors.add_to_base "Maximum births must be greater than population size" if self.population_size >= self.maximum_births
49: self.errors.add_to_base "Population size must be at least three" if self.population_size < 3
50: self.errors.add_to_base "Mutation strength must be between 1 and 100" unless 0 < self.mutation_strength and self.mutation_strength <= 100
51: self.errors.add_to_base "Mutation rate must be between 1 and 100" unless 0 < self.mutation_rate and self.mutation_rate <= 100
52: end