evol_game_simu 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 681faa7e19c2e016796984902bab09570abcb26037f55cae98603db5454a8d78
4
- data.tar.gz: 478de2a71df41746282373dfb3162b9420e2548b6ec3345ddffa143458b0d941
3
+ metadata.gz: 03c47726493c14799f0496b0ab9f134ef1860d63c0d03d1fb443bd5da2d54e5e
4
+ data.tar.gz: 9f02d4c6bd3290f60323f586f53973741cc86d445522cee8a813b24a9b992bcc
5
5
  SHA512:
6
- metadata.gz: 79afff3307d74ec3cc4cbb5f0abde8896bc2eacf430ecdcedf6949f6c8a1eadcf02968e1fabfb8b6b25d31849ab13c1d67373ca36858b5e002b0399986e4e873
7
- data.tar.gz: b2100f14b330c61bddd542ded41f4a9fcbc246c04325fd0c847fe9124713420120aab5d2888491af1d7fa631316df484f984dec71755d4a46acf676180f95265
6
+ metadata.gz: 2d0430da58d375e8827f643075d1513e0bef90e1f7bcf119c492f4068fc1cc959416e149a756d99b9a80500372ccd9a6c5dfd7e411c750a5b88138e2cc86e634
7
+ data.tar.gz: 2e19d179aeeaea1174cfe1a2ec54619fb900722a2a9e4c4bff9c3cf388d7107873e480e4883b78a9416a93b15b4302a1f290575d57677c686576f30cbcc4ec92
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- evol_game_simu (0.1.1)
4
+ evol_game_simu (0.2.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,3 +1,3 @@
1
1
  module EvolGameSimu
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,19 +1,27 @@
1
1
  require "evol_game_simu/version"
2
2
 
3
- $Cooperator = [0,0, [[0, [0, 0]]]]
4
- $Defector = [0,0, [[1, [0, 0]]]]
5
- $Titfortat = [0,0, [[0, [0, 1]],
6
- [1, [0, 1]]]]
3
+ # now i say again
4
+ # this time, it was also very tempting to do mutation
5
+ # but then please remember this bug
6
+ # you mutate at posn x, somehow it mutates also at posn y
7
+ # it breaks your simulation
8
+ # you cannot even manually set the value in posn y back
9
+ # wow
10
+
11
+ $Cooperator = [0, [[0, [0, 0]]]].freeze
12
+ $Defector = [0, [[1, [0, 0]]]].freeze
13
+ $Titfortat = [0, [[0, [0, 1]],
14
+ [1, [0, 1]]]].freeze
7
15
  def Cooperator()
8
- $Cooperator
16
+ $Cooperator.clone
9
17
  end
10
18
  def Defector()
11
- $Defector
19
+ $Defector.clone
12
20
  end
13
21
  def Titfortat()
14
- $Titfortat
22
+ $Titfortat.clone
15
23
  end
16
- $PAY = [[[3,3],[0,4]],[[4,0],[1,1]]]
24
+ $PAY = [[[3,3],[0,4]],[[4,0],[1,1]]].freeze
17
25
  $ACTION = 2
18
26
  $DELTA = 0.9
19
27
  $ROUNDS = 400
@@ -21,39 +29,37 @@ def generate_deltas(delta, rounds)
21
29
  result = (0..rounds-1).to_a
22
30
  result.map { |round| delta ** round }
23
31
  end
24
- $DELTAS = generate_deltas($DELTA, $ROUNDS)
32
+ $DELTAS = generate_deltas($DELTA, $ROUNDS).freeze
25
33
 
26
34
  def sum(arr)
27
35
  arr.reduce() { | total, n | total += n }
28
36
  end
29
37
  def interact(machine1,machine2,rounds)
30
38
  result = []
31
- (1..rounds).reduce(result) do | result |
32
- current1,current2 = machine1[1],machine2[1]
33
- states1, states2 = machine1[2], machine2[2]
39
+ current1, current2 = machine1[0],machine2[0]
40
+ (1..rounds).reduce(result) do | result |
41
+ states1, states2 = machine1[1], machine2[1]
34
42
  cstate1, cstate2 = states1[current1], states2[current2]
35
43
  action1,action2 = cstate1[0], cstate2[0]
36
44
  dispatch1,dispatch2 = cstate1[1], cstate2[1]
37
- machine1[1],machine2[1] = dispatch1[action2], dispatch2[action1]
45
+ current1, current2 = dispatch1[action2], dispatch2[action1]
38
46
  result << $PAY[action1][action2]
39
47
  end
40
- machine1[1],machine2[1]=machine1[0],machine2[0]
41
48
  result
42
49
  end
43
50
  def match_machines(machine1,machine2,rounds, deltas)
44
51
  pay1, pay2 = 0, 0
52
+ current1, current2 = machine1[0], machine2[0]
45
53
  for i in 0..rounds-1 do
46
- current1,current2 = machine1[1],machine2[1]
47
- states1, states2 = machine1[2], machine2[2]
54
+ states1, states2 = machine1[1], machine2[1]
48
55
  cstate1, cstate2 = states1[current1], states2[current2]
49
56
  action1,action2 = cstate1[0], cstate2[0]
50
57
  dispatch1,dispatch2 = cstate1[1], cstate2[1]
51
- machine1[1],machine2[1] = dispatch1[action2], dispatch2[action1]
58
+ current1,current2 = dispatch1[action2], dispatch2[action1]
52
59
  p1,p2 = $PAY[action1][action2]
53
60
  pay1 += p1*deltas[i]
54
61
  pay2 += p2*deltas[i]
55
62
  end
56
- machine1[1], machine2[1] = machine1[0] , machine2[0]
57
63
  return pay1.round(2), pay2.round(2)
58
64
  end
59
65
  def generate_dispatch(states)
@@ -65,96 +71,116 @@ end
65
71
  def generate_machine(states)
66
72
  init = rand(states)
67
73
  m = Array.new(states) { generate_state(states) }
68
- [init,init]+[m]
69
- end
70
-
71
- def reset_machine(machine)
72
- machine[1] = machine[0]
74
+ m = [init]+[m]
75
+ m.freeze
73
76
  end
74
-
75
77
  def mutate_init(machine)
76
- states = machine[2].length
77
- newinit = rand(states)
78
+ init, ss = machine
79
+ newinit = rand(ss.length)
78
80
  puts "initial state: #{machine[0]} -> #{newinit}"
79
- machine[0], machine[1] = newinit, newinit
80
- return
81
+ new = [newinit] + [ss]
82
+ new.freeze
81
83
  end
82
84
 
83
85
  def mutate_action(machine)
84
- states = machine[2].length
85
- state = rand(states)
86
- newact = rand($ACTION)
87
- puts "state #{state}: change action #{machine[2][state][0]} -> #{newact}"
88
- machine[2][state][0] = newact
89
- return
90
- end
91
-
92
- def mutate_dispatch!(machine)
93
- states = machine[2].length
94
- state = rand(states)
95
- reactto = rand($ACTION)
86
+ init, states = machine
87
+ ss = states.length
88
+ s = rand(ss)
96
89
  newact = rand($ACTION)
97
- puts "state #{state}: change reaction to #{reactto} from #{machine[2][state][1][reactto]} -> #{newact}"
98
- machine[2][state][1][reactto] = newact
99
- return
90
+ puts "state #{s}: change action #{machine[1][s][0]} -> #{newact}"
91
+ newss = []
92
+ for i in 0..ss-1 do
93
+ if i == s
94
+ newss << [newact, states[i][1].clone]
95
+ else
96
+ newss << states[i].clone
97
+ end
98
+ end
99
+ newss = [init] + [newss]
100
+ newss.freeze
100
101
  end
101
102
 
102
103
  def mutate_dispatch(machine)
103
- i, c, ss = machine
104
- s = rand(ss.length)
104
+ init, states = machine
105
+ ss = states.length
106
+ s = rand(states.length)
105
107
  reactto = rand($ACTION)
106
- newact=rand($ACTION)
107
- puts "state #{s}: change reaction to #{reactto} from #{machine[2][s][1][reactto]} -> #{newact}"
108
-
109
- b = []
110
- for index in 0..ss.length-1 do
111
- if index == s
112
- act, disp = ss.dup[index].dup
108
+ newdispatch=rand(ss)
109
+ puts "state #{s}: change reaction to #{reactto} from #{machine[1][s][1][reactto]} -> #{newdispatch}"
110
+ newss = []
111
+ for i in 0..ss-1 do
112
+ if i == s
113
+ act, disp = states[i].clone
113
114
  toc, tod = disp
114
115
  if reactto == 0
115
- toc = newact
116
+ toc = newdispatch
116
117
  else
117
- tod = newact
118
+ tod = newdispatch
118
119
  end
119
- b << [act, [toc, tod]]
120
+ newss << [act, [toc, tod]]
120
121
  else
121
- b << ss.dup[index].dup
122
+ newss << states[i].clone
122
123
  end
123
124
  end
124
- b = [i,c]+[b]
125
- machine = b
126
- return
125
+ newss = [init] + [newss]
126
+ newss.freeze
127
127
  end
128
128
 
129
-
130
129
  def add_state(machine)
131
- newstates = machine[2].length + 1
132
- newstate = generate_state(newstates)
133
- machine[2] << newstate
134
- oldstate = rand(newstates - 1)
130
+ init, states = machine
131
+ ss = states.length
132
+ newss = ss + 1
133
+ newstate = generate_state(newss)
134
+
135
+ newstates = []
136
+ s = rand(ss)
135
137
  moveendof = rand($ACTION)
136
- puts "add new state at the end: state #{oldstate}: reaction to #{moveendof} goes to the new state"
137
- machine[2][oldstate][1][rand($ACTION)] = machine[2].length - 1
138
- return
138
+ puts "add new state at the end: state #{s}: reaction to #{moveendof} goes to the new state"
139
+
140
+ for i in 0..ss-1 do
141
+ if i == s
142
+ act, disp = states[i].clone
143
+ toc, tod = disp
144
+ if moveendof == 0
145
+ toc = newss - 1
146
+ else
147
+ tod = newss - 1
148
+ end
149
+ newstates << [act, [toc, tod]]
150
+ else
151
+ newstates << states[i].clone
152
+ end
153
+ end
154
+ newstates << newstate
155
+ newstates = [init] + [newstates]
156
+ newstates.freeze
139
157
  end
140
158
  def random_member(arr)
141
159
  arr[rand(arr.length)]
142
160
  end
143
161
  def del_state(machine)
144
- states = machine[2].length
145
- return puts "\n" if states == 1
146
- pos = (0..states-1).to_a
147
- state = rand(states)
148
- pos.delete_at(state)
149
- for i in 0..states-1 do
150
- dispatch = machine[2][i][1]
151
- dispatch[0] = random_member(pos) if dispatch[0] == state
152
- dispatch[1] = random_member(pos) if dispatch[1] == state
162
+ init, states = machine
163
+ ss = states.length
164
+ if ss == 1
165
+ puts "\n"
166
+ return machine.clone
153
167
  end
154
- puts "delete state #{state}"
168
+ pos = (0..ss-1).to_a
169
+ s = rand(ss)
170
+ pos.delete_at(s)
171
+ newss = []
172
+ for i in 0..ss-1 do
173
+ act, dispatch = states[i]
174
+ toc, tod = dispatch
175
+ toc = random_member(pos) if toc == s
176
+ tod = random_member(pos) if tod == s
177
+ newss << [act, [toc, tod]]
178
+ end
179
+ puts "delete state #{s}"
180
+ newss = [init] + [newss]
181
+ newss.freeze
155
182
  end
156
- def mutate_machine(machine,i)
157
- print("machine #{i}: ")
183
+ def mutate_machine(machine)
158
184
  r = rand(5)
159
185
  case r
160
186
  when 0
@@ -172,7 +198,6 @@ end
172
198
  def generate_population(n)
173
199
  Array.new(n) { generate_machine(1) }
174
200
  end
175
-
176
201
  def match_population(p,n,rounds,deltas)
177
202
  res = []
178
203
  for i in (0..n-2).step(2) do
@@ -221,22 +246,19 @@ def throws(arr,s)
221
246
  res
222
247
  end
223
248
 
224
- def regenerate(p,arr)
249
+ def regenerate!(p,arr)
225
250
  subs = arr.map{|e| p[e]}
226
251
  for i in 0..subs.length-1 do
227
252
  p[i] = subs[i]
228
253
  end
229
254
  end
230
255
 
231
- def mutate(p,n)
256
+ def mutate!(p,n)
232
257
  for i in 0..n-1 do
233
- mutate_machine(p[i],i)
258
+ p[i] = mutate_machine(p[i])
234
259
  end
235
260
  end
236
261
 
237
- def reset(population)
238
- population.map{ |machine| reset_machine(machine) }
239
- end
240
262
  $N = 100
241
263
  $P = generate_population $N
242
264
  def evolve(p,n,cycles,speed,mutation,rounds,deltas)
@@ -252,10 +274,10 @@ def evolve(p,n,cycles,speed,mutation,rounds,deltas)
252
274
  a = accumulate(res)
253
275
  t = throws(a, speed)
254
276
 
255
- regenerate(p,t)
277
+ regenerate!(p,t)
256
278
  p.shuffle!
257
- mutate(p,mutation)
258
- reset(p)
279
+ mutate!(p,mutation)
280
+
259
281
  end
260
282
  avg
261
283
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evol_game_simu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - chi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-01 00:00:00.000000000 Z
11
+ date: 2019-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler