bashrw_ttt 0.1.0

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.
Files changed (130) hide show
  1. data/bin/play.rb +10 -0
  2. data/lib/ttt/ai.rb +33 -0
  3. data/lib/ttt/ai_easy.rb +17 -0
  4. data/lib/ttt/ai_hard.rb +21 -0
  5. data/lib/ttt/ai_medium.rb +21 -0
  6. data/lib/ttt/ai_medium_back.rb +58 -0
  7. data/lib/ttt/board.rb +37 -0
  8. data/lib/ttt/config_helper.rb +53 -0
  9. data/lib/ttt/config_options.rb +27 -0
  10. data/lib/ttt/context.rb +214 -0
  11. data/lib/ttt/four_by_four.rb +62 -0
  12. data/lib/ttt/game.rb +94 -0
  13. data/lib/ttt/game_history.rb +37 -0
  14. data/lib/ttt/game_interactor.rb +126 -0
  15. data/lib/ttt/human.rb +12 -0
  16. data/lib/ttt/interfaces/cli/lib/cli/board_selection.rb +34 -0
  17. data/lib/ttt/interfaces/cli/lib/cli/cli_game.rb +186 -0
  18. data/lib/ttt/interfaces/cli/lib/cli/cli_presenter.rb +216 -0
  19. data/lib/ttt/interfaces/cli/lib/cli/clio.rb +17 -0
  20. data/lib/ttt/interfaces/cli/lib/cli/play_again.rb +38 -0
  21. data/lib/ttt/interfaces/cli/lib/cli/player_selection.rb +43 -0
  22. data/lib/ttt/interfaces/cli/lib/cli/selection.rb +8 -0
  23. data/lib/ttt/interfaces/cli/lib/cli/walk_history.rb +48 -0
  24. data/lib/ttt/interfaces/cli/spec/cli/board_selection_spec.rb +29 -0
  25. data/lib/ttt/interfaces/cli/spec/cli/cli_game_spec.rb +376 -0
  26. data/lib/ttt/interfaces/cli/spec/cli/cli_presenter_spec.rb +147 -0
  27. data/lib/ttt/interfaces/cli/spec/cli/play_again_spec.rb +39 -0
  28. data/lib/ttt/interfaces/cli/spec/cli/player_selection_spec.rb +62 -0
  29. data/lib/ttt/interfaces/cli/spec/cli/walk_history_spec.rb +115 -0
  30. data/lib/ttt/interfaces/cli/spec/spec_helper.rb +14 -0
  31. data/lib/ttt/interfaces/limelight/four_by_four/props.rb +1 -0
  32. data/lib/ttt/interfaces/limelight/four_by_four/styles.rb +74 -0
  33. data/lib/ttt/interfaces/limelight/four_by_four_finished/props.rb +1 -0
  34. data/lib/ttt/interfaces/limelight/four_by_four_finished/styles.rb +74 -0
  35. data/lib/ttt/interfaces/limelight/game_list/players/load_button.rb +10 -0
  36. data/lib/ttt/interfaces/limelight/game_list/props.rb +17 -0
  37. data/lib/ttt/interfaces/limelight/game_list/styles.rb +8 -0
  38. data/lib/ttt/interfaces/limelight/main_menu/players/exit_ttt.rb +3 -0
  39. data/lib/ttt/interfaces/limelight/main_menu/players/load_game.rb +3 -0
  40. data/lib/ttt/interfaces/limelight/main_menu/players/new_game.rb +3 -0
  41. data/lib/ttt/interfaces/limelight/main_menu/props.rb +17 -0
  42. data/lib/ttt/interfaces/limelight/new_game/players/board_type.rb +1 -0
  43. data/lib/ttt/interfaces/limelight/new_game/players/new_game.rb +5 -0
  44. data/lib/ttt/interfaces/limelight/new_game/players/player_type.rb +1 -0
  45. data/lib/ttt/interfaces/limelight/new_game/players/setup_button.rb +21 -0
  46. data/lib/ttt/interfaces/limelight/new_game/props.rb +21 -0
  47. data/lib/ttt/interfaces/limelight/new_game/styles.rb +23 -0
  48. data/lib/ttt/interfaces/limelight/partials/board_partial.rb +14 -0
  49. data/lib/ttt/interfaces/limelight/partials/menu_button_partial.rb +5 -0
  50. data/lib/ttt/interfaces/limelight/partials/move_history_partial.rb +6 -0
  51. data/lib/ttt/interfaces/limelight/partials/title_history_partial.rb +10 -0
  52. data/lib/ttt/interfaces/limelight/players/board.rb +3 -0
  53. data/lib/ttt/interfaces/limelight/players/game.rb +4 -0
  54. data/lib/ttt/interfaces/limelight/players/generic_move_history.rb +5 -0
  55. data/lib/ttt/interfaces/limelight/players/generic_player.rb +8 -0
  56. data/lib/ttt/interfaces/limelight/players/left_button.rb +3 -0
  57. data/lib/ttt/interfaces/limelight/players/main_menu.rb +3 -0
  58. data/lib/ttt/interfaces/limelight/players/right_button.rb +3 -0
  59. data/lib/ttt/interfaces/limelight/playscripts/game_playscript.rb +169 -0
  60. data/lib/ttt/interfaces/limelight/production.rb +14 -0
  61. data/lib/ttt/interfaces/limelight/spec/game_playscript_spec.rb +218 -0
  62. data/lib/ttt/interfaces/limelight/spec/main_menu/main_menu_spec.rb +38 -0
  63. data/lib/ttt/interfaces/limelight/spec/new_game/new_game_spec.rb +45 -0
  64. data/lib/ttt/interfaces/limelight/spec/spec_helper.rb +8 -0
  65. data/lib/ttt/interfaces/limelight/stages.rb +6 -0
  66. data/lib/ttt/interfaces/limelight/styles.rb +119 -0
  67. data/lib/ttt/interfaces/limelight/three_by_three/props.rb +1 -0
  68. data/lib/ttt/interfaces/limelight/three_by_three/styles.rb +39 -0
  69. data/lib/ttt/interfaces/limelight/three_by_three_by_three/props.rb +1 -0
  70. data/lib/ttt/interfaces/limelight/three_by_three_by_three/styles.rb +119 -0
  71. data/lib/ttt/interfaces/limelight/three_by_three_by_three_finished/props.rb +1 -0
  72. data/lib/ttt/interfaces/limelight/three_by_three_by_three_finished/styles.rb +119 -0
  73. data/lib/ttt/interfaces/limelight/three_by_three_finished/props.rb +1 -0
  74. data/lib/ttt/interfaces/limelight/three_by_three_finished/styles.rb +39 -0
  75. data/lib/ttt/interfaces/rails/app/controllers/application_controller.rb +3 -0
  76. data/lib/ttt/interfaces/rails/app/controllers/ttt_games_controller.rb +86 -0
  77. data/lib/ttt/interfaces/rails/app/helpers/application_helper.rb +2 -0
  78. data/lib/ttt/interfaces/rails/app/models/ttt_game.rb +34 -0
  79. data/lib/ttt/interfaces/rails/app/presenters/web_game_presenter.rb +159 -0
  80. data/lib/ttt/interfaces/rails/autotest/discover.rb +1 -0
  81. data/lib/ttt/interfaces/rails/config/application.rb +67 -0
  82. data/lib/ttt/interfaces/rails/config/boot.rb +6 -0
  83. data/lib/ttt/interfaces/rails/config/environment.rb +5 -0
  84. data/lib/ttt/interfaces/rails/config/environments/development.rb +37 -0
  85. data/lib/ttt/interfaces/rails/config/environments/production.rb +67 -0
  86. data/lib/ttt/interfaces/rails/config/environments/test.rb +37 -0
  87. data/lib/ttt/interfaces/rails/config/initializers/backtrace_silencers.rb +7 -0
  88. data/lib/ttt/interfaces/rails/config/initializers/inflections.rb +15 -0
  89. data/lib/ttt/interfaces/rails/config/initializers/mime_types.rb +5 -0
  90. data/lib/ttt/interfaces/rails/config/initializers/secret_token.rb +7 -0
  91. data/lib/ttt/interfaces/rails/config/initializers/session_store.rb +8 -0
  92. data/lib/ttt/interfaces/rails/config/initializers/wrap_parameters.rb +14 -0
  93. data/lib/ttt/interfaces/rails/config/routes.rb +49 -0
  94. data/lib/ttt/interfaces/rails/db/schema.rb +28 -0
  95. data/lib/ttt/interfaces/rails/db/seeds.rb +7 -0
  96. data/lib/ttt/interfaces/rails/spec/controllers/ttt_games_controller_spec.rb +211 -0
  97. data/lib/ttt/interfaces/rails/spec/models/ttt_game_spec.rb +76 -0
  98. data/lib/ttt/interfaces/rails/spec/presenters/web_game_presenter_spec.rb +52 -0
  99. data/lib/ttt/interfaces/rails/spec/spec_helper.rb +13 -0
  100. data/lib/ttt/interfaces/web_interface/html_generator.rb +76 -0
  101. data/lib/ttt/interfaces/web_interface/web_game_presenter.rb +0 -0
  102. data/lib/ttt/minimax.rb +46 -0
  103. data/lib/ttt/move_history.rb +10 -0
  104. data/lib/ttt/move_traverser.rb +49 -0
  105. data/lib/ttt/player.rb +15 -0
  106. data/lib/ttt/riak_db.rb +53 -0
  107. data/lib/ttt/setup.rb +59 -0
  108. data/lib/ttt/three_by_three.rb +35 -0
  109. data/lib/ttt/three_by_three_by_three.rb +37 -0
  110. data/spec/spec_helper.rb +22 -0
  111. data/spec/ttt/ai_easy_spec.rb +15 -0
  112. data/spec/ttt/ai_hard_spec.rb +76 -0
  113. data/spec/ttt/ai_medium_spec.rb +65 -0
  114. data/spec/ttt/ai_spec.rb +50 -0
  115. data/spec/ttt/board_spec.rb +96 -0
  116. data/spec/ttt/config_helper_spec.rb +54 -0
  117. data/spec/ttt/context_spec.rb +398 -0
  118. data/spec/ttt/four_by_four_spec.rb +112 -0
  119. data/spec/ttt/game_history_spec.rb +41 -0
  120. data/spec/ttt/game_interactor_spec.rb +197 -0
  121. data/spec/ttt/game_spec.rb +246 -0
  122. data/spec/ttt/human_spec.rb +18 -0
  123. data/spec/ttt/move_history_spec.rb +13 -0
  124. data/spec/ttt/move_traverser_spec.rb +75 -0
  125. data/spec/ttt/player_spec.rb +13 -0
  126. data/spec/ttt/riak_db_spec.rb +64 -0
  127. data/spec/ttt/setup_spec.rb +63 -0
  128. data/spec/ttt/three_by_three_by_three_spec.rb +130 -0
  129. data/spec/ttt/three_by_three_spec.rb +110 -0
  130. metadata +238 -0
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module TTT
4
+ describe AI do
5
+
6
+ let(:ai) { AI.new(side: "x") }
7
+ let(:board) { ThreeByThree.new }
8
+
9
+ describe "#move" do
10
+ it "responds to message(:move)" do
11
+ ai.should respond_to(:move)
12
+ end
13
+ end
14
+
15
+ describe "#available_moves" do
16
+ it "returns an array of available moves" do
17
+ ai.board = board
18
+ ai.available_moves.should == [0,1,2,3,4,5,6,7,8]
19
+ end
20
+
21
+ it "returns [] when no available moves are found" do
22
+ board[] = ["o", "x", "o", "x", "o", "x", "o", "x", "o"]
23
+ ai.board = board
24
+ ai.available_moves.should == []
25
+ end
26
+ end
27
+
28
+ describe "#undo_move" do
29
+ it "should revert the original game board back to its previous state" do
30
+ index = 3
31
+ ai.board = board
32
+ ai.board[][3] = "x"
33
+ ai.undo_move(index)
34
+ ai.board[][3].should == " "
35
+ end
36
+ end
37
+
38
+ describe "#no_gui?" do
39
+ it "returns true" do
40
+ ai.no_gui?.should == true
41
+ end
42
+ end
43
+
44
+ describe "#prompt" do
45
+ it "returns 'Computer thinking'" do
46
+ ai.prompt.should == "Computer thinking."
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module TTT
4
+ describe Board do
5
+ let(:board) { ThreeByThree.new }
6
+
7
+ describe "#initialize" do
8
+ it "board has length 9" do
9
+ board[].length.should == 9
10
+ end
11
+ end
12
+
13
+ describe "#update" do
14
+ it "updates the game board after move is received" do
15
+ board.update(1, "x")
16
+ board[].should == [" ", "x", " ", " ", " ", " ", " ", " ", " "]
17
+ end
18
+ end
19
+
20
+ describe "#empty?" do
21
+ it "returns true when board is empty" do
22
+ board.empty?.should == true
23
+ end
24
+
25
+ it "returns false when board is not empty" do
26
+ board.update(1, "x")
27
+ board.empty?.should == false
28
+ end
29
+ end
30
+
31
+ describe "#full?" do
32
+ it "returns true when board is full" do
33
+ 9.times do |n|
34
+ board.update(n, "o")
35
+ end
36
+ board.full?.should == true
37
+ end
38
+
39
+ it "returns false when board isn't full" do
40
+ board.update(1, "x")
41
+ board.full?.should == false
42
+ end
43
+ end
44
+
45
+ describe "#free?" do
46
+ it "returns false when board is occupied at a given cell" do
47
+ board.update(1, "x")
48
+ board.free?(1).should == false
49
+ end
50
+
51
+ it "returns true when board is not occupied at a given cell" do
52
+ board.free?(0).should == true
53
+ end
54
+ end
55
+
56
+ describe "#draw_game?" do
57
+ it "returns false when board is not full" do
58
+ board.draw_game?.should == false
59
+ end
60
+
61
+ it "returns true when board is full" do
62
+ board[] = ["x", "o", "x", "x", "o", "o", "o", "x", "o"]
63
+ board.draw_game?.should == true
64
+ end
65
+ end
66
+
67
+ describe "#winner?" do
68
+ it "returns false when the board has no winner" do
69
+ board.winner?.should == false
70
+ end
71
+
72
+ it "returns true when the board has a winner" do
73
+ board[] = ["x", "x", "x", "o", " ", "o", " ", " ", " "]
74
+ board.winner?.should == true
75
+ end
76
+ end
77
+
78
+ describe "#finished?" do
79
+ it "returns false when board is not full, no win, or no draw" do
80
+ board.finished?.should == false
81
+ end
82
+
83
+ it "returns true when board has a win" do
84
+ board.update(0, 'x')
85
+ board.update(1, 'x')
86
+ board.update(2, 'x')
87
+ board.finished?.should == true
88
+ end
89
+
90
+ it "returns true when board has a draw" do
91
+ board[] = ["x", "o", "x", "x", "o", "o", "o", "x", "o"]
92
+ board.finished?.should == true
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'ttt/config_options'
3
+
4
+ module TTT
5
+ describe ConfigHelper do
6
+ describe "#self.player_types" do
7
+ it { described_class.player_types.should == ConfigOptions::HUMAN_READABLE_PLAYERS }
8
+ end
9
+
10
+ describe "#self.board_types" do
11
+ it { described_class.board_types.should == ConfigOptions::HUMAN_READABLE_BOARDS }
12
+ end
13
+
14
+ describe "#self.bucket" do
15
+ it { described_class.bucket.should == ConfigOptions::BUCKET }
16
+ end
17
+
18
+ describe "#self.port" do
19
+ it { described_class.port.should == ConfigOptions::PORT }
20
+ end
21
+
22
+ describe "#self.http_backend" do
23
+ it { described_class.http_backend.should == ConfigOptions::HTTP_BACKEND }
24
+ end
25
+
26
+ describe "#self.get_player_const" do
27
+ it { described_class.get_player_const("Human").should == Human }
28
+ end
29
+
30
+ describe "#self.get_board_const" do
31
+ it { described_class.get_board_const("3x3").should == ThreeByThree }
32
+ end
33
+
34
+ describe "#self.get_player_index" do
35
+ it { described_class.get_player_index("Human").should == ConfigOptions::HUMAN_READABLE_PLAYERS.index("Human") }
36
+ end
37
+
38
+ describe "#self.get_board_index" do
39
+ it { described_class.get_board_index("3x3").should == ConfigOptions::HUMAN_READABLE_BOARDS.index("3x3") }
40
+ end
41
+
42
+ describe "#self.get_db_const" do
43
+ it { described_class.get_db_const.should == ConfigOptions::DB }
44
+ end
45
+
46
+ describe "#self.get_history_const" do
47
+ it { described_class.get_history_const.should == ConfigOptions::HISTORY }
48
+ end
49
+
50
+ describe "#self.get_game_interactor_const" do
51
+ it { described_class.get_game_interactor_const.should == ConfigOptions::INTERACTOR }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,398 @@
1
+ require 'spec_helper'
2
+ require 'ttt/config_options'
3
+
4
+ module TTT
5
+ describe Context do
6
+ let(:context) { Context.instance }
7
+ let(:setup) { Setup.new }
8
+ let(:players) { setup.players }
9
+ let(:boards) { setup.boards }
10
+ let(:game) { setup.new_game(player1: players.first, player2: players.first, board: boards.first) }
11
+
12
+ before(:each) do
13
+ context.setup=(Setup)
14
+ end
15
+
16
+ describe "players" do
17
+ it "returns the list of player types supported by the library" do
18
+ context.players.should == ConfigOptions::HUMAN_READABLE_PLAYERS
19
+ end
20
+ end
21
+
22
+ describe "boards" do
23
+ it "returns the list of board types supported by the library" do
24
+ context.boards.should == ConfigOptions::HUMAN_READABLE_BOARDS
25
+ end
26
+ end
27
+
28
+ describe "setup" do
29
+ it "returns a reference to a TTT::Setup object" do
30
+ context.setup.class.should == TTT::Setup
31
+ end
32
+ end
33
+
34
+ describe "add_game" do
35
+ it "adds a game to the db and returns the id" do
36
+ id = context.add_game(game)
37
+ id.should_not == nil
38
+ end
39
+ end
40
+
41
+ describe "create_game" do
42
+ it "create a new game and adds it to the db, returning the id" do
43
+ id = context.create_game(players.first, players.first, boards.first)
44
+ context.get_game(id).should_not == nil
45
+ end
46
+ end
47
+
48
+ describe "get_game" do
49
+ it "gets a game from the db and returns the game" do
50
+ game.player1.side = "get_game_test"
51
+ id = context.add_game(game)
52
+ retrieved_game = context.get_game(id)
53
+ retrieved_game.player1.side.should == game.player1.side
54
+ end
55
+ end
56
+
57
+ describe "#delete_game" do
58
+ it "removes a game from the db" do
59
+ id = context.add_game(game)
60
+ context.delete_game(id)
61
+ context.get_game(id).should == nil
62
+ end
63
+ end
64
+
65
+ describe "#save_game" do
66
+ it "saves a game to the db" do
67
+ id = context.add_game(game)
68
+ added_game = context.get_game(id)
69
+ added_game.board[] = %w(a b c d e f g h i)
70
+ context.save_game(id, added_game)
71
+ saved_game = context.get_game(id)
72
+ added_game.board[].should == saved_game.board[]
73
+ end
74
+ end
75
+
76
+ describe "#update_game" do
77
+ before(:each) do
78
+ id = context.add_game(game)
79
+ context.update_game(id, 0, 'x')
80
+ @updated_game = context.get_game(id)
81
+ end
82
+
83
+ it "updates a game in the db" do
84
+ @updated_game.board[][0].should == "x"
85
+ end
86
+
87
+ it "records move history" do
88
+ @updated_game.history.history.length.should == 1
89
+ end
90
+
91
+ it "switches the player" do
92
+ @updated_game.current_player.eql? @updated_game.player2
93
+ end
94
+
95
+ it "returns nil if no game is associated with the id" do
96
+ context.update_game(10000000000, 0, 'x').should == nil
97
+ end
98
+ end
99
+
100
+ describe "#game_list" do
101
+ it "returns an array of game ids (Strings)" do
102
+ context.game_list.should_not == []
103
+ end
104
+
105
+ it "gets a list of all game id's from the db" do
106
+ id = context.add_game(game)
107
+ context.game_list.include? id
108
+ end
109
+ end
110
+
111
+ describe "#ai_move?" do
112
+ it "returns true if the next move is from an AI player" do
113
+ game.player1 = TTT::AIEasy.new(:side => "x")
114
+ game.current_player = game.player1
115
+ id = context.add_game(game)
116
+ context.ai_move?(id).should == true
117
+ end
118
+
119
+ it "returns false if the next move is not from an AI player" do
120
+ id = context.add_game(game)
121
+ context.ai_move?(id).should == false
122
+ end
123
+
124
+ it "returns nil if the game cannot be found" do
125
+ context.ai_move?(100000000000000).should == nil
126
+ end
127
+ end
128
+
129
+ describe "#ai_move" do
130
+ before(:each) do
131
+ game.player1 = AIEasy.new(:side => 'x')
132
+ game.current_player = game.player1
133
+ id = context.add_game(game)
134
+ context.ai_move(id)
135
+ @updated_game = context.get_game(id)
136
+ end
137
+
138
+ it "gets an updated game with the board containing the ai move" do
139
+ @updated_game.board.empty?.should_not == true
140
+ end
141
+
142
+ it "advances current player to the next player" do
143
+ @updated_game.current_player.eql? game.player2
144
+ end
145
+
146
+ it "records the game history for the ai move" do
147
+ @updated_game.history.history.length.should == 1
148
+ end
149
+ end
150
+
151
+ describe "#finished?" do
152
+ it "returns true if the game is over" do
153
+ game.board[] = %w(a b c d e f g h i)
154
+ id = context.add_game(game)
155
+ context.finished?(id).should == true
156
+ end
157
+
158
+ it "returns false if the game is not over" do
159
+ game.board[] = Array.new(9, " ")
160
+ id = context.add_game(game)
161
+ context.finished?(id).should == false
162
+ end
163
+
164
+ it "returns nil if the game is not found" do
165
+ context.finished?(100000000).should == nil
166
+ end
167
+ end
168
+
169
+ describe "#winner?" do
170
+ it "returns true if a winner is found" do
171
+ game.board[] = %w(x x x x x x x x x)
172
+ id = context.add_game(game)
173
+ context.winner?(id).should == true
174
+ end
175
+
176
+ it "returns false if a winner is not found" do
177
+ game.board[] = Array.new(9, " ")
178
+ id = context.add_game(game)
179
+ context.winner?(id).should == false
180
+ end
181
+
182
+ it "returns nil if no game exists for the provided id" do
183
+ context.winner?(100000000).should == nil
184
+ end
185
+ end
186
+
187
+ describe "#winner" do
188
+ it "returns the winner as a string: 'Player 1' or 'Player 2'" do
189
+ game.board[] = %w(x x x x x x x x x)
190
+ game.switch_player
191
+ id = context.add_game(game)
192
+ context.winner(id).should == "Player 1"
193
+ end
194
+
195
+ it "returns nil if no game exists for the provided id" do
196
+ context.winner?(10000000000000).should == nil
197
+ end
198
+ end
199
+
200
+ describe "#draw?" do
201
+ it "returns true if the game is a draw" do
202
+ game.board[] = %w(a b c d e f g h i)
203
+ id = context.add_game(game)
204
+ context.draw?(id).should == true
205
+ end
206
+
207
+ it "returns false if the game is not a draw" do
208
+ game.board[] = Array.new(9, " ")
209
+ id = context.add_game(game)
210
+ context.draw?(id).should == false
211
+ end
212
+
213
+ it "returns false if the game has a winner" do
214
+ game.board[] = %w(x x x x x x x x x)
215
+ id = context.add_game(game)
216
+ context.draw?(id).should == false
217
+ end
218
+
219
+ it "returns nil if there is no game for that id" do
220
+ context.draw?(1000000000).should == nil
221
+ end
222
+ end
223
+
224
+ describe "#which_board" do
225
+ it "returns `three_by_three` when the board type is 3x3" do
226
+ id = context.add_game(game)
227
+ context.which_board(id).should == "three_by_three"
228
+ end
229
+
230
+ it "returns `four_by_four` when the board type is 4x4" do
231
+ game.board = FourByFour.new
232
+ id = context.add_game(game)
233
+ context.which_board(id).should == "four_by_four"
234
+ end
235
+
236
+ it "returns `three_by_three_by_three` when the board type is 3x3x3" do
237
+ game.board = ThreeByThreeByThree.new
238
+ id = context.add_game(game)
239
+ context.which_board(id).should == "three_by_three_by_three"
240
+ end
241
+
242
+ it "returns nil if there is no game associated with the id" do
243
+ context.which_board(10000000000).should == nil
244
+ end
245
+ end
246
+
247
+ describe "#valid_move?" do
248
+ it "returns true if the move input by the user is a valid move for the current game board" do
249
+ id = context.add_game(game)
250
+ move = 0
251
+ context.valid_move?(id, move).should == true
252
+ end
253
+
254
+ it "returns false if the move input by the user is not a valid move for the current game board" do
255
+ game.board[] = %w(x x x x x x x x x)
256
+ id = context.add_game(game)
257
+ move = 0
258
+ context.valid_move?(id, move).should == false
259
+ end
260
+
261
+ it "returns nil if there is no game associated with the id" do
262
+ context.valid_move?(100000000000000, 0).should == nil
263
+ end
264
+ end
265
+
266
+ describe "#show_history" do
267
+ it "returns an array of move_history objects for the current game" do
268
+ id = context.add_game(game)
269
+ context.update_game(id, 0, 'x')
270
+ context.update_game(id, 1, 'o')
271
+ context.get_history(id).length.should == 2
272
+ end
273
+
274
+ it "returns an empty array when no move has occurred" do
275
+ id = context.add_game(game)
276
+ context.get_history(id).should == []
277
+ end
278
+
279
+ it "returns nil if the game associated with the id doesn't exist" do
280
+ context.get_history(100000000000).should == nil
281
+ end
282
+ end
283
+
284
+ describe "#which_current_player?" do
285
+ it "returns a string of the current player" do
286
+ id = context.add_game(game)
287
+ context.which_current_player?(id).should == "Player 1"
288
+ end
289
+
290
+ it "returns nil if the game associated with the id doesn't exist" do
291
+ context.which_current_player?(100000000000000).should == nil
292
+ end
293
+ end
294
+
295
+ describe "#board_arr" do
296
+ it "returns the board array" do
297
+ id = context.add_game(game)
298
+ context.board(id).should == Array.new(9, " ")
299
+ end
300
+
301
+ it "returns nil if the game associated with an id doesn't exist" do
302
+ context.board(10000000000).should == nil
303
+ end
304
+ end
305
+
306
+ describe "#adjust_move_index" do
307
+ before(:each) do
308
+ game.record_move(1, 'x')
309
+ game.record_move(2, 'o')
310
+ game.record_move(3, 'x')
311
+ game.record_move(4, 'o')
312
+ @id = context.add_game(game)
313
+ end
314
+
315
+ it "adjusts a game's move traverser move index by -1 when it receives -1" do
316
+ cur_move_index = game.history.move_traverser.move_index
317
+ cur_move_index.should == 4
318
+ context.adjust_move_index(@id, -1)
319
+ updated_game = context.get_game(@id)
320
+ updated_game.history.move_traverser.move_index.should == 3
321
+ end
322
+
323
+ it "cannot move to a move index less than 0" do
324
+ context.adjust_move_index(@id, -4)
325
+ updated_game = context.get_game(@id)
326
+ updated_game.history.move_traverser.move_index.should == 0
327
+ context.adjust_move_index(@id, -3)
328
+ updated_game = context.get_game(@id)
329
+ updated_game.history.move_traverser.move_index.should == 0
330
+ end
331
+
332
+ it "cannot move to a move index greater than the max length of a game's move history" do
333
+ context.adjust_move_index(@id, 100)
334
+ updated_game = context.get_game(@id)
335
+ updated_game.history.move_traverser.move_index.should == 4
336
+ end
337
+
338
+ it "adjusts a game's move traverser move index by 1 when it receives 1" do
339
+ context.adjust_move_index(@id, -2)
340
+ updated_game = context.get_game(@id)
341
+ updated_game.history.move_traverser.move_index.should == 2
342
+ context.adjust_move_index(@id, 1)
343
+ updated_game = context.get_game(@id)
344
+ updated_game.history.move_traverser.move_index.should == 3
345
+ end
346
+ end
347
+
348
+ describe "#get_history_board" do
349
+ it "returns the game's board as an array" do
350
+ id = context.add_game(game)
351
+ context.get_history_board(id).should == Array.new(9, " ")
352
+ end
353
+ end
354
+
355
+ describe "#initialize_history" do
356
+ before(:each) do
357
+ game.record_move(0, 'o')
358
+ game.record_move(1, 'x')
359
+ game.record_move(2, 'x')
360
+ game.record_move(3, 'x')
361
+ game.record_move(4, 'o')
362
+ game.record_move(5, 'o')
363
+ game.record_move(6, 'x')
364
+ game.record_move(7, 'o')
365
+ game.record_move(8, 'x')
366
+ @id = context.add_game(game)
367
+ end
368
+
369
+ it "returns the game's move history index to it the length of the number of moves made in the game" do
370
+ stored_game = context.get_game(@id)
371
+ stored_game.history.move_traverser.move_index.should == 9
372
+ context.adjust_move_index(@id, -9)
373
+ stored_game = context.get_game(@id)
374
+ stored_game.history.move_traverser.move_index.should == 0
375
+ context.initialize_history(@id)
376
+ stored_game = context.get_game(@id)
377
+ stored_game.history.move_traverser.move_index.should == 9
378
+ end
379
+ end
380
+
381
+ describe "#get_move_index" do
382
+ before(:each) do
383
+ end
384
+
385
+ it "returns the current move index" do
386
+ id = context.add_game(game)
387
+ cur_game = context.get_game(id)
388
+ cur_game.record_move(1, 'x')
389
+ context.save_game(id, cur_game)
390
+ context.get_move_index(id).should == 1
391
+ cur_game = context.get_game(id)
392
+ cur_game.record_move(2, 'o')
393
+ context.save_game(id, cur_game)
394
+ context.get_move_index(id).should == 2
395
+ end
396
+ end
397
+ end
398
+ end