Class Simulation
In: app/models/simulation.rb
Parent: ActiveRecord::Base

Schema Information

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

Methods

Public Instance methods

choose three random Creatures, kill the weakest one, mate the remaining two

[Source]

    # 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

least fit living Creature

[Source]

    # File app/models/simulation.rb, line 27
27:         def least_fit
28:           find(:first, :conditions => ["fitness is not null and killed_at is null"], :order => "fitness DESC")
29:         end

most fit living Creature

[Source]

    # File app/models/simulation.rb, line 22
22:         def most_fit
23:           find(:first, :conditions => ["fitness is not null and killed_at is null"], :order => "fitness ASC")
24:         end

run the Simulation

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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

[Source]

    # 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

[Validate]