minigame 0.0.1 → 0.0.2

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YWY0MTkxZDc2ZTg1NWExMTgwODMyMDAwNjEwNmQ3YzZiODJmYTM1Zg==
4
+ OWQ1MjQwNjNjNGM5MTZiNWQ2ZDE3ZjQ4YWUxYmZmZjMyM2QxY2NmNA==
5
5
  data.tar.gz: !binary |-
6
- NGYzYTBiYTQ0ODFkNDg5OWVlYWRiZDJmYTJjNDIyNzZlY2VmNzk3Yw==
6
+ ZjMyNjg1N2ZjYjY0ODI1YmY5ZTdhMDA1NzkxM2Y5OWRhOGIxMThhMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTM4MDgzZGY3MWNlNWUwOWY0ZGE0ZmM2ZDg4NWQ0NmQxNzU0YTc2Y2JiNWQy
10
- MWMzMTA3MmY5MDk1Mjk0ZjVjMGNkODNlYTU0OGU2ZjJlMGYzYTdjYTBmOWE3
11
- NTA2OWMzMDhhNGU2OGFmYjFhNzA5ZGJiNjVjZGMyODg2MThiYTg=
9
+ YzBlNDY5ODdkZTdlMTRjNzExYTNhMjVlZGViYzQxMDZlNzdkNDMyODQyNzhk
10
+ Y2RiMzA0NGU4OGM1M2IxMzY5YmM5ZGQ1MTJhNDQyMTYyMzJiNjUwYzYxYzVi
11
+ NzljNDg0NzQ1OTg5ZjAxNzhjZDc2MTg1NGRlZWYyODI1Y2E4MjQ=
12
12
  data.tar.gz: !binary |-
