tic_tac_toe_nhu 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,58 +2,51 @@ require 'tic_tac_toe/spec_helper'
2
2
  require 'tic_tac_toe/player_factory'
3
3
  require 'tic_tac_toe/strategy/minimax'
4
4
  require 'tic_tac_toe/strategy/console_user'
5
+ require 'tic_tac_toe/values'
5
6
 
6
7
  describe TicTacToe::PlayerFactory do
7
-
8
8
  before(:each) do
9
9
  @factory = TicTacToe::PlayerFactory.new
10
+ @value = TicTacToe::VALUES[0]
11
+ end
12
+
13
+ it "checks player types" do
14
+ [:human, :computer] == @factory.types
10
15
  end
11
16
 
12
- context "console player" do
13
- it "returns a console player with passed in values" do
14
- name = "Billy"
15
- value = "bill"
16
- player = @factory.human(name, value)
17
- player.name.should == name
18
- player.value.should == value
17
+ context "human player" do
18
+ before(:each) do
19
+ @human = @factory.create(:human, @value)
19
20
  end
20
21
 
21
22
  it "strategy is console user" do
22
- @factory.human.strategy.should be_kind_of(TicTacToe::Strategy::ConsoleUser)
23
+ @human.strategy.should be_kind_of(TicTacToe::Strategy::ConsoleUser)
23
24
  end
24
25
 
25
- it "checks default name" do
26
- @factory.human.name.should == "User"
26
+ it "checks name" do
27
+ @human.name.should == "User"
27
28
  end
28
29
 
29
- it "checks default value" do
30
- @factory.human.value.should == "X"
30
+ it "checks value" do
31
+ @human.value.should == @value
31
32
  end
32
33
  end
33
34
 
34
35
  context "computer player" do
35
36
  before(:each) do
36
- @board = "fake board"
37
+ @computer = @factory.create(:computer, @value)
37
38
  end
38
39
 
39
- it "returns a computer player with given value" do
40
- computer_value = "Danny"
41
- opponent_value = "Bill"
42
- player = @factory.computer(@board, computer_value, opponent_value)
43
- player.value.should == computer_value
40
+ it "checks strategy" do
41
+ @computer.strategy.should be_kind_of(TicTacToe::Strategy::Minimax)
44
42
  end
45
43
 
46
- it "checks default strategy" do
47
- @factory.computer(@board).strategy.should be_kind_of(TicTacToe::Strategy::Minimax)
44
+ it "checks name" do
45
+ @computer.name.should == "Computer"
48
46
  end
49
47
 
50
- it "checks default name" do
51
- @factory.computer(@board).name.should == "Computer"
52
- end
53
-
54
- it "checks default value" do
55
- @factory.computer(@board).value.should == "O"
48
+ it "checks value" do
49
+ @computer.value.should == @value
56
50
  end
57
51
  end
58
-
59
52
  end
@@ -1,32 +1,27 @@
1
1
  require 'tic_tac_toe/spec_helper'
2
2
  require 'tic_tac_toe/player'
3
+ require 'tic_tac_toe/board'
4
+ require 'tic_tac_toe/values'
3
5
  require 'mocks/strategy/dynamic'
4
6
 
5
7
  describe TicTacToe::Player do
8
+ before(:each) do
9
+ @move = 4
10
+ @value = TicTacToe::VALUES[0]
11
+ @name = "blu"
12
+ @strategy = MockDynamicStrategy.new([@move])
13
+ @player = TicTacToe::Player.new(@name, @value, @strategy)
14
+ end
6
15
 
7
16
  it "gets name" do
8
- name = "bruce"
9
- player = TicTacToe::Player.new(name, nil, nil)
10
- player.name.should == name
17
+ @player.name.should == @name
11
18
  end
12
19
 
13
20
  it "gets player value" do
