tic_tac_toe_nhu 0.0.5 → 0.0.11
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 +4 -4
- data/bin/tic_tac_toe +3 -3
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +135 -51
- data/lib/tic_tac_toe/board.rb +1 -1
- data/lib/tic_tac_toe/game.rb +23 -44
- data/lib/tic_tac_toe/game_factory.rb +51 -0
- data/lib/tic_tac_toe/player.rb +2 -2
- data/lib/tic_tac_toe/player_factory.rb +3 -3
- data/lib/tic_tac_toe/rules.rb +1 -1
- data/lib/tic_tac_toe/runner.rb +53 -0
- data/lib/tic_tac_toe/strategy/console_user.rb +1 -1
- data/lib/tic_tac_toe/strategy/minimax.rb +16 -18
- data/lib/tic_tac_toe/ui/console.rb +3 -3
- data/spec/integration/tictactoe/unbeatable_computer_spec.rb +3 -3
- data/spec/mocks/game.rb +1 -1
- data/spec/mocks/game_factory.rb +14 -0
- data/spec/mocks/player_factory.rb +2 -3
- data/spec/mocks/strategy/dynamic.rb +1 -1
- data/spec/tic_tac_toe/game_factory_spec.rb +78 -0
- data/spec/tic_tac_toe/game_spec.rb +78 -64
- data/spec/tic_tac_toe/player_factory_mock.rb +10 -0
- data/spec/tic_tac_toe/player_factory_spec.rb +9 -5
- data/spec/tic_tac_toe/player_spec.rb +16 -17
- data/spec/tic_tac_toe/runner_spec.rb +95 -0
- data/spec/tic_tac_toe/strategy/console_user_spec.rb +1 -1
- data/spec/tic_tac_toe/strategy/minimax_spec.rb +64 -65
- data/spec/tic_tac_toe/ui/console_spec.rb +1 -1
- data/tic_tac_toe_nhu.gemspec +1 -2
- metadata +8 -12
- data/lib/tic_tac_toe/game_state.rb +0 -35
- data/lib/tic_tac_toe/game_state_factory.rb +0 -56
- data/lib/tic_tac_toe/values.rb +0 -10
- data/spec/mocks/game_state.rb +0 -18
- data/spec/mocks/game_state_factory.rb +0 -14
- data/spec/mocks/player.rb +0 -16
- data/spec/tic_tac_toe/game_state_factory_spec.rb +0 -63
- data/spec/tic_tac_toe/game_state_spec.rb +0 -73
- data/spec/tic_tac_toe/values_spec.rb +0 -17
@@ -1,157 +1,156 @@
|
|
1
1
|
require 'tic_tac_toe/spec_helper'
|
2
2
|
require 'tic_tac_toe/board'
|
3
3
|
require 'tic_tac_toe/strategy/minimax'
|
4
|
-
require 'tic_tac_toe/values'
|
5
4
|
|
6
5
|
describe TicTacToe::Strategy::Minimax, :slow_test => true do
|
7
6
|
|
8
7
|
before(:each) do
|
9
8
|
@board = TicTacToe::Board.new(3)
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@strategy = TicTacToe::Strategy::Minimax.new(@
|
9
|
+
@opponent = "X"
|
10
|
+
@computer = "O"
|
11
|
+
@strategy = TicTacToe::Strategy::Minimax.new(@board, @computer, @opponent)
|
13
12
|
end
|
14
13
|
|
15
14
|
context "move" do
|
16
15
|
context "when there is only one position left" do
|
17
16
|
it "returns move when it's a winning move" do
|
18
|
-
mark((1...@board.size**2), @
|
19
|
-
@strategy.move
|
17
|
+
mark((1...@board.size**2), @computer)
|
18
|
+
@strategy.move.should == 0
|
20
19
|
end
|
21
20
|
|
22
21
|
it "returns the move when it's a tied" do
|
23
|
-
mark([0, 2, 5, 6], @
|
24
|
-
mark([1, 3, 4, 8], @
|
25
|
-
@strategy.move
|
22
|
+
mark([0, 2, 5, 6], @computer)
|
23
|
+
mark([1, 3, 4, 8], @opponent)
|
24
|
+
@strategy.move.should == 7
|
26
25
|
end
|
27
26
|
|
28
27
|
it "returns the move when opponent wins" do
|
29
|
-
mark((0...@board.size**2 - 1).to_a, @
|
30
|
-
@strategy.move
|
28
|
+
mark((0...@board.size**2 - 1).to_a, @opponent)
|
29
|
+
@strategy.move.should == 8
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
33
|
context "when there are two positions left" do
|
35
34
|
it "returns losing scores when the two moves are losing moves" do
|
36
|
-
mark((2...@board.size**2).to_a, @
|
37
|
-
@strategy.move
|
35
|
+
mark((2...@board.size**2).to_a, @opponent)
|
36
|
+
@strategy.move.should == 0
|
38
37
|
end
|
39
38
|
|
40
39
|
it "returns the first win move when the two moves are winning moves" do
|
41
|
-
mark((2...@board.size**2).to_a, @
|
42
|
-
@strategy.move
|
40
|
+
mark((2...@board.size**2).to_a, @computer)
|
41
|
+
@strategy.move.should == 0
|
43
42
|
end
|
44
43
|
|
45
44
|
it "returns the first tie move when the two moves are tie moves" do
|
46
|
-
mark([0, 2, 7], @
|
47
|
-
mark([1, 4, 6, 8], @
|
48
|
-
@strategy.move
|
45
|
+
mark([0, 2, 7], @computer)
|
46
|
+
mark([1, 4, 6, 8], @opponent)
|
47
|
+
@strategy.move.should == 3
|
49
48
|
end
|
50
49
|
|
51
50
|
it "returns win move when there are winning and losing moves" do
|
52
|
-
mark([0, 1, 3, 7], @
|
53
|
-
mark([2, 4, 5], @
|
54
|
-
@strategy.move
|
51
|
+
mark([0, 1, 3, 7], @computer)
|
52
|
+
mark([2, 4, 5], @opponent)
|
53
|
+
@strategy.move.should == 6
|
55
54
|
end
|
56
55
|
|
57
56
|
it "returns winning move when there are winning and tie moves" do
|
58
|
-
mark([0, 2, 3, 4], @
|
59
|
-
mark([1, 5, 8], @
|
60
|
-
@strategy.move
|
57
|
+
mark([0, 2, 3, 4], @computer)
|
58
|
+
mark([1, 5, 8], @opponent)
|
59
|
+
@strategy.move.should == 6
|
61
60
|
end
|
62
61
|
|
63
62
|
it "returns tied move when there are losing and tie moves" do
|
64
|
-
mark([2, 3, 4], @
|
65
|
-
mark([0, 5, 6, 7], @
|
66
|
-
@strategy.move
|
63
|
+
mark([2, 3, 4], @computer)
|
64
|
+
mark([0, 5, 6, 7], @opponent)
|
65
|
+
@strategy.move.should == 8
|
67
66
|
end
|
68
67
|
|
69
68
|
context "winning move appear later in the board" do
|
70
69
|
it "returns win move when winning move is later than losing move" do
|
71
|
-
mark([1, 2, 5, 7], @
|
72
|
-
mark([0, 3, 4], @
|
73
|
-
@strategy.move
|
70
|
+
mark([1, 2, 5, 7], @computer)
|
71
|
+
mark([0, 3, 4], @opponent)
|
72
|
+
@strategy.move.should == 8
|
74
73
|
end
|
75
74
|
|
76
75
|
it "returns winning move when winning move is later than tie move" do
|
77
|
-
mark([0, 2, 4, 5], @
|
78
|
-
mark([1, 3, 6], @
|
79
|
-
@strategy.move
|
76
|
+
mark([0, 2, 4, 5], @computer)
|
77
|
+
mark([1, 3, 6], @opponent)
|
78
|
+
@strategy.move.should == 8
|
80
79
|
end
|
81
80
|
|
82
81
|
it "returns tied move when there are losing and tie moves" do
|
83
|
-
mark([2, 3, 4], @
|
84
|
-
mark([0, 5, 6, 7], @
|
85
|
-
@strategy.move
|
82
|
+
mark([2, 3, 4], @computer)
|
83
|
+
mark([0, 5, 6, 7], @opponent)
|
84
|
+
@strategy.move.should == 8
|
86
85
|
end
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
90
89
|
context "when there are three moves left" do
|
91
90
|
it "chooses the winning move when there is one available" do
|
92
|
-
mark([1, 4], @
|
93
|
-
mark([0, 3, 2, 5], @
|
94
|
-
@strategy.move
|
91
|
+
mark([1, 4], @computer)
|
92
|
+
mark([0, 3, 2, 5], @opponent)
|
93
|
+
@strategy.move.should == 7
|
95
94
|
end
|
96
95
|
|
97
96
|
it "chooses a tie move when there are only losing and tie moves" do
|
98
|
-
mark([1, 4], @
|
99
|
-
mark([0, 2, 5, 7], @
|
100
|
-
@strategy.move
|
97
|
+
mark([1, 4], @computer)
|
98
|
+
mark([0, 2, 5, 7], @opponent)
|
99
|
+
@strategy.move.should == 8
|
101
100
|
end
|
102
101
|
end
|
103
102
|
|
104
103
|
context "when there are 4 moves left" do
|
105
104
|
it "chooses a winning move when one is available" do
|
106
|
-
mark([0, 4], @
|
107
|
-
mark([1, 2, 6], @
|
108
|
-
@strategy.move
|
105
|
+
mark([0, 4], @computer)
|
106
|
+
mark([1, 2, 6], @opponent)
|
107
|
+
@strategy.move.should == 8
|
109
108
|
end
|
110
109
|
|
111
110
|
it "chooses a move that would create 2 winning moves" do
|
112
|
-
mark([0, 6], @
|
113
|
-
mark([1, 3, 5], @
|
114
|
-
@strategy.move
|
111
|
+
mark([0, 6], @computer)
|
112
|
+
mark([1, 3, 5], @opponent)
|
113
|
+
@strategy.move.should == 4
|
115
114
|
end
|
116
115
|
end
|
117
116
|
end
|
118
117
|
|
119
118
|
it "chooses the winning move when available" do
|
120
|
-
mark([1, 4], @
|
121
|
-
mark([0], @
|
122
|
-
@strategy.move
|
119
|
+
mark([1, 4], @computer)
|
120
|
+
mark([0], @opponent)
|
121
|
+
@strategy.move.should == 7
|
123
122
|
end
|
124
123
|
|
125
124
|
it "chooses the winning move when available" do
|
126
|
-
mark([0, 4], @
|
127
|
-
mark([1, 2], @
|
128
|
-
@strategy.move
|
125
|
+
mark([0, 4], @computer)
|
126
|
+
mark([1, 2], @opponent)
|
127
|
+
@strategy.move.should == 8
|
129
128
|
end
|
130
129
|
|
131
130
|
it "chooses a blocking move when there is no winning move" do
|
132
|
-
mark([2], @
|
133
|
-
mark([0, 4], @
|
134
|
-
@strategy.move
|
131
|
+
mark([2], @computer)
|
132
|
+
mark([0, 4], @opponent)
|
133
|
+
@strategy.move.should == 8
|
135
134
|
end
|
136
135
|
|
137
136
|
it "chooses a blocking move when there is no winning move" do
|
138
|
-
mark([2], @
|
139
|
-
mark([1, 4], @
|
140
|
-
@strategy.move
|
137
|
+
mark([2], @computer)
|
138
|
+
mark([1, 4], @opponent)
|
139
|
+
@strategy.move.should == 7
|
141
140
|
end
|
142
141
|
|
143
142
|
it "chooses the middle square when computer is the second player" do
|
144
|
-
mark([0], @
|
145
|
-
@strategy.move
|
143
|
+
mark([0], @opponent)
|
144
|
+
@strategy.move.should == 4
|
146
145
|
end
|
147
146
|
|
148
147
|
it "chooses the first corner of the board when the middle square is taken as a second player" do
|
149
|
-
mark([4], @
|
150
|
-
@strategy.move
|
148
|
+
mark([4], @opponent)
|
149
|
+
@strategy.move.should == 0
|
151
150
|
end
|
152
151
|
|
153
152
|
it "chooses the middle square on the first move" do
|
154
|
-
@strategy.move
|
153
|
+
@strategy.move.should == 4
|
155
154
|
end
|
156
155
|
|
157
156
|
def move_node(move, score)
|
@@ -79,7 +79,7 @@ describe TicTacToe::Console do
|
|
79
79
|
it "displays winner" do
|
80
80
|
player = TicTacToe::Player.new("Todd", "X", nil)
|
81
81
|
@console.display_winner(player)
|
82
|
-
@output.string.should == "Todd(X)
|
82
|
+
@output.string.should == "Todd(X) win!\n"
|
83
83
|
end
|
84
84
|
|
85
85
|
it "display tied game" do
|
data/tic_tac_toe_nhu.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'tic_tac_toe_nhu'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.11'
|
4
4
|
s.date = '2013-06-11'
|
5
5
|
s.summary = "Tic Tac Toe"
|
6
6
|
s.description = "A simple tic tac toe game with AI"
|
@@ -8,5 +8,4 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.email = 'nhu313@gmail.com'
|
9
9
|
s.files = `git ls-files`.split("\n")
|
10
10
|
s.homepage = 'http://rubygems.org/gems/tic_tac_toe_nhu'
|
11
|
-
s.executables << 'tic_tac_toe'
|
12
11
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tic_tac_toe_nhu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nhu Nguyen
|
@@ -12,8 +12,7 @@ date: 2013-06-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
13
13
|
description: A simple tic tac toe game with AI
|
14
14
|
email: nhu313@gmail.com
|
15
|
-
executables:
|
16
|
-
- tic_tac_toe
|
15
|
+
executables: []
|
17
16
|
extensions: []
|
18
17
|
extra_rdoc_files: []
|
19
18
|
files:
|
@@ -32,36 +31,33 @@ files:
|
|
32
31
|
- features/tictactoe_submit_move.feature
|
33
32
|
- lib/tic_tac_toe/board.rb
|
34
33
|
- lib/tic_tac_toe/game.rb
|
35
|
-
- lib/tic_tac_toe/
|
36
|
-
- lib/tic_tac_toe/game_state_factory.rb
|
34
|
+
- lib/tic_tac_toe/game_factory.rb
|
37
35
|
- lib/tic_tac_toe/player.rb
|
38
36
|
- lib/tic_tac_toe/player_factory.rb
|
39
37
|
- lib/tic_tac_toe/rules.rb
|
38
|
+
- lib/tic_tac_toe/runner.rb
|
40
39
|
- lib/tic_tac_toe/strategy/console_user.rb
|
41
40
|
- lib/tic_tac_toe/strategy/minimax.rb
|
42
41
|
- lib/tic_tac_toe/ui/console.rb
|
43
|
-
- lib/tic_tac_toe/values.rb
|
44
42
|
- spec/integration/tictactoe/unbeatable_computer_spec.rb
|
45
43
|
- spec/mocks/game.rb
|
46
|
-
- spec/mocks/
|
47
|
-
- spec/mocks/game_state_factory.rb
|
48
|
-
- spec/mocks/player.rb
|
44
|
+
- spec/mocks/game_factory.rb
|
49
45
|
- spec/mocks/player_factory.rb
|
50
46
|
- spec/mocks/rules.rb
|
51
47
|
- spec/mocks/strategy/dynamic.rb
|
52
48
|
- spec/mocks/ui/console.rb
|
53
49
|
- spec/tic_tac_toe/board_spec.rb
|
50
|
+
- spec/tic_tac_toe/game_factory_spec.rb
|
54
51
|
- spec/tic_tac_toe/game_spec.rb
|
55
|
-
- spec/tic_tac_toe/
|
56
|
-
- spec/tic_tac_toe/game_state_spec.rb
|
52
|
+
- spec/tic_tac_toe/player_factory_mock.rb
|
57
53
|
- spec/tic_tac_toe/player_factory_spec.rb
|
58
54
|
- spec/tic_tac_toe/player_spec.rb
|
59
55
|
- spec/tic_tac_toe/rules_spec.rb
|
56
|
+
- spec/tic_tac_toe/runner_spec.rb
|
60
57
|
- spec/tic_tac_toe/spec_helper.rb
|
61
58
|
- spec/tic_tac_toe/strategy/console_user_spec.rb
|
62
59
|
- spec/tic_tac_toe/strategy/minimax_spec.rb
|
63
60
|
- spec/tic_tac_toe/ui/console_spec.rb
|
64
|
-
- spec/tic_tac_toe/values_spec.rb
|
65
61
|
- tic_tac_toe_nhu.gemspec
|
66
62
|
homepage: http://rubygems.org/gems/tic_tac_toe_nhu
|
67
63
|
licenses: []
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'tic_tac_toe/board'
|
2
|
-
require 'tic_tac_toe/rules'
|
3
|
-
|
4
|
-
module TicTacToe
|
5
|
-
class GameState
|
6
|
-
attr_reader :board, :current_player
|
7
|
-
|
8
|
-
def initialize(players, board = TicTacToe::Board.new)
|
9
|
-
@board = board
|
10
|
-
@players = players
|
11
|
-
@current_player = players[0]
|
12
|
-
end
|
13
|
-
|
14
|
-
def change_player
|
15
|
-
@current_player = (@players[0] == @current_player)? @players[1] : @players[0]
|
16
|
-
end
|
17
|
-
|
18
|
-
def game_over?
|
19
|
-
rules.game_over?
|
20
|
-
end
|
21
|
-
|
22
|
-
def winner
|
23
|
-
player(rules.winner)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
def rules
|
28
|
-
TicTacToe::Rules.new(board)
|
29
|
-
end
|
30
|
-
|
31
|
-
def player(value)
|
32
|
-
@players.detect {|p| p.value == value}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'tic_tac_toe/game_state'
|
2
|
-
require 'tic_tac_toe/board'
|
3
|
-
require 'tic_tac_toe/player_factory'
|
4
|
-
require 'tic_tac_toe/values'
|
5
|
-
|
6
|
-
module TicTacToe
|
7
|
-
class GameStateFactory
|
8
|
-
def initialize(player_factory = TicTacToe::PlayerFactory.new)
|
9
|
-
@player_factory = player_factory
|
10
|
-
end
|
11
|
-
|
12
|
-
def types
|
13
|
-
[[:human, :computer], [:computer, :human], [:human, :human], [:computer, :computer]]
|
14
|
-
end
|
15
|
-
|
16
|
-
def create(game_type)
|
17
|
-
case game_type
|
18
|
-
when 1
|
19
|
-
human_computer_game
|
20
|
-
when 2
|
21
|
-
computer_human_game
|
22
|
-
when 3
|
23
|
-
human_human_game
|
24
|
-
when 4
|
25
|
-
computer_computer_game
|
26
|
-
else
|
27
|
-
raise ArgumentError, "Type #{game_type} does not exist. Please select a number corresponding to the game type."
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
def computer_human_game
|
33
|
-
create_game(@player_factory.computer, @player_factory.human)
|
34
|
-
end
|
35
|
-
|
36
|
-
def human_computer_game
|
37
|
-
create_game(@player_factory.human, @player_factory.computer)
|
38
|
-
end
|
39
|
-
|
40
|
-
def human_human_game
|
41
|
-
player1 = @player_factory.human
|
42
|
-
player2 = @player_factory.human("Friend", TicTacToe::Values.opponent(player1.value))
|
43
|
-
create_game(player1, player2)
|
44
|
-
end
|
45
|
-
|
46
|
-
def computer_computer_game
|
47
|
-
computer1 = @player_factory.computer(TicTacToe::VALUES[0])
|
48
|
-
computer2 = @player_factory.computer(TicTacToe::Values.opponent(computer1.value))
|
49
|
-
create_game(computer1, computer2)
|
50
|
-
end
|
51
|
-
|
52
|
-
def create_game(player1, player2)
|
53
|
-
TicTacToe::GameState.new([player1, player2])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/lib/tic_tac_toe/values.rb
DELETED
data/spec/mocks/game_state.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'surrogate/rspec'
|
2
|
-
require 'tic_tac_toe/game_state'
|
3
|
-
|
4
|
-
class MockGameState
|
5
|
-
Surrogate.endow(self)
|
6
|
-
define_reader :board
|
7
|
-
define_reader :current_player
|
8
|
-
|
9
|
-
define :winner
|
10
|
-
define :change_player
|
11
|
-
define(:game_over?){true}
|
12
|
-
end
|
13
|
-
|
14
|
-
describe TicTacToe::GameState do
|
15
|
-
it "checks MockGameState" do
|
16
|
-
MockGameState.should be_substitutable_for(TicTacToe::GameState)
|
17
|
-
end
|
18
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'surrogate/rspec'
|
2
|
-
|
3
|
-
class MockGameStateFactory
|
4
|
-
Surrogate.endow(self)
|
5
|
-
define(:initialize) {|player_factory|}
|
6
|
-
define :types
|
7
|
-
define(:create) {|type|}
|
8
|
-
end
|
9
|
-
|
10
|
-
describe TicTacToe::GameStateFactory do
|
11
|
-
it "checks game factory" do
|
12
|
-
MockGameStateFactory.should be_substitutable_for(TicTacToe::GameStateFactory)
|
13
|
-
end
|
14
|
-
end
|
data/spec/mocks/player.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'surrogate/rspec'
|
2
|
-
|
3
|
-
class MockPlayer
|
4
|
-
Surrogate.endow(self)
|
5
|
-
define(:initialize) {|name = "Player", value = "X", strategy = "no"|}
|
6
|
-
define_reader :name
|
7
|
-
define_reader :value
|
8
|
-
define_reader :strategy
|
9
|
-
define(:move) {|board|}
|
10
|
-
end
|
11
|
-
|
12
|
-
describe TicTacToe::Player do
|
13
|
-
it "checks if mock is substitutable" do
|
14
|
-
MockPlayer.should be_substitutable_for(TicTacToe::Player)
|
15
|
-
end
|
16
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'tic_tac_toe/spec_helper'
|
2
|
-
require 'tic_tac_toe/game_state_factory'
|
3
|
-
require 'tic_tac_toe/player_factory'
|
4
|
-
require 'mocks/player_factory'
|
5
|
-
require 'tic_tac_toe/player'
|
6
|
-
|
7
|
-
describe TicTacToe::GameStateFactory do
|
8
|
-
before(:each) do
|
9
|
-
@player_factory = MockPlayerFactory.new
|
10
|
-
@game_factory = TicTacToe::GameStateFactory.new(@player_factory)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns 4 types of games" do
|
14
|
-
@game_factory.types.size.should == 4
|
15
|
-
end
|
16
|
-
|
17
|
-
context "creates game state" do
|
18
|
-
before(:each) do
|
19
|
-
@human = TicTacToe::Player.new("Human", TicTacToe::VALUES[0], nil)
|
20
|
-
@computer = TicTacToe::Player.new("Computer", opponent_value(@human.value), nil)
|
21
|
-
|
22
|
-
@player_factory.will_have_human @human
|
23
|
-
@player_factory.will_have_computer @computer
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_game_state_creation(game_type, players)
|
27
|
-
game = @game_factory.create(game_type)
|
28
|
-
game.current_player.should == players[0]
|
29
|
-
game.change_player
|
30
|
-
game.current_player.should == players[1]
|
31
|
-
end
|
32
|
-
|
33
|
-
it "returns human vs computer game state" do
|
34
|
-
test_game_state_creation(1, [@human, @computer])
|
35
|
-
end
|
36
|
-
|
37
|
-
it "returns computer vs human game" do
|
38
|
-
test_game_state_creation(2, [@computer, @human])
|
39
|
-
end
|
40
|
-
|
41
|
-
it "returns user vs user game" do
|
42
|
-
@human2 = TicTacToe::Player.new("Human 2", opponent_value(@human.value), nil)
|
43
|
-
@player_factory.will_have_human @human, @human2
|
44
|
-
|
45
|
-
test_game_state_creation(3, [@human, @human2])
|
46
|
-
end
|
47
|
-
|
48
|
-
it "returns computer vs computer game" do
|
49
|
-
@computer2 = TicTacToe::Player.new("Computer 2", opponent_value(@computer.value), nil)
|
50
|
-
@player_factory.will_have_computer @computer, @computer2
|
51
|
-
|
52
|
-
test_game_state_creation(4, [@computer, @computer2])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it "raises an error when the game type doesn't exist" do
|
57
|
-
lambda{@game_factory.create(10)}.should raise_error(ArgumentError)
|
58
|
-
end
|
59
|
-
|
60
|
-
def opponent_value(value)
|
61
|
-
TicTacToe::Values.opponent(value)
|
62
|
-
end
|
63
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'tic_tac_toe/spec_helper'
|
2
|
-
require 'tic_tac_toe/board'
|
3
|
-
require 'tic_tac_toe/game_state'
|
4
|
-
require 'tic_tac_toe/player'
|
5
|
-
require 'tic_tac_toe/values'
|
6
|
-
|
7
|
-
describe TicTacToe::GameState do
|
8
|
-
attr_reader :game_state, :player1, :player2, :board
|
9
|
-
|
10
|
-
before(:each) do
|
11
|
-
@board = TicTacToe::Board.new
|
12
|
-
@player1 = TicTacToe::Player.new("player1", TicTacToe::VALUES[0], nil)
|
13
|
-
@player2 = TicTacToe::Player.new("player1", TicTacToe::VALUES[1], nil)
|
14
|
-
@game_state = TicTacToe::GameState.new([@player1, @player2], @board)
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
it "can read board" do
|
19
|
-
game_state.board.should == board
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "current player" do
|
23
|
-
it "starts with player 1 as the current player" do
|
24
|
-
game_state.current_player.should == player1
|
25
|
-
end
|
26
|
-
|
27
|
-
it "changes current player to player 2" do
|
28
|
-
game_state.current_player.should == player1
|
29
|
-
game_state.change_player
|
30
|
-
game_state.current_player.should == player2
|
31
|
-
end
|
32
|
-
|
33
|
-
it "changes current player to player 1 after two calls on change player" do
|
34
|
-
game_state.current_player.should == player1
|
35
|
-
game_state.change_player
|
36
|
-
game_state.change_player
|
37
|
-
game_state.current_player.should == player1
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "game over" do
|
42
|
-
it "is false when there is no mark" do
|
43
|
-
game_state.should_not be_game_over
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be over when there is a winner" do
|
47
|
-
mark_winning_board(player1.value)
|
48
|
-
game_state.should be_game_over
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "winner" do
|
53
|
-
it "has no winner when there is no mark" do
|
54
|
-
game_state.winner.should be_nil
|
55
|
-
end
|
56
|
-
|
57
|
-
it "is player 1" do
|
58
|
-
mark_winning_board(player1.value)
|
59
|
-
game_state.winner.should == player1
|
60
|
-
end
|
61
|
-
|
62
|
-
it "is player 2" do
|
63
|
-
mark_winning_board(player2.value)
|
64
|
-
game_state.winner.should == player2
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def mark_winning_board(value)
|
69
|
-
[0, 4, 8].each do |move|
|
70
|
-
game_state.board.mark(move, value)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'tic_tac_toe/values'
|
2
|
-
|
3
|
-
describe "Values" do
|
4
|
-
VALUES = ["X", "O"]
|
5
|
-
|
6
|
-
it "has X and O values" do
|
7
|
-
TicTacToe::VALUES.should == VALUES
|
8
|
-
end
|
9
|
-
|
10
|
-
it "gets opponent for X" do
|
11
|
-
TicTacToe::Values.opponent(VALUES[0]).should == VALUES[1]
|
12
|
-
end
|
13
|
-
|
14
|
-
it "gets opponent for O" do
|
15
|
-
TicTacToe::Values.opponent(VALUES[1]).should == VALUES[0]
|
16
|
-
end
|
17
|
-
end
|