tic_tac_toes 0.0.7 → 0.0.8
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/Gemfile.lock +1 -1
- data/Rakefile +2 -2
- data/bin/tic_tac_toes +18 -22
- data/lib/tic_tac_toes/command_line/menu.rb +55 -0
- data/lib/tic_tac_toes/command_line/prompt.rb +29 -0
- data/lib/tic_tac_toes/command_line/runner.rb +38 -0
- data/lib/tic_tac_toes/core/board.rb +64 -0
- data/lib/tic_tac_toes/core/board_factory.rb +11 -0
- data/lib/tic_tac_toes/core/game_state.rb +40 -0
- data/lib/tic_tac_toes/core/game_state_factory.rb +15 -0
- data/lib/tic_tac_toes/core/history.rb +29 -0
- data/lib/tic_tac_toes/core/io.rb +93 -0
- data/lib/tic_tac_toes/core/move_strategies/easy_ai.rb +13 -0
- data/lib/tic_tac_toes/core/move_strategies/hard_ai.rb +89 -0
- data/lib/tic_tac_toes/core/move_strategies/human.rb +20 -0
- data/lib/tic_tac_toes/core/move_strategies/medium_ai.rb +15 -0
- data/lib/tic_tac_toes/core/player.rb +22 -0
- data/lib/tic_tac_toes/core/player_factory.rb +30 -0
- data/lib/tic_tac_toes/core/rules.rb +66 -0
- data/lib/tic_tac_toes/core/strings.rb +106 -0
- data/lib/tic_tac_toes/database/pg_wrapper.rb +74 -0
- data/lib/tic_tac_toes/ui/adapter.rb +96 -0
- data/lib/tic_tac_toes/ui/serializer.rb +0 -0
- data/lib/tic_tac_toes/version.rb +1 -1
- data/spec/{command_line → tic_tac_toes/command_line}/menu_spec.rb +14 -14
- data/spec/{command_line → tic_tac_toes/command_line}/runner_spec.rb +7 -10
- data/spec/tic_tac_toes/{board_factory_spec.rb → core/board_factory_spec.rb} +3 -3
- data/spec/tic_tac_toes/{board_spec.rb → core/board_spec.rb} +23 -23
- data/spec/tic_tac_toes/{game_state_factory_spec.rb → core/game_state_factory_spec.rb} +3 -3
- data/spec/tic_tac_toes/core/game_state_spec.rb +129 -0
- data/spec/tic_tac_toes/{history_spec.rb → core/history_spec.rb} +3 -3
- data/spec/tic_tac_toes/{io_spec.rb → core/io_spec.rb} +7 -7
- data/spec/tic_tac_toes/core/move_strategies/easy_ai_spec.rb +19 -0
- data/spec/tic_tac_toes/core/move_strategies/hard_ai_spec.rb +121 -0
- data/spec/tic_tac_toes/{move_strategies → core/move_strategies}/human_spec.rb +3 -3
- data/spec/tic_tac_toes/core/move_strategies/medium_ai_spec.rb +21 -0
- data/spec/tic_tac_toes/{player_factory_spec.rb → core/player_factory_spec.rb} +7 -7
- data/spec/tic_tac_toes/{player_spec.rb → core/player_spec.rb} +5 -5
- data/spec/tic_tac_toes/{rules_spec.rb → core/rules_spec.rb} +34 -34
- data/spec/tic_tac_toes/{strings_spec.rb → core/strings_spec.rb} +8 -8
- data/spec/{database → tic_tac_toes/database}/pg_wrapper_spec.rb +3 -3
- data/spec/tic_tac_toes/test_board_generator.rb +17 -0
- data/spec/{ui → tic_tac_toes/ui}/adapter_spec.rb +13 -13
- data/spec/tic_tac_toes/ui/serializer_spec.rb +0 -0
- metadata +64 -61
- data/lib/command_line/menu.rb +0 -53
- data/lib/command_line/prompt.rb +0 -27
- data/lib/command_line/runner.rb +0 -37
- data/lib/database/pg_wrapper.rb +0 -72
- data/lib/tic_tac_toes/board.rb +0 -62
- data/lib/tic_tac_toes/board_factory.rb +0 -9
- data/lib/tic_tac_toes/game_state.rb +0 -27
- data/lib/tic_tac_toes/game_state_factory.rb +0 -14
- data/lib/tic_tac_toes/history.rb +0 -27
- data/lib/tic_tac_toes/io.rb +0 -91
- data/lib/tic_tac_toes/move_strategies/easy_ai.rb +0 -11
- data/lib/tic_tac_toes/move_strategies/hard_ai.rb +0 -87
- data/lib/tic_tac_toes/move_strategies/human.rb +0 -18
- data/lib/tic_tac_toes/move_strategies/medium_ai.rb +0 -13
- data/lib/tic_tac_toes/player.rb +0 -20
- data/lib/tic_tac_toes/player_factory.rb +0 -28
- data/lib/tic_tac_toes/rules.rb +0 -64
- data/lib/tic_tac_toes/strings.rb +0 -104
- data/lib/ui/adapter.rb +0 -94
- data/spec/test_board_generator.rb +0 -15
- data/spec/tic_tac_toes/game_state_spec.rb +0 -66
- data/spec/tic_tac_toes/move_strategies/easy_ai_spec.rb +0 -19
- data/spec/tic_tac_toes/move_strategies/hard_ai_spec.rb +0 -121
- data/spec/tic_tac_toes/move_strategies/medium_ai_spec.rb +0 -21
- /data/lib/{tasks → tic_tac_toes/tasks}/destroy_databases.rake +0 -0
- /data/lib/{tasks → tic_tac_toes/tasks}/set_up_databases.rake +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'tic_tac_toes/history'
|
1
|
+
require 'tic_tac_toes/core/history'
|
2
2
|
|
3
|
-
describe TicTacToes::History do
|
3
|
+
describe TicTacToes::Core::History do
|
4
4
|
let(:database_wrapper) { double("database wrapper", :record_game_history => true) }
|
5
|
-
let(:history) { TicTacToes::History.new(database_wrapper) }
|
5
|
+
let(:history) { TicTacToes::Core::History.new(database_wrapper) }
|
6
6
|
|
7
7
|
describe '#record_board_size' do
|
8
8
|
it "records the passed board size" do
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'tic_tac_toes/board'
|
2
|
-
require 'tic_tac_toes/io'
|
3
|
-
require 'tic_tac_toes/strings'
|
1
|
+
require 'tic_tac_toes/core/board'
|
2
|
+
require 'tic_tac_toes/core/io'
|
3
|
+
require 'tic_tac_toes/core/strings'
|
4
4
|
|
5
|
-
describe TicTacToes::IO do
|
6
|
-
let(:strings) { TicTacToes::Strings }
|
5
|
+
describe TicTacToes::Core::IO do
|
6
|
+
let(:strings) { TicTacToes::Core::Strings }
|
7
7
|
let(:prompt) { double("prompt", solicit_input: 0, display: true, display_red: true) }
|
8
|
-
let(:io) { TicTacToes::IO.new(prompt) }
|
8
|
+
let(:io) { TicTacToes::Core::IO.new(prompt) }
|
9
9
|
|
10
10
|
describe '#get_row_size' do
|
11
11
|
it "displays a row size solicitation" do
|
@@ -70,7 +70,7 @@ describe TicTacToes::IO do
|
|
70
70
|
|
71
71
|
describe '#draw_board' do
|
72
72
|
it "displays a board string" do
|
73
|
-
board = TicTacToes::Board.new
|
73
|
+
board = TicTacToes::Core::Board.new
|
74
74
|
board_string = strings.board(board)
|
75
75
|
|
76
76
|
expect(prompt).to receive(:display).with(board_string)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'tic_tac_toes/test_board_generator'
|
2
|
+
require 'tic_tac_toes/core/move_strategies/easy_ai'
|
3
|
+
|
4
|
+
describe TicTacToes::Core::MoveStrategies::EasyAI do
|
5
|
+
describe '#move' do
|
6
|
+
let(:players) { double("players") }
|
7
|
+
let(:easy_ai) { TicTacToes::Core::MoveStrategies::EasyAI }
|
8
|
+
|
9
|
+
it "returns a randomly-selected valid move" do
|
10
|
+
board = TicTacToes::TestBoardGenerator.generate([ :O, nil, nil,
|
11
|
+
nil, :X, nil,
|
12
|
+
nil, :X, nil])
|
13
|
+
valid_moves = [1, 2, 3, 5, 6, 8]
|
14
|
+
|
15
|
+
move = easy_ai.move(board, players)
|
16
|
+
expect(valid_moves).to include(move)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'tic_tac_toes/test_board_generator'
|
2
|
+
require 'tic_tac_toes/core/move_strategies/hard_ai'
|
3
|
+
require 'tic_tac_toes/core/player'
|
4
|
+
|
5
|
+
describe TicTacToes::Core::MoveStrategies::HardAI do
|
6
|
+
let(:hard_ai) { TicTacToes::Core::MoveStrategies::HardAI }
|
7
|
+
let(:x) { TicTacToes::Core::Player.new("human", "x", false, "io") }
|
8
|
+
let(:o) { TicTacToes::Core::Player.new(hard_ai, "o", true, "io") }
|
9
|
+
let(:players) { [o, x] }
|
10
|
+
|
11
|
+
|
12
|
+
describe '#move' do
|
13
|
+
it "returns the best move" do
|
14
|
+
board = TicTacToes::TestBoardGenerator.generate([x, nil, nil,
|
15
|
+
o, o, nil,
|
16
|
+
x, nil, x])
|
17
|
+
best_move = 5
|
18
|
+
|
19
|
+
expect(hard_ai.move(board, players)).to eql(best_move)
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when playing on a 3x3 board" do
|
23
|
+
it "returns 4 when the opponent’s first move was a corner" do
|
24
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
|
25
|
+
nil, nil, nil,
|
26
|
+
nil, nil, x])
|
27
|
+
|
28
|
+
expect(hard_ai.move(board, players)).to eq(4)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns 4 when the opponent’s first move was an edge" do
|
32
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
|
33
|
+
nil, nil, x,
|
34
|
+
nil, nil, nil])
|
35
|
+
|
36
|
+
expect(hard_ai.move(board, players)).to eq(4)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns 0 when the opponent’s first move was the center" do
|
40
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
|
41
|
+
nil, x, nil,
|
42
|
+
nil, nil, nil])
|
43
|
+
|
44
|
+
expect(hard_ai.move(board, players)).to eq(0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
describe '#minimax' do
|
51
|
+
it "returns the correct score for a pre-win board" do
|
52
|
+
board = TicTacToes::TestBoardGenerator.generate([x, nil, nil,
|
53
|
+
o, o, nil,
|
54
|
+
x, nil, x])
|
55
|
+
win_score = 1
|
56
|
+
|
57
|
+
expect(hard_ai.minimax(board, :max, players)).to eql(win_score)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns the correct score for a pre-loss board" do
|
61
|
+
board = TicTacToes::TestBoardGenerator.generate([ o, o, x,
|
62
|
+
nil, nil, nil,
|
63
|
+
x, nil, x])
|
64
|
+
loss_score = -1
|
65
|
+
|
66
|
+
expect(hard_ai.minimax(board, :max, players)).to eql(loss_score)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns the correct score for a pre-draw board" do
|
70
|
+
board = TicTacToes::TestBoardGenerator.generate([x, x, o,
|
71
|
+
o, nil, x,
|
72
|
+
x, o, x])
|
73
|
+
draw_score = 0
|
74
|
+
|
75
|
+
expect(hard_ai.minimax(board, :max, players)).to eql(draw_score)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
describe '#generate_board' do
|
81
|
+
it "returns a board based on a token, a space, and an existing board" do
|
82
|
+
token, space = o, 3
|
83
|
+
board = TicTacToes::TestBoardGenerator.generate([ x, nil, nil,
|
84
|
+
nil, o, nil,
|
85
|
+
x, nil, nil])
|
86
|
+
|
87
|
+
new_board = hard_ai.generate_board(token, space, board)
|
88
|
+
expect(new_board.space(space)).to eql(token)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
describe '#score' do
|
94
|
+
it "returns the correct score when HardAI has won" do
|
95
|
+
board = TicTacToes::TestBoardGenerator.generate([ o, nil, nil,
|
96
|
+
nil, o, nil,
|
97
|
+
nil, nil, o])
|
98
|
+
win_score = 1
|
99
|
+
|
100
|
+
expect(hard_ai.score(board, players)).to eql(win_score)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "returns the correct score when no one has won" do
|
104
|
+
board = TicTacToes::TestBoardGenerator.generate([o, o, x,
|
105
|
+
x, x, o,
|
106
|
+
o, x, o])
|
107
|
+
draw_score = 0
|
108
|
+
|
109
|
+
expect(hard_ai.score(board, players)).to eql(draw_score)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns the correct score when the opponent has won" do
|
113
|
+
board = TicTacToes::TestBoardGenerator.generate([ x, nil, nil,
|
114
|
+
nil, x, nil,
|
115
|
+
nil, nil, x])
|
116
|
+
loss_score = -1
|
117
|
+
|
118
|
+
expect(hard_ai.score(board, players)).to eql(loss_score)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'tic_tac_toes/move_strategies/human'
|
1
|
+
require 'tic_tac_toes/core/move_strategies/human'
|
2
2
|
|
3
|
-
describe TicTacToes::MoveStrategies::Human do
|
3
|
+
describe TicTacToes::Core::MoveStrategies::Human do
|
4
4
|
describe '#move' do
|
5
5
|
let(:io) { double("io", solicit_input: 0, move_solicitation: true, not_an_integer_error: true) }
|
6
|
-
let(:human) { TicTacToes::MoveStrategies::Human.new(io) }
|
6
|
+
let(:human) { TicTacToes::Core::MoveStrategies::Human.new(io) }
|
7
7
|
|
8
8
|
it "displays a move solicitation" do
|
9
9
|
expect(io).to receive(:move_solicitation)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'tic_tac_toes/test_board_generator'
|
2
|
+
require 'tic_tac_toes/core/move_strategies/medium_ai'
|
3
|
+
|
4
|
+
describe TicTacToes::Core::MoveStrategies::MediumAI do
|
5
|
+
let(:medium_ai) { TicTacToes::Core::MoveStrategies::MediumAI }
|
6
|
+
let(:x) { TicTacToes::Core::Player.new("human", "x", false, "io") }
|
7
|
+
let(:o) { TicTacToes::Core::Player.new(medium_ai, "o", true, "io") }
|
8
|
+
let(:players) { [x, o] }
|
9
|
+
|
10
|
+
describe '#move' do
|
11
|
+
it "returns a valid move (based on either EasyAI or HardAI)" do
|
12
|
+
board = TicTacToes::TestBoardGenerator.generate([ o, o, x,
|
13
|
+
nil, x, nil,
|
14
|
+
nil, x, nil])
|
15
|
+
valid_moves = [3, 5, 6, 8]
|
16
|
+
|
17
|
+
move = medium_ai.move(board, players)
|
18
|
+
expect(valid_moves).to include(move)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require 'tic_tac_toes/move_strategies/human'
|
2
|
-
require 'tic_tac_toes/move_strategies/medium_ai'
|
3
|
-
require 'tic_tac_toes/player_factory'
|
1
|
+
require 'tic_tac_toes/core/move_strategies/human'
|
2
|
+
require 'tic_tac_toes/core/move_strategies/medium_ai'
|
3
|
+
require 'tic_tac_toes/core/player_factory'
|
4
4
|
|
5
|
-
describe TicTacToes::PlayerFactory do
|
6
|
-
let(:player_factory) { TicTacToes::PlayerFactory.new("io") }
|
5
|
+
describe TicTacToes::Core::PlayerFactory do
|
6
|
+
let(:player_factory) { TicTacToes::Core::PlayerFactory.new("io") }
|
7
7
|
|
8
8
|
describe '#generate_human_player' do
|
9
9
|
it "returns a player with the correct token and move strategy" do
|
10
|
-
strategy = TicTacToes::MoveStrategies::Human
|
10
|
+
strategy = TicTacToes::Core::MoveStrategies::Human
|
11
11
|
token = 'X'
|
12
12
|
|
13
13
|
human_player = player_factory.generate_human_player(token)
|
@@ -20,7 +20,7 @@ describe TicTacToes::PlayerFactory do
|
|
20
20
|
it 'returns a player with the correct token and move strategy' do
|
21
21
|
token = 'O'
|
22
22
|
difficulty = :medium
|
23
|
-
strategy = TicTacToes::MoveStrategies::MediumAI
|
23
|
+
strategy = TicTacToes::Core::MoveStrategies::MediumAI
|
24
24
|
|
25
25
|
computer_player = player_factory.generate_computer_player(token,
|
26
26
|
difficulty)
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'tic_tac_toes/board'
|
2
|
-
require 'tic_tac_toes/player'
|
1
|
+
require 'tic_tac_toes/core/board'
|
2
|
+
require 'tic_tac_toes/core/player'
|
3
3
|
|
4
|
-
describe TicTacToes::Player do
|
5
|
-
let(:board) { TicTacToes::Board.new(row_size: 3) }
|
4
|
+
describe TicTacToes::Core::Player do
|
5
|
+
let(:board) { TicTacToes::Core::Board.new(row_size: 3) }
|
6
6
|
let(:io) { double("io", invalid_move_error: true) }
|
7
7
|
let(:players) { double("players") }
|
8
8
|
|
@@ -11,7 +11,7 @@ describe TicTacToes::Player do
|
|
11
11
|
let(:token) { "X" }
|
12
12
|
let(:needs_to_think) { false }
|
13
13
|
|
14
|
-
let(:player) { TicTacToes::Player.new(move_strategy, token, needs_to_think, io) }
|
14
|
+
let(:player) { TicTacToes::Core::Player.new(move_strategy, token, needs_to_think, io) }
|
15
15
|
|
16
16
|
it "only places/returns a move once it receives a valid move" do
|
17
17
|
invalid_space, valid_space = 9, 0
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'test_board_generator'
|
2
|
-
require 'tic_tac_toes/rules'
|
1
|
+
require 'tic_tac_toes/test_board_generator'
|
2
|
+
require 'tic_tac_toes/core/rules'
|
3
3
|
|
4
|
-
describe TicTacToes::Rules do
|
5
|
-
let(:rules) { TicTacToes::Rules }
|
4
|
+
describe TicTacToes::Core::Rules do
|
5
|
+
let(:rules) { TicTacToes::Core::Rules }
|
6
6
|
let(:x) { double("human player", token: "x") }
|
7
7
|
let(:o) { double("computer player", token: "o") }
|
8
8
|
let(:players) { [x, o] }
|
@@ -60,25 +60,25 @@ describe TicTacToes::Rules do
|
|
60
60
|
|
61
61
|
describe '#game_over?' do
|
62
62
|
it "returns false if there is not yet a winner and the board is not full" do
|
63
|
-
board = TestBoardGenerator.generate([x, x, o,
|
64
|
-
|
65
|
-
|
63
|
+
board = TicTacToes::TestBoardGenerator.generate([x, x, o,
|
64
|
+
o, o, nil,
|
65
|
+
x, o, x])
|
66
66
|
|
67
67
|
expect(rules.game_over?(board, players)).to be false
|
68
68
|
end
|
69
69
|
|
70
70
|
it "returns true if any player has won" do
|
71
|
-
board = TestBoardGenerator.generate([ x, nil, nil,
|
72
|
-
|
73
|
-
|
71
|
+
board = TicTacToes::TestBoardGenerator.generate([ x, nil, nil,
|
72
|
+
nil, x, nil,
|
73
|
+
nil, nil, x])
|
74
74
|
|
75
75
|
expect(rules.game_over?(board, players)).to be true
|
76
76
|
end
|
77
77
|
|
78
78
|
it "returns true if the board is full" do
|
79
|
-
board = TestBoardGenerator.generate([x, x, o,
|
80
|
-
|
81
|
-
|
79
|
+
board = TicTacToes::TestBoardGenerator.generate([x, x, o,
|
80
|
+
o, o, x,
|
81
|
+
x, o, x])
|
82
82
|
|
83
83
|
expect(rules.game_over?(board, players)).to be true
|
84
84
|
end
|
@@ -87,18 +87,18 @@ describe TicTacToes::Rules do
|
|
87
87
|
|
88
88
|
describe '#determine_winner' do
|
89
89
|
it "returns the winning token when there is a winner" do
|
90
|
-
board = TestBoardGenerator.generate([ o, nil, nil,
|
91
|
-
|
92
|
-
|
90
|
+
board = TicTacToes::TestBoardGenerator.generate([ o, nil, nil,
|
91
|
+
nil, o, nil,
|
92
|
+
nil, nil, o])
|
93
93
|
winning_token = "o"
|
94
94
|
|
95
95
|
expect(rules.determine_winner(board, players)).to eql(winning_token)
|
96
96
|
end
|
97
97
|
|
98
98
|
it "returns nil if there is not a winner" do
|
99
|
-
board = TestBoardGenerator.generate([x, x, o,
|
100
|
-
|
101
|
-
|
99
|
+
board = TicTacToes::TestBoardGenerator.generate([x, x, o,
|
100
|
+
o, o, nil,
|
101
|
+
x, o, x])
|
102
102
|
|
103
103
|
expect(rules.determine_winner(board, players)).to be_nil
|
104
104
|
end
|
@@ -107,41 +107,41 @@ describe TicTacToes::Rules do
|
|
107
107
|
|
108
108
|
describe '#win?' do
|
109
109
|
it "returns false if the given token has not won" do
|
110
|
-
board = TestBoardGenerator.generate([x, x, o,
|
111
|
-
|
112
|
-
|
110
|
+
board = TicTacToes::TestBoardGenerator.generate([x, x, o,
|
111
|
+
o, o, nil,
|
112
|
+
x, o, x])
|
113
113
|
|
114
114
|
expect(rules.win?(board, x)).to be false
|
115
115
|
end
|
116
116
|
|
117
117
|
it "returns true if the given token has achieved a back diagonal win" do
|
118
|
-
board = TestBoardGenerator.generate([ x, nil, nil,
|
119
|
-
|
120
|
-
|
118
|
+
board = TicTacToes::TestBoardGenerator.generate([ x, nil, nil,
|
119
|
+
nil, x, nil,
|
120
|
+
nil, nil, x])
|
121
121
|
|
122
122
|
expect(rules.win?(board, x)).to be true
|
123
123
|
end
|
124
124
|
|
125
125
|
it "returns true if the given token has achieved a front diagonal win" do
|
126
|
-
board = TestBoardGenerator.generate([nil, nil, x,
|
127
|
-
|
128
|
-
|
126
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, nil, x,
|
127
|
+
nil, x, nil,
|
128
|
+
x, nil, nil])
|
129
129
|
|
130
130
|
expect(rules.win?(board, x)).to be true
|
131
131
|
end
|
132
132
|
|
133
133
|
it "returns true if the given token has achieved a horizonatal win" do
|
134
|
-
board = TestBoardGenerator.generate([nil, nil, nil,
|
135
|
-
|
136
|
-
|
134
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
|
135
|
+
x, x, x,
|
136
|
+
nil, nil, nil])
|
137
137
|
|
138
138
|
expect(rules.win?(board, x)).to be true
|
139
139
|
end
|
140
140
|
|
141
141
|
it "returns true if the given token has achieved a vertical win" do
|
142
|
-
board = TestBoardGenerator.generate([nil, x, nil,
|
143
|
-
|
144
|
-
|
142
|
+
board = TicTacToes::TestBoardGenerator.generate([nil, x, nil,
|
143
|
+
nil, x, nil,
|
144
|
+
nil, x, nil])
|
145
145
|
|
146
146
|
expect(rules.win?(board, x)).to be true
|
147
147
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require 'tic_tac_toes/board'
|
2
|
-
require 'tic_tac_toes/rules'
|
3
|
-
require 'tic_tac_toes/strings'
|
1
|
+
require 'tic_tac_toes/core/board'
|
2
|
+
require 'tic_tac_toes/core/rules'
|
3
|
+
require 'tic_tac_toes/core/strings'
|
4
4
|
|
5
|
-
describe TicTacToes::Strings do
|
6
|
-
let(:strings) { TicTacToes::Strings }
|
5
|
+
describe TicTacToes::Core::Strings do
|
6
|
+
let(:strings) { TicTacToes::Core::Strings }
|
7
7
|
|
8
8
|
describe '#invalid_row_size' do
|
9
9
|
it "returns a string containing the minimum and maximum allowed row sizes" do
|
10
|
-
smallest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.min.to_s
|
11
|
-
largest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.max.to_s
|
10
|
+
smallest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.min.to_s
|
11
|
+
largest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.max.to_s
|
12
12
|
|
13
13
|
expect(strings::INVALID_ROW_SIZE).to include(smallest_row_size, largest_row_size)
|
14
14
|
end
|
@@ -30,7 +30,7 @@ describe TicTacToes::Strings do
|
|
30
30
|
|
31
31
|
describe '#board' do
|
32
32
|
it "returns a board string" do
|
33
|
-
board = TicTacToes::Board.new(row_size: 3)
|
33
|
+
board = TicTacToes::Core::Board.new(row_size: 3)
|
34
34
|
|
35
35
|
leading_spaces_regexp = /^[[:blank:]]+/
|
36
36
|
board_string = <<-END.gsub(leading_spaces_regexp, '')
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'database/pg_wrapper'
|
1
|
+
require 'tic_tac_toes/database/pg_wrapper'
|
2
2
|
require 'pg'
|
3
3
|
|
4
|
-
describe Database::PGWrapper do
|
4
|
+
describe TicTacToes::Database::PGWrapper do
|
5
5
|
database = "tic_tac_toes_test"
|
6
6
|
|
7
|
-
let(:pg_wrapper) { Database::PGWrapper.new(database) }
|
7
|
+
let(:pg_wrapper) { TicTacToes::Database::PGWrapper.new(database) }
|
8
8
|
let(:history1) { double("history 1",
|
9
9
|
:board_size => 9,
|
10
10
|
:moves => [["X", 1], ["O", 4]],
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'tic_tac_toes/core/board'
|
2
|
+
|
3
|
+
module TicTacToes
|
4
|
+
module TestBoardGenerator
|
5
|
+
def self.generate(structure)
|
6
|
+
board_size = structure.count
|
7
|
+
row_size = Math.sqrt(board_size)
|
8
|
+
board = TicTacToes::Core::Board.new(row_size: row_size)
|
9
|
+
|
10
|
+
structure.each_with_index do |player, index|
|
11
|
+
board.place(player, index)
|
12
|
+
end
|
13
|
+
|
14
|
+
board
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require 'tic_tac_toes/board'
|
2
|
-
require 'tic_tac_toes/game_state'
|
3
|
-
require 'tic_tac_toes/player_factory'
|
4
|
-
require 'ui/adapter'
|
1
|
+
require 'tic_tac_toes/core/board'
|
2
|
+
require 'tic_tac_toes/core/game_state'
|
3
|
+
require 'tic_tac_toes/core/player_factory'
|
4
|
+
require 'tic_tac_toes/ui/adapter'
|
5
5
|
|
6
|
-
describe UI::Adapter do
|
6
|
+
describe TicTacToes::UI::Adapter do
|
7
7
|
describe '#new_board_structure' do
|
8
8
|
it 'returns a new board structure' do
|
9
9
|
new_board_structure = [nil, nil, nil, nil, nil, nil, nil, nil, nil]
|
10
|
-
expect(UI::Adapter.new_board_structure).to eq(new_board_structure)
|
10
|
+
expect(TicTacToes::UI::Adapter.new_board_structure).to eq(new_board_structure)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -21,7 +21,7 @@ describe UI::Adapter do
|
|
21
21
|
updated_board_structure = ["X", "O", "X", nil, "O", nil, nil, nil, nil]
|
22
22
|
|
23
23
|
expect(listener).to receive(:move_was_valid).with(updated_board_structure)
|
24
|
-
UI::Adapter.make_move(board_structure, move, listener)
|
24
|
+
TicTacToes::UI::Adapter.make_move(board_structure, move, listener)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -35,7 +35,7 @@ describe UI::Adapter do
|
|
35
35
|
game_over_message = "Game over"
|
36
36
|
|
37
37
|
expect(listener).to receive(:game_is_over).with(updated_board_structure, game_over_message)
|
38
|
-
UI::Adapter.make_move(board_structure, move, listener)
|
38
|
+
TicTacToes::UI::Adapter.make_move(board_structure, move, listener)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -44,7 +44,7 @@ describe UI::Adapter do
|
|
44
44
|
it 'returns a game state object based on a board structure' do
|
45
45
|
board_structure = [nil, nil, nil, nil, "X", nil, nil, nil, nil]
|
46
46
|
|
47
|
-
game_state = UI::Adapter.game_state_from_board_structure(board_structure)
|
47
|
+
game_state = TicTacToes::UI::Adapter.game_state_from_board_structure(board_structure)
|
48
48
|
middle_space = game_state.board.space(4)
|
49
49
|
first_player = game_state.players.first
|
50
50
|
second_player = game_state.players.last
|
@@ -57,16 +57,16 @@ describe UI::Adapter do
|
|
57
57
|
|
58
58
|
describe '#game_state_to_board_structure' do
|
59
59
|
it 'returns a board structure based on a game state object' do
|
60
|
-
player_factory = TicTacToes::PlayerFactory.new('unused_io')
|
60
|
+
player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
|
61
61
|
first_player = player_factory.generate_human_player('X')
|
62
62
|
second_player = player_factory.generate_computer_player('O', :hard)
|
63
63
|
players = [first_player, second_player]
|
64
|
-
board = TicTacToes::Board.new
|
64
|
+
board = TicTacToes::Core::Board.new
|
65
65
|
board.place(first_player, 4)
|
66
66
|
|
67
|
-
game_state = TicTacToes::GameState.new(board, players, UI::NullHistory.new)
|
67
|
+
game_state = TicTacToes::Core::GameState.new(board, players, TicTacToes::UI::NullHistory.new)
|
68
68
|
board_structure = [nil, nil, nil, nil, "X", nil, nil, nil, nil]
|
69
|
-
expect(UI::Adapter.game_state_to_board_structure(game_state)).to eq(board_structure)
|
69
|
+
expect(TicTacToes::UI::Adapter.game_state_to_board_structure(game_state)).to eq(board_structure)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
File without changes
|