14
- value = "X"
15
- player = TicTacToe::Player.new(nil, value, nil)
16
- player.value.should == value
17
- end
18
-
19
- it "gets player's move" do
20
- move = 4
21
- strategy = MockDynamicStrategy.new([4])
22
- player = TicTacToe::Player.new(nil, nil, strategy)
23
- player.move.should == move
21
+ @player.value.should == @value
24
22
  end
25
23
 
26
24
  it "gets strategy" do
27
- strategy = MockDynamicStrategy.new([4])
28
- player = TicTacToe::Player.new(nil, nil, strategy)
29
- player.strategy.should == strategy
30
-
25
+ @player.strategy.should == @strategy
31
26
  end
32
27
  end
@@ -1,95 +1,88 @@
1
1
  require 'tic_tac_toe/spec_helper'
2
2
  require 'tic_tac_toe/runner'
3
- require 'tic_tac_toe/player'
4
- require 'tic_tac_toe/game'
5
- require 'tic_tac_toe/rules'
6
- require 'tic_tac_toe/board'
7
- require 'mocks/game'
3
+
8
4
  require 'mocks/game_factory'
5
+ require 'mocks/game'
9
6
  require 'mocks/ui/console'
10
- require 'mocks/strategy/dynamic'
11
- require 'mocks/rules'
7
+ require 'mocks/player'
12
8
 
13
9
  describe TicTacToe::Runner do
10
+ attr_reader :game, :ui, :game_state, :game_state_factory
11
+
14
12
  before(:each) do
13
+ @game_state = MockGame.factory
14
+ @game_state_factory = MockGameFactory.factory create: game_state
15
15
  @ui = MockConsole.factory
16
- @todd = TicTacToe::Player.new("Todd", "X", MockDynamicStrategy.new([1,2,3]))
17
- @game = MockGame.factory current_player: @todd, winner: @todd
18
- @game_factory = MockGameFactory.factory create: @game
19
- @controller = TicTacToe::Runner.new(@ui, @game_factory)
16
+ @game = TicTacToe::Runner.new(@ui, @game_state_factory)
20
17
  end
21
18
 
22
- describe "starts game" do
23
- it "displays welcome message" do
24
- @controller.start
25
- @ui.was told_to(:display_welcome_message)
26
- end
19
+ it "displays a welcome message" do
20
+ game.start
21
+ ui.was told_to(:display_welcome_message)
22
+ end
27
23
 
28
- it "asked ui to get game type" do
29
- @controller.start
24
+ describe "create game state" do
25
+ it "asks user for a game type" do
26
+ game.start
30
27
  @ui.was asked_for(:game_type)
31
28
  end
32
29
 
33
- it "creates a game based on user input" do
34
- @controller.start
35
- @game_factory.was told_to(:create)
30
+ it "asks game state factory to create a game with input game type" do
31
+ game_type = 4
32
+ ui.will_have_game_type 4
33
+ game.start
34
+ @game_state_factory.was told_to(:create).with(game_type)
36
35
  end
37
36
 
38
37
  it "asks ui for game type again if the input is incorrect" do
39
- @game_factory.will_create ArgumentError.new, @game
40
- @controller.start
38
+ game_state_factory.will_create ArgumentError.new, game_state
39
+ game.start
40
+ ui.was asked_for(:game_type).times(2)
41
41
  end
42
42
  end
43
43
 
44
44
  describe "play game" do
45
- before(:each) do
46
- @game.will_over? false, true
47
- end
45
+ attr_reader :player
48
46
 
49
- it "display board" do
50
- @controller.start
51
- @ui.was told_to(:display_board)
52
- end
53
-
54
- it "displays whose turn it is" do
55
- @controller.start
56
- @ui.was told_to(:display_player_turn).with(@todd)
47
+ before(:each) do
48
+ @player = MockPlayer.new
49
+ game_state.will_game_over? false, true
50
+ game_state.will_have_current_player @player
57
51
  end
58
52
 
