I think there was still a bug as the last right is also the first one on the left
Hereās a new version of the code that does the mutation in more lazy fashion. I removed the extra mutation live_loops as i understand calling the mutate after the each loop does exactly the same thing. Added also some helper functions to make the code more readable.
I felt like all these changes were making the changes too slow for me, so i added some values to the initial state to kickstart it. Also used only the Rule 150 this time as I feel like when combining the different rules the melody seems bit out of sync. Also noticed that if you use Rule 150 with only 7 values it quickly turns to all zeros, so added a few extra notes.
use_debug false
generations = {
:gen1=>{:cells=>[0, 0, 1, 0, 0, 0, 0, 1, 1]},
:gen2=>{:cells=>[1, 0, 0, 0, 1, 0, 0, 0, 0]}
}
# Rule 110 https://en.wikipedia.org/wiki/Rule_110
rule_110 = {
"111" => 0, "110" => 1,
"101" => 1, "100" => 0,
"011" => 1, "010" => 1,
"001" => 1, "000" => 0
}
rule_150 = {
"111" => 1, "110" => 0,
"101" => 0, "100" => 1,
"011" => 0, "010" => 1,
"001" => 1, "000" => 0
}
define :cells do |gen|
generations[gen][:cells]
end
define :store_state do |gen|
generations[gen][:last] = generations[gen][:cells].dup # dup to create new object
end
define :mutate do |rule, gen, i|
store_state gen if i == 0 # Store state in first cycle
cells = generations[gen][:cells]
last_gen = generations[gen][:last]
left = i > 0 ? i - 1 : cells.length - 1;
right = i < cells.length - 1 ? i + 1 : 0;
pattern = "#{last_gen[left]}#{last_gen[i]}#{last_gen[right]}";
cells[i] = rule[pattern]
end
use_synth :pluck
use_synth_defaults release: 1.5, coef: 0.4
with_fx :reverb, mix: 0.4 do
with_fx :flanger, wave: 3, depth: 7, decay: 1.5 do
live_loop :organism_1 do
print cells(:gen1)
cells(:gen1).each_with_index do |s,i|
play (degree i+1, :d, :dorian), pan: rrand(-0.5, 0.5) if s==1
sleep 0.25
end
mutate(rule_150, :gen1, tick%cells(:gen1).length)
end
live_loop :organism_2 do
print cells(:gen2)
cells(:gen2).each_with_index do |s,i|
play (degree i+1, :d3, :dorian), pan: rrand(-0.5, 0.5) if s==1
sleep 0.25
end
mutate(rule_150, :gen2, tick%cells(:gen2).length)
end
end
end