13
- YjhlN2JiMzQzMjRmZDBmOGFjODQyMjA5Nzk5ZjRkZDAwZGYyN2Y4NGM3YjQ4
14
- ZjZhM2NjMWI4YmNlNWQwZjc3OTVkMDk3ZDQwODhiNGJjNmVhMzc4YWUxNjI1
15
- ZWJhZjk5YTNmMzUyMWMyMzUwYWNkY2ZiYTNjMzgzNzk1Y2RjNzA=
13
+ YjcyMmE3MjUyYzg0MDM5NGQyZWNmYmY4NDdjNjllYzdmZmI4YTYwNWYxZmM0
14
+ ODE4Mjk2Y2YwMTg5MmRiNzEzM2YzMjgyNGUzZjM1NzdlMDFhZjRmMWMzZjNm
15
+ YmYyMDM4NDY1MjZjNjRhNjYxMDJiY2ZjNWJlMGE4MDk0ZmFiMjM=
data/.gitignore CHANGED
@@ -91,6 +91,8 @@ capybara-*.html
91
91
  /log/*
92
92
  /tmp/*
93
93
  /db/*.sqlite3
94
+ /pkg
95
+ /pkg/*
94
96
  /public/system/*
95
97
  /coverage/
96
98
  /spec/tmp/*
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ # uncomment this line if your project needs to run something other than `rake`:
5
+ # script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in minigame.gemspec
4
4
  gemspec
5
- gem 'debugger'
5
+ #gem 'debugger'
data/Gemfile.lock CHANGED
@@ -1,27 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- minigame (0.0.1)
4
+ minigame (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- columnize (0.3.6)
10
- debugger (1.6.1)
11
- columnize (>= 0.3.1)
12
- debugger-linecache (~> 1.2.0)
13
- debugger-ruby_core_source (~> 1.2.3)
14
- debugger-linecache (1.2.0)
15
- debugger-ruby_core_source (1.2.3)
9
+ diff-lcs (1.2.4)
16
10
  minitest (5.0.6)
17
11
  rake (10.1.0)
12
+ rspec (2.13.0)
13
+ rspec-core (~> 2.13.0)
14
+ rspec-expectations (~> 2.13.0)
15
+ rspec-mocks (~> 2.13.0)
16
+ rspec-core (2.13.1)
17
+ rspec-expectations (2.13.0)
18
+ diff-lcs (>= 1.1.3, < 2.0)
19
+ rspec-mocks (2.13.1)
18
20
 
19
21
  PLATFORMS
20
22
  ruby
21
23
 
22
24
  DEPENDENCIES
23
25
  bundler (~> 1.3)
24
- debugger
25
26
  minigame!
26
27
  minitest
27
28
  rake
29
+ rspec
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
+ [![Build Status](https://travis-ci.org/wavell/minigame.png)](https://travis-ci.org/wavell/minigame)
1
2
  # MiniGame
2
3
  ## Simplistic Game Theory Library in Ruby
3
4
 
5
+ Installation
6
+ ```
7
+ gem install minigame
8
+ ```
9
+
4
10
  Usage:
5
11
 
6
12
  To create new players:
@@ -70,7 +76,7 @@ To get the list a weakly dominated strategies:
70
76
  # ------------------------|---------------------|------------------
71
77
  gs.weakly_dominated_list
72
78
 
73
- [{:name=>"Generic Training"}, {:name=>"Deny Training"}]
79
+ [{:name=>"Generic Training"}]
74
80
 
75
81
  ```
76
82
 
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
3
  Rake::TestTask.new do |t|
4
4
  t.libs << 'test'
5
+ system("bundle exec rspec spec/")
5
6
  end
6
7
 
7
8
  desc "Run tests"
@@ -79,7 +79,10 @@ module Gameable
79
79
  end
80
80
  end
81
81
  end
82
- dominated_list.flatten.uniq
82
+ dom = dominated_list.flatten.uniq
83
+ strict = strictly_dominated_list
84
+ weakly_dominated_list = dom.take_while{|i| strict.include?(i)==false}
85
+ weakly_dominated_list
83
86
  end
84
87
 
85
88
  def strategies_by_player(player)
@@ -1,3 +1,3 @@
1
1
  module Minigame
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/minigame.gemspec CHANGED
@@ -6,11 +6,11 @@ require 'minigame/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "minigame"
8
8
  spec.version = Minigame::VERSION
9
- spec.authors = ["Wavell Watson"]
10
- spec.email = ["wavell.watson@gmail.com"]
9
+ spec.authors = ["W Watson"]
10
+ spec.email = ["me@wwatson.me"]
11
11
  spec.description = %q{A game theory library}
12
12
  spec.summary = %q{A minimalistic game theory library that computes nash equilibrium}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/wavell/minigame"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -21,5 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "rspec"
24
25
 
25
26
  end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArrayOfHashes do
4
+ before(:each) do
5
+ class TestAOfH
6
+ include ArrayOfHashes
7
+ end
8
+ end
9
+
10
+ it "should instantiate with an array of hashes" do
11
+ aoh = TestAOfH.new [{keyname1: "test1", keyname2: "test2"},{keyname3: "test3", keyname4: "test4"}]
12
+ aoh.count.should == 2
13
+ end
14
+
15
+ it "should have enumerable functions" do
16
+ aoh = TestAOfH.new [{keyname1: "test1", keyname2: "test2"},{keyname3: "test3", keyname4: "test4"}]
17
+ @test2 = aoh.select{|x| x[:keyname2] == "test2"}
18
+ @test2.count.should == 1
19
+ end
20
+
21
+ it ".required_keys should reject non-symbols" do
22
+ aoh=TestAOfH.new
23
+ expect {
24
+ aoh.required_keys ["name", "description"]
25
+ }.to raise_error(RuntimeError,/Not a symbol/)
26
+ end
27
+
28
+ it ".required_keys should work as assignment" do
29
+ aoh=TestAOfH.new
30
+ expect {
31
+ aoh.required_keys = [:name, :description]
32
+ }.to_not raise_error
33
+ end
34
+
35
+ it ".required_keys should also work with a single symbol (not an array)" do
36
+ aoh=TestAOfH.new
37
+ expect {
38
+ aoh.required_keys = :name
39
+ }.to_not raise_error
40
+ end
41
+
42
+ it ".required_keys should accept a list of symbols" do
43
+ aoh=TestAOfH.new
44
+ expect {
45
+ aoh.required_keys([:name, :description])
46
+ }.to_not raise_error
47
+ end
48
+
49
+ it ".check_keys should allow a name" do
50
+ aoh=TestAOfH.new
51
+ expect {
52
+ aoh.check_keys({name: "Deny Training"})
53
+ }.to_not raise_error
54
+ end
55
+
56
+ it ".check_keys should raise an error if not passed a hash" do
57
+ aoh=TestAOfH.new
58
+ expect {
59
+ aoh.check_keys('notahash')
60
+ }.to raise_error(RuntimeError,/Not a Hash/)
61
+ end
62
+
63
+ it ".check_keys should check for name" do
64
+ aoh=TestAOfH.new
65
+ aoh.required_keys :name
66
+ expect {
67
+ aoh.check_keys({hmm: 'notahash'})
68
+ }.to raise_error(RuntimeError,/Name required/)
69
+ end
70
+
71
+ it "should allow addition of hashes with <<" do
72
+ aoh = TestAOfH.new
73
+ aoh << {keyname1: "test1", keyname2: "test2"}
74
+ aoh << {keyname3: "test3", keyname4: "test4"}
75
+ aoh.count.should == 2
76
+ end
77
+
78
+ it "should check for an required keys when initializing" do
79
+ aoh = TestAOfH.new
80
+ aoh.required_keys = [:name, :description]
81
+ expect {
82
+ aoh << {notname: "test1", description: "test2"}
83
+ }.to raise_error(RuntimeError,/Name required/)
84
+ end
85
+
86
+ it "should allow inserts when required keys are present" do
87
+ aoh = TestAOfH.new
88
+ aoh.required_keys = [:name, :description]
89
+ expect {
90
+ aoh << {name: "test1", description: "test2"}
91
+ aoh << {name: "test3", description: "test4"}
92
+ }.to_not raise_error
93
+ end
94
+ end
@@ -0,0 +1,4 @@
1
+ describe Gameable do
2
+ it "should create a game on another entity" do
3
+ end
4
+ end
@@ -0,0 +1,280 @@
1
+ require 'spec_helper'
2
+
3
+ describe Game do
4
+
5
+ # training game -- generic weakly dominated (not realistic)
6
+ #
7
+ # Employer: | Task Specific | Generic
8
+ # You: -----------------|---------------------|------------------
9
+ # | |
10
+ # Deny Training | (-2, -1) | (-2, -1)
11
+ # ------------------------|---------------------|------------------
12
+ # Accept Training | (1, 4) | (5, -2)
13
+ # ------------------------|---------------------|------------------
14
+ def game_with_weakly_dominated_strategies
15
+ strategies = Strategy.new [{name: "Accept Training"}, {name: "Generic Training"},{name: "Task Specific Training"},{name: "Deny Training"}]
16
+ accept = strategies.find{|x| x[:name] == "Accept Training"}
17
+ generic = strategies.find{|x| x[:name] == "Generic Training"}
18
+ task = strategies.find{|x| x[:name] == "Task Specific Training"}
19
+ deny = strategies.find{|x| x[:name] == "Deny Training"}
20
+ employer = Player.new name: "IBM"
21
+ employee = Player.new name: "John Smith"
22
+
23
+ strategy_profile = StrategyProfile.new
24
+ strategy_profile << {id: 1, strategy: generic, payoff: -2, player: employer}
25
+ strategy_profile << {id: 1, strategy: accept, payoff: 5, player: employee}
26
+
27
+ strategy_profile << {id: 2, strategy: generic, payoff: -1, player: employer}
28
+ strategy_profile << {id: 2, strategy: deny, payoff: -2, player: employee}
29
+
30
+ # not realistic
31
+ strategy_profile << {id: 3, strategy: task, payoff: -1, player: employer}
32
+ strategy_profile << {id: 3, strategy: deny, payoff: -2, player: employee}
33
+
34
+ strategy_profile << {id: 4, strategy: task, payoff: 4, player: employer}
35
+ strategy_profile << {id: 4, strategy: accept, payoff: 1, player: employee}
36
+ gs = Game.new
37
+ gs.strategy_profiles = strategy_profile
38
+ gs
39
+ end
40
+
41
+ # Regular training game -- generic strictly dominated
42
+ #
43
+ # Employer: | Task Specific | Generic
44
+ # You: -----------------|---------------------|------------------
45
+ # | |
46
+ # Deny Training | (-2, 0) | (-2, -1)
47
+ # ------------------------|---------------------|------------------
48
+ # Accept Training | (1, 4) | (5, -2)
49
+ # ------------------------|---------------------|------------------
50
+ before(:each) do
51
+ @strategies = Strategy.new [{name: "Accept Training"}, {name: "Generic Training"},{name: "Task Specific Training"},{name: "Deny Training"}]
52
+ @accept = @strategies.find{|x| x[:name] == "Accept Training"}
53
+ @generic = @strategies.find{|x| x[:name] == "Generic Training"}
54
+ @task = @strategies.find{|x| x[:name] == "Task Specific Training"}
55
+ @deny = @strategies.find{|x| x[:name] == "Deny Training"}
56
+ @employer = Player.new name: "IBM"
57
+ @employee = Player.new name: "John Smith"
58
+
59
+ @strategy_profile = StrategyProfile.new
60
+ @strategy_profile << {id: 1, strategy: @generic, payoff: -2, player: @employer}
61
+ @strategy_profile << {id: 1, strategy: @accept, payoff: 5, player: @employee}
62
+
63
+ @strategy_profile << {id: 2, strategy: @generic, payoff: -1, player: @employer}
64
+ @strategy_profile << {id: 2, strategy: @deny, payoff: -2, player: @employee}
65
+
66
+ @strategy_profile << {id: 3, strategy: @task, payoff: 0, player: @employer}
67
+ @strategy_profile << {id: 3, strategy: @deny, payoff: -2, player: @employee}
68
+
69
+ @strategy_profile << {id: 4, strategy: @task, payoff: 4, player: @employer}
70
+ @strategy_profile << {id: 4, strategy: @accept, payoff: 1, player: @employee}
71
+ @gs = Game.new
72
+ @gs.strategy_profiles = @strategy_profile
73
+ end
74
+
75
+ it ".strategies should allow assignment of strategies" do
76
+ @gs.strategy_profiles.count.should == 8
77
+ end
78
+
79
+ it ".payoff should return the payoff for a strategy and player" do
80
+ @gs.payoff(@generic, @employer).should == -2
81
+ end
82
+
83
+
84
+ it '.players should return a list of players' do
85
+ @gs.players.count.should == 2
86
+ end
87
+
88
+ it '.player_names should return a list of player names' do
89
+ @gs.player_names.count.should == 2
90
+ end
91
+
92
+ it '.opposing_players should return a list of players who receive payouts for the passed in strategy profile' do
93
+ gen_strat_profile = @gs.strategy_profiles.select{|x| x[:strategy][:name] == "Generic Training"}.first
94
+ @gs.opposing_players(gen_strat_profile).count.should == 1
95
+ end
96
+
97
+ it '.player_strategy_profiles should return a list of strategy profiles for the players' do
98
+ @gs.player_strategy_profiles(@employer).count.should == 4
99
+ end
100
+
101
+ it '.complementary_moves? should return a list of strategy profiles for a player other than the passed in profile' do
102
+ gen_strat_profile = @gs.strategy_profiles.select{|x| x[:strategy][:name] == @generic[:name]}.first
103
+ @gs.complementary_moves(gen_strat_profile).count.should == 1
104
+ @gs.complementary_moves(gen_strat_profile).first[:strategy][:name].should == @task[:name]
105
+ end
106
+
107
+ it '.opposing_player_strategy_profile should return the name of the opposing players strategy for the passed in profile' do
108
+ gen_strat_profile = @gs.strategy_profiles.select{|x| x[:strategy][:name] == @generic[:name]}.first
109
+ @gs.opposing_player_strategy_profile(gen_strat_profile)[:strategy][:name].should == @accept[:name]
110
+ end
111
+
112
+ it '.better_payoffs? should return a list of strategy profiles that are better than the passed in profile for the passed in player' do
113
+ gen_strat_profile = @gs.strategy_profiles.select{|x| x[:strategy][:name] == @generic[:name]}.first
114
+ #@gs.better_moves?(gen_strat_profile).first[:strategy][:name].should == @task[:name]
115
+ @gs.better_payoffs?(gen_strat_profile).first[:strategy][:name].should == @task[:name]
116
+ end
117
+
118
+ # should return this
119
+ # Employer: | Task Specific | Generic
120
+ # You: -----------------|---------------------|------------------
121
+ # | get all alternates | Pass in this
122
+ # Deny Training | ( , 0) | (-2, )
123
+ # ------------------------|---------------------|------------------
124
+ # Accept Training | | (5, )
125
+ # ------------------------|---------------------|------------------
126
+ it '.worse_payoffs? should return a list of strategy profiles that are worse than the passed in profile for the passed in player'do
127
+ gen_strat_profile = @gs.strategy_profiles.select{|x| x[:strategy][:name] == @accept[:name]}.first
128
+ @gs.worse_payoffs?(gen_strat_profile).should_not be_nil
129
+ @gs.worse_payoffs?(gen_strat_profile).should_not be_empty
130
+ @gs.worse_payoffs?(gen_strat_profile)[0][:payoff].should == -2
131
+ end
132
+
133
+ # Employer: | Task Specific | Generic
134
+ # You: -----------------|---------------------|------------------
135
+ # | |
136
+ # Deny Training | (-2, -1) | (-2, -1)
137
+ # ------------------------|---------------------|------------------
138
+ # Accept Training | (1, 4) | (5, -2)
139
+ # ------------------------|---------------------|------------------
140
+ it '.better_or_equal_moves? should return a list of strategy profiles that are better than the passed in profile for the passed in player' do
141
+ gs = game_with_weakly_dominated_strategies
142
+ # gets the generic strategy vs the deny training profile
143
+ gen_strat_profile = gs.strategy_profiles.select{|x| x[:strategy][:name] == @generic[:name]}[1]
144
+ gs.better_payoffs?(gen_strat_profile).count.should == 0
145
+ gs.better_or_equal_payoffs?(gen_strat_profile).count.should == 1
146
+ gs.better_or_equal_payoffs?(gen_strat_profile).first[:strategy][:name].should == @task[:name]
147
+ end
148
+
149
+ it ".strictly_dominated_list should return a list of strictly dominated strategies" do
150
+ # generic training and deny training are strictly dominated
151
+ @gs.strictly_dominated_list.count.should == 2
152
+ @gs.strictly_dominated_list.select{|x| x[:name] == @generic[:name]}.count.should > 0
153
+ @gs.strictly_dominated_list.select{|x| x[:name] == @deny[:name]}.count.should > 0
154
+ end
155
+
156
+ # Employer: | Task Specific | Generic
157
+ # You: -----------------|---------------------|------------------
158
+ # | |
159
+ # Deny Training | (-2, -1) | (-2, -1)
160
+ # ------------------------|---------------------|------------------
161
+ # Accept Training | (1, 4) | (5, -2)
162
+ # ------------------------|---------------------|------------------
163
+ it ".equal_moves should return a list of moves for a matchup that are equal in payoffs" do
164
+ # in the above game generic training is weakly dominated
165
+ gs = game_with_weakly_dominated_strategies
166
+ gen_strat_profiles = gs.strategy_profiles.select do |x|
167
+ x[:strategy][:name] == @generic[:name] &&
168
+ x[:payoff] == -1
169
+ end
170
+ gen_strat_profile = gen_strat_profiles.first
171
+ gs.equal_moves(gen_strat_profile).count.should == 1
172
+ gs.equal_moves(gen_strat_profile).first[:payoff].should == -1
173
+ end
174
+
175
+ # Employer: | Task Specific | Generic
176
+ # You: -----------------|---------------------|------------------
177
+ # | |
178
+ # Deny Training | (-2, -1) | (-2, -1)
179
+ # ------------------------|---------------------|------------------
180
+ # Accept Training | (1, 4) | (5, -2)
181
+ # ------------------------|---------------------|------------------
182
+ it ".all_other_moves should return a list of moves for a matchup that are equal in payoffs" do
183
+ # in the above game generic training is weakly dominated
184
+ gs = game_with_weakly_dominated_strategies
185
+ gen_strat_profiles = gs.strategy_profiles.select do |x|
186
+ x[:strategy][:name] == @generic[:name] &&
187
+ x[:payoff] == -1
188
+ end
189
+ gen_strat_profile = gen_strat_profiles.first
190
+ gs.equal_moves(gen_strat_profile).count.should == 1
191
+ gs.equal_moves(gen_strat_profile).first[:payoff].should == -1
192
+ end
193
+
194
+ # Employer: | Task Specific | Generic
195
+ # You: -----------------|---------------------|------------------
196
+ # | |
197
+ # Deny Training | (-2, -1) | (-2, -1)
198
+ # ------------------------|---------------------|------------------
199
+ # Accept Training | (1, 4) | (5, -2)
200
+ # ------------------------|---------------------|------------------
201
+ it ".weakly_dominated_list should return a list of weakly dominated strategies" do
202
+ # in the above game generic training is weakly dominated
203
+ gs = game_with_weakly_dominated_strategies
204
+ # generic should not be strictly but rather weakly dominated
205
+ gs.strictly_dominated_list.count.should == 1
206
+ gs.weakly_dominated_list.count.should == 1
207
+ gs.weakly_dominated_list.select{|x| x[:name] == @generic[:name]}.count.should > 0
208
+ end
209
+ it ".weakly_dominated_list should not return ant strictly dominated strategies" do
210
+ # in the above game generic training is weakly dominated
211
+ gs = game_with_weakly_dominated_strategies
212
+ # generic should not be strictly but rather weakly dominated
213
+ gs.strictly_dominated_list.count.should == 1
214
+ gs.weakly_dominated_list.count.should == 1
215
+ gs.weakly_dominated_list.select{|x| x[:name] == @generic[:name]}.count.should > 0
216
+ gs.weakly_dominated_list.select{|x| x[:name] == @deny[:name]}.count.should == 0
217
+ end
218
+
219
+ # Employer: | Task Specific | Generic
220
+ # You: -----------------|---------------------|------------------
221
+ # | |
222
+ # Deny Training | (-2, -1) | (-2, -1)
223
+ # ------------------------|---------------------|------------------
224
+ # Accept Training | (1, 4) | (5, -2)
225
+ # ------------------------|---------------------|------------------
226
+ it ".valid_deviation? should not be nil if the strategy and the deviation belongs to the same player" do
227
+ gs = game_with_weakly_dominated_strategies
228
+ gs.valid_deviation?(@deny, @accept).should_not be_nil
229
+ end
230
+
231
+ it ".valid_deviation? should not be nil if the strategy and the deviation belongs to the same player" do
232
+ gs = game_with_weakly_dominated_strategies
233
+ gs.valid_deviation?(@deny, @generic).should == nil
234
+ end
235
+
236
+ # Employer: | Task Specific | Generic
237
+ # You: -----------------|---------------------|------------------
238
+ # | |
239
+ # Deny Training | (-2, -1) | (-2, -1)
240
+ # ------------------------|---------------------|------------------
241
+ # Accept Training | (1, 4) | (5, -2)
242
+ # ------------------------|---------------------|------------------
243
+ it ".compare_deviating_strategy should return a list of weakly dominated strategies" do
244
+ # in the above game generic training is weakly dominated
245
+ gs = game_with_weakly_dominated_strategies
246
+ gs.compare_deviating_strategy(@deny, @accept).should == :strictly_dominated
247
+ end
248
+
249
+ it ".deviating_strategies should return a list of deviations" do
250
+ gen_strat_payoff = @gs.strategy_profiles.detect{|x| x[:strategy][:name] == @generic[:name]}
251
+ task_strat_payoff = @gs.strategy_profiles.detect{|x| x[:strategy][:name] == @task[:name]}
252
+ @gs.deviating_strategies(gen_strat_payoff).include?(gen_strat_payoff[:strategy]).should == false
253
+ @gs.deviating_strategies(gen_strat_payoff).include?(task_strat_payoff[:strategy]).should == true
254
+ end
255
+
256
+ it ".player_from_strategy should get the player for a particular strategy" do
257
+ @gs.player_from_strategy(@accept).should eq @employee
258
+ end
259
+
260
+ it ".best_response should be the action of a player that is best for him given his beliefs about the other's action" do
261
+ task_strat_payoff = @gs.strategy_profiles.detect{|x| x[:strategy][:name] == @task[:name]}
262
+ accept_strat_payoff = @gs.strategy_profiles.detect{|x| x[:strategy][:name] == @accept[:name]}
263
+ @gs.best_response_against(task_strat_payoff)[:strategy][:name].should == accept_strat_payoff[:strategy][:name]
264
+
265
+ end
266
+
267
+ it ".player_enum should get a list of player enumerators" do
268
+ @gs.player_enum.include?(@employer).should == true
269
+ end
270
+
271
+ it ".strategies_by_player should get a list of strategies by player" do
272
+ @gs.strategies_by_player(@employee).include?(@accept).should == true
273
+ end
274
+
275
+ it ".nash should return a list of strategy profiles that are nash equilibriums" do
276
+ @gs.nash.include?([@accept[:name],@task[:name]]).should == true
277
+ end
278
+
279
+
280
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Player do
4
+ it "should check for an required keys when initializing" do
5
+ players=Player.new
6
+ expect {
7
+ players << {notname: "test1", description: "test2"}
8
+ }.to raise_error(RuntimeError,/Name required/)
9
+ end
10
+
11
+ it "should allow and insert when name and description are present" do
12
+ players=Player.new
13
+ expect {
14
+ players << {name: "test1", description: "test2"}
15
+ players << {name: "test3", description: "test4"}
16
+ }.to_not raise_error
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe StrategyProfile do
4
+ #
5
+ # Employer: | Task Specific | Generic
6
+ # You: -----------------|---------------------|------------------
7
+ # | |
8
+ # Deny Training | (-2, 0) | (-2, -1)
9
+ # ------------------------|---------------------|------------------
10
+ # Accept Training | (1, 4) | (5, -2)
11
+ # ------------------------|---------------------|------------------
12
+ before (:each) do
13
+ @strategies = Strategy.new [{name: "Accept Training"}, {name: "Generic Training"},{name: "Task Specific Training"},{name: "Deny Training"}]
14
+ @accept = @strategies.find{|x| x[:name] == "Accept Training"}
15
+ @generic = @strategies.find{|x| x[:name] == "Generic Training"}
16
+ @task_specific = @strategies.find{|x| x[:name] == "Task Specific Training"}
17
+ @deny = @strategies.find{|x| x[:name] == "Deny Training"}
18
+ @employer = Player.new name: "John Smith"
19
+ @employee = Player.new name: "John Smith"
20
+ end
21
+ # hash of stategy, matchup, player, payoff
22
+ it "should collect matchups" do
23
+ @strategy_profile = StrategyProfile.new
24
+ @strategy_profile << {id: 1, strategy: @accept, payoff: -2, player: @employer}
25
+ @strategy_profile << {id: 1, strategy: @generic, payoff: 5, player: @employee}
26
+ @strategy_profile.count.should == 2
27
+
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Strategy do
4
+
5
+ it "should check for an required keys when initializing" do
6
+ strategies=Strategy.new
7
+ expect {
8
+ strategies << {notname: "test1", description: "test2"}
9
+ }.to raise_error(RuntimeError,/Name required/)
10
+ end
11
+
12
+ it "should allow and insert when name and description are present" do
13
+ strategies=Strategy.new
14
+ expect {
15
+ strategies << {name: "test1", description: "test2"}
16
+ strategies << {name: "test3", description: "test4"}
17
+ }.to_not raise_error
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ #this file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ #require File.expand_path("../../config/environment", __FILE__)
4
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/array_of_hashes.rb')
5
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/strategy.rb')
6
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/strategy_profile.rb')
7
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/player.rb')
8
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/gameable.rb')
9
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/minigame/game.rb')
10
+ require 'rspec/autorun'
11
+
12
+ # Requires supporting ruby files with custom matchers and macros, etc,
13
+ # in spec/support/ and its subdirectories.
14
+ #Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
15
+
16
+ Dir["../app/models/*.rb"].each {|f| require_relative f}
17
+ RSpec.configure do |config|
18
+ # == Mock Framework
19
+ #
20
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
21
+ #
22
+ # config.mock_with :mocha
23
+ # config.mock_with :flexmock
24
+ # config.mock_with :rr
25
+ config.mock_with :rspec
26
+
27
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
28
+ #config.fixture_path = "#{::Rails.root}/spec/fixtures"
29
+
30
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
31
+ # examples within a transaction, remove the following line or assign false
32
+ # instead of true.
33
+ # next line doesn't work with database cleaner
34
+ #config.use_transactional_fixtures = true
35
+
36
+ # If true, the base class of anonymous controllers will be inferred
37
+ # automatically. This will be the default behavior in future versions of
38
+ # rspec-rails.
39
+ #config.infer_base_class_for_anonymous_controllers = false
40
+ #config.include FactoryGirl::Syntax::Methods
41
+
42
+ #config.before(:suite) do
43
+ # DatabaseCleaner.strategy = :transaction
44
+ # DatabaseCleaner.clean_with(:truncation)
45
+ #end
46
+ #config.before(:each) do
47
+ # DatabaseCleaner.start
48
+ #end
49
+
50
+ #config.after(:each) do
51
+ # DatabaseCleaner.clean
52
+ #end
53
+
54
+ end
55
+
@@ -1,8 +1,8 @@
1
1
  require 'minigame'
2
2
  require 'minigame/player'
3
- require 'debugger'
4
3
  require 'minitest/autorun'
5
4
  require 'minitest/unit'
5
+ #require 'debugger'
6
6
 
7
7
  class MiniGameTest < Minitest::Test
8
8
  class Game
@@ -94,8 +94,8 @@ class MiniGameTest < Minitest::Test
94
94
 
95
95
  def test_weakly_dominated_list
96
96
  game = Game.new
97
- game.strategy_profiles = new_profiles
98
- assert_equal [{:name=>"Generic Training"}, {:name=>"Deny Training"}], game.weakly_dominated_list
97
+ game.strategy_profiles = new_weak_profiles
98
+ assert_equal [{:name=>"Generic Training"}], game.weakly_dominated_list
99
99
  end
100
100
 
101
101
  def test_nash
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minigame
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
- - Wavell Watson
7
+ - W Watson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-13 00:00:00.000000000 Z
11
+ date: 2013-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,15 +52,30 @@ dependencies:
52
52
  - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: A game theory library
56
70
  email:
57
- - wavell.watson@gmail.com
71
+ - me@wwatson.me
58
72
  executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - .gitignore
63
77
  - .rvmrc
78
+ - .travis.yml
64
79
  - Gemfile
65
80
  - Gemfile.lock
66
81
  - LICENSE.txt
@@ -70,14 +85,20 @@ files:
70
85
  - lib/minigame/array_of_hashes.rb
71
86
  - lib/minigame/game.rb
72
87
  - lib/minigame/gameable.rb
73
- - lib/minigame/payoff.rb
74
88
  - lib/minigame/player.rb
75
89
  - lib/minigame/strategy.rb
76
90
  - lib/minigame/strategy_profile.rb
77
91
  - lib/minigame/version.rb
78
92
  - minigame.gemspec
93
+ - spec/models/array_of_hashes_spec.rb
94
+ - spec/models/gameable_spec.rb
95
+ - spec/models/games_spec.rb
96
+ - spec/models/player_spec.rb
97
+ - spec/models/strategy_profile_spec.rb
98
+ - spec/models/strategy_spec.rb
99
+ - spec/spec_helper.rb
79
100
  - test/test_minigame.rb
80
- homepage: ''
101
+ homepage: https://github.com/wavell/minigame
81
102
  licenses:
82
103
  - MIT
83
104
  metadata: {}
@@ -102,4 +123,11 @@ signing_key:
102
123
  specification_version: 4
103
124
  summary: A minimalistic game theory library that computes nash equilibrium
104
125
  test_files:
126
+ - spec/models/array_of_hashes_spec.rb
127
+ - spec/models/gameable_spec.rb
128
+ - spec/models/games_spec.rb
129
+ - spec/models/player_spec.rb
130
+ - spec/models/strategy_profile_spec.rb
131
+ - spec/models/strategy_spec.rb
132
+ - spec/spec_helper.rb
105
133
  - test/test_minigame.rb
@@ -1,12 +0,0 @@
1
- require 'data_mapper'
2
- #class Payoff < ActiveRecord::Base
3
- # belongs_to :player
4
- # belongs_to :matchup
5
- # attr_accessible :payoff
6
- #end
7
- class Payoff
8
- include DataMapper::Resource
9
- belongs_to :player
10
- belongs_to :matchup
11
- #attr_accessible :payoff
12
- end