59
- it "tells game to make a move" do
60
- @game.will_over? false, true
61
- @controller.start
62
- @game.was told_to(:make_move)
53
+ it "displays the board" do
54
+ game.start
55
+ ui.was told_to(:display_board)
63
56
  end
64
57
 
65
- it "asks for game move until game is over" do
66
- @game.will_over? false, false, false, true
67
- @controller.start
68
- @game.was told_to(:make_move).times(3)
58
+ it "tells ui to display player turn" do
59
+ game.start
60
+ ui.was told_to(:display_player_turn).with(player)
69
61
  end
70
62
 
71
- it "displays message when square is not available" do
72
- @game.will_make_move TicTacToe::MoveNotAvailableError.new
73
- @controller.start
74
- @ui.was told_to(:display_square_not_available)
63
+ it "tells player to move again if there is an error" do
64
+ game_state.will_make_player_move TicTacToe::MoveNotAvailableError.new, nil
65
+ game.start
66
+ game_state.was told_to(:make_player_move).times(2)
75
67
  end
76
68
  end
77
69
 
78
70
  describe "end game" do
79
- it "displays the board when the game is over" do
80
- @controller.start
81
- @ui.was told_to(:display_board)
71
+ it "display a board at the end of the game" do
72
+ game.start
73
+ ui.was told_to(:display_board)
82
74
  end
83
75
 
84
- it "notifies user when player wins" do
85
- @controller.start
86
- @ui.was told_to(:display_winner).with(@todd)
76
+ it "asks ui to display a winner if there is a winner" do
77
+ winner = "Winner"
78
+ game_state.will_have_winner winner
79
+ game.start
80
+ ui.was told_to(:display_winner).with(winner)
87
81
  end
88
82
 
89
- it "notifies user when it's a tied game" do
90
- @game.will_have_winner nil
91
- @controller.start
92
- @ui.was told_to(:display_tied_game)
83
+ it "asks ui to display a draw" do
84
+ game.start
85
+ ui.was told_to(:display_tied_game)
93
86
  end
94
87
  end
95
88
  end
@@ -13,7 +13,7 @@ describe TicTacToe::Strategy::ConsoleUser do
13
13
  it "prompts the user for a move" do
14
14
  @output.should_receive(:puts).with("Please enter a square number that is not marked: ")
15
15
  @input.should_receive(:gets).and_return("3")
16
- @strategy.move
16
+ @strategy.move(@board)
17
17
  end
18
18
 
19
19
  it "returns a number when user enters a number" do
@@ -1,156 +1,157 @@
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'
4
5
 
5
6
  describe TicTacToe::Strategy::Minimax, :slow_test => true do
6
7
 
7
8
  before(:each) do
8
9
  @board = TicTacToe::Board.new(3)
9
- @opponent = "X"
10
- @computer = "O"
11
- @strategy = TicTacToe::Strategy::Minimax.new(@board, @computer, @opponent)
10
+ @computer_value = TicTacToe::VALUES[1]
11
+ @opponent_value = TicTacToe::Values.opponent(@computer_value)
12
+ @strategy = TicTacToe::Strategy::Minimax.new(@computer_value)
12
13
  end
13
14
 
14
15
  context "move" do
15
16
  context "when there is only one position left" do
16
17
  it "returns move when it's a winning move" do
17
- mark((1...@board.size**2), @computer)
18
- @strategy.move.should == 0
18
+ mark((1...@board.size**2), @computer_value)
19
+ @strategy.move(@board).should == 0
19
20
  end
20
21
 
21
22
  it "returns the move when it's a tied" do
22
- mark([0, 2, 5, 6], @computer)
23
- mark([1, 3, 4, 8], @opponent)
24
- @strategy.move.should == 7
23
+ mark([0, 2, 5, 6], @computer_value)
24
+ mark([1, 3, 4, 8], @opponent_value)
25
+ @strategy.move(@board).should == 7
25
26
  end
26
27
 
27
28
  it "returns the move when opponent wins" do
28
- mark((0...@board.size**2 - 1).to_a, @opponent)
29
- @strategy.move.should == 8
29
+ mark((0...@board.size**2 - 1).to_a, @opponent_value)
30
+ @strategy.move(@board).should == 8
30
31
  end
31
32
  end
32
33
 
33
34
  context "when there are two positions left" do
34
35
  it "returns losing scores when the two moves are losing moves" do
35
- mark((2...@board.size**2).to_a, @opponent)
36
- @strategy.move.should == 0
36
+ mark((2...@board.size**2).to_a, @opponent_value)
37
+ @strategy.move(@board).should == 0
37
38
  end
38
39
 
39
40
  it "returns the first win move when the two moves are winning moves" do
40
- mark((2...@board.size**2).to_a, @computer)
41
- @strategy.move.should == 0
41
+ mark((2...@board.size**2).to_a, @computer_value)
42
+ @strategy.move(@board).should == 0
42
43
  end
43
44
 
44
45
  it "returns the first tie move when the two moves are tie moves" do
45
- mark([0, 2, 7], @computer)
46
- mark([1, 4, 6, 8], @opponent)
47
- @strategy.move.should == 3
46
+ mark([0, 2, 7], @computer_value)
47
+ mark([1, 4, 6, 8], @opponent_value)
48
+ @strategy.move(@board).should == 3
48
49
  end
49
50
 
50
51
  it "returns win move when there are winning and losing moves" do
51
- mark([0, 1, 3, 7], @computer)
52
- mark([2, 4, 5], @opponent)
53
- @strategy.move.should == 6
52
+ mark([0, 1, 3, 7], @computer_value)
53
+ mark([2, 4, 5], @opponent_value)
54
+ @strategy.move(@board).should == 6
54
55
  end
55
56
 
56
57
  it "returns winning move when there are winning and tie moves" do
57
- mark([0, 2, 3, 4], @computer)
58
- mark([1, 5, 8], @opponent)
59
- @strategy.move.should == 6
58
+ mark([0, 2, 3, 4], @computer_value)
59
+ mark([1, 5, 8], @opponent_value)
60
+ @strategy.move(@board).should == 6
60
61
  end
61
62
 
62
63
  it "returns tied move when there are losing and tie moves" do
63
- mark([2, 3, 4], @computer)
64
- mark([0, 5, 6, 7], @opponent)
65
- @strategy.move.should == 8
64
+ mark([2, 3, 4], @computer_value)
65
+ mark([0, 5, 6, 7], @opponent_value)
66
+ @strategy.move(@board).should == 8
66
67
  end
67
68
 
68
69
  context "winning move appear later in the board" do
69
70
  it "returns win move when winning move is later than losing move" do
70
- mark([1, 2, 5, 7], @computer)
71
- mark([0, 3, 4], @opponent)
72
- @strategy.move.should == 8
71
+ mark([1, 2, 5, 7], @computer_value)
72
+ mark([0, 3, 4], @opponent_value)
73
+ @strategy.move(@board).should == 8
73
74
  end
74
75
 
75
76
  it "returns winning move when winning move is later than tie move" do
76
- mark([0, 2, 4, 5], @computer)
77
- mark([1, 3, 6], @opponent)
78
- @strategy.move.should == 8
77
+ mark([0, 2, 4, 5], @computer_value)
78
+ mark([1, 3, 6], @opponent_value)
79
+ @strategy.move(@board).should == 8
79
80
  end
80
81
 
81
82
  it "returns tied move when there are losing and tie moves" do
82
- mark([2, 3, 4], @computer)
83
- mark([0, 5, 6, 7], @opponent)
84
- @strategy.move.should == 8
83
+ mark([2, 3, 4], @computer_value)
84
+ mark([0, 5, 6, 7], @opponent_value)
85
+ @strategy.move(@board).should == 8
85
86
  end
86
87
  end
87
88
  end
88
89
 
89
90
  context "when there are three moves left" do
90
91
  it "chooses the winning move when there is one available" do
91
- mark([1, 4], @computer)
92
- mark([0, 3, 2, 5], @opponent)
93
- @strategy.move.should == 7
92
+ mark([1, 4], @computer_value)
93
+ mark([0, 3, 2, 5], @opponent_value)
94
+ @strategy.move(@board).should == 7
94
95
  end
95
96
 
96
97
  it "chooses a tie move when there are only losing and tie moves" do
97
- mark([1, 4], @computer)
98
- mark([0, 2, 5, 7], @opponent)
99
- @strategy.move.should == 8
98
+ mark([1, 4], @computer_value)
99
+ mark([0, 2, 5, 7], @opponent_value)
100
+ @strategy.move(@board).should == 8
100
101
  end
101
102
  end
102
103
 
103
104
  context "when there are 4 moves left" do
104
105
  it "chooses a winning move when one is available" do
105
- mark([0, 4], @computer)
106
- mark([1, 2, 6], @opponent)
107
- @strategy.move.should == 8
106
+ mark([0, 4], @computer_value)
107
+ mark([1, 2, 6], @opponent_value)
108
+ @strategy.move(@board).should == 8
108
109
  end
109
110
 
110
111
  it "chooses a move that would create 2 winning moves" do
111
- mark([0, 6], @computer)
112
- mark([1, 3, 5], @opponent)
113
- @strategy.move.should == 4
112
+ mark([0, 6], @computer_value)
113
+ mark([1, 3, 5], @opponent_value)
114
+ @strategy.move(@board).should == 4
114
115
  end
115
116
  end
116
117
  end
117
118
 
118
119
  it "chooses the winning move when available" do
119
- mark([1, 4], @computer)
120
- mark([0], @opponent)
121
- @strategy.move.should == 7
120
+ mark([1, 4], @computer_value)
121
+ mark([0], @opponent_value)
122
+ @strategy.move(@board).should == 7
122
123
  end
123
124
 
124
125
  it "chooses the winning move when available" do
125
- mark([0, 4], @computer)
126
- mark([1, 2], @opponent)
127
- @strategy.move.should == 8
126
+ mark([0, 4], @computer_value)
127
+ mark([1, 2], @opponent_value)
128
+ @strategy.move(@board).should == 8
128
129
  end
129
130
 
130
131
  it "chooses a blocking move when there is no winning move" do
131
- mark([2], @computer)
132
- mark([0, 4], @opponent)
133
- @strategy.move.should == 8
132
+ mark([2], @computer_value)
133
+ mark([0, 4], @opponent_value)
134
+ @strategy.move(@board).should == 8
134
135
  end
135
136
 
136
137
  it "chooses a blocking move when there is no winning move" do
137
- mark([2], @computer)
138
- mark([1, 4], @opponent)
139
- @strategy.move.should == 7
138
+ mark([2], @computer_value)
139
+ mark([1, 4], @opponent_value)
140
+ @strategy.move(@board).should == 7
140
141
  end
141
142
 
142
143
  it "chooses the middle square when computer is the second player" do
143
- mark([0], @opponent)
144
- @strategy.move.should == 4
144
+ mark([0], @opponent_value)
145
+ @strategy.move(@board).should == 4
145
146
  end
146
147
 
147
148
  it "chooses the first corner of the board when the middle square is taken as a second player" do
148
- mark([4], @opponent)
149
- @strategy.move.should == 0
149
+ mark([4], @opponent_value)
150
+ @strategy.move(@board).should == 0
150
151
  end
151
152
 
152
153
  it "chooses the middle square on the first move" do
153
- @strategy.move.should == 4
154
+ @strategy.move(@board).should == 4
154
155
  end
155
156
 
156
157
  def move_node(move, score)