erics_tic_tac_toe 0.1.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.markdown +6 -7
- data/Rakefile +2 -1
- data/bin/tic_tac_toe +41 -2
- data/lib/tic_tac_toe.rb +5 -4
- data/lib/tic_tac_toe/board.rb +153 -0
- data/lib/tic_tac_toe/game.rb +70 -0
- data/lib/tic_tac_toe/game_types/terminal_game.rb +86 -0
- data/lib/tic_tac_toe/player.rb +13 -0
- data/lib/tic_tac_toe/players/computer_player.rb +26 -0
- data/lib/tic_tac_toe/players/human_player.rb +28 -0
- data/lib/tic_tac_toe/presentors/game_presenter.rb +16 -0
- data/lib/tic_tac_toe/presentors/player_presenter.rb +13 -0
- data/lib/tic_tac_toe/strategies/minimax_strategy.rb +91 -0
- data/lib/tic_tac_toe/strategies/three_by_three_strategy.rb +260 -0
- data/lib/{tic-tac-toe → tic_tac_toe}/version.rb +1 -1
- data/test/board_test.rb +40 -52
- data/test/game_presentor_test.rb +19 -0
- data/test/game_test.rb +79 -0
- data/test/player_presenter_test.rb +12 -0
- data/test/player_test.rb +57 -0
- data/test/potential_state_test.rb +53 -0
- data/test/solver_test.rb +169 -93
- data/test/terminal_game_test.rb +78 -0
- data/test/test_helper.rb +4 -0
- data/tic-tac-toe.gemspec +1 -1
- metadata +25 -11
- data/lib/tic-tac-toe/board.rb +0 -148
- data/lib/tic-tac-toe/game.rb +0 -62
- data/lib/tic-tac-toe/game_types/terminal_game.rb +0 -63
- data/lib/tic-tac-toe/solver.rb +0 -16
- data/lib/tic-tac-toe/strategies/threebythree_implementations/brute_force_implementation.rb +0 -197
- data/lib/tic-tac-toe/strategies/threebythree_stategy.rb +0 -30
- data/test/brute_force_implementation_test.rb +0 -25
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GamePresentorTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@game = TicTacToe::Game.new
|
6
|
+
@presentor = TicTacToe::GamePresentor.new(@game)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_grid
|
10
|
+
assert_equal [%w(1 2 3), %w(4 5 6), %w(7 8 9)], @presentor.grid
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_grid_with_moves
|
14
|
+
@game = TicTacToe::Game.new([['x', nil, nil], [nil, nil, nil], [nil, nil, nil]])
|
15
|
+
@presentor = TicTacToe::GamePresentor.new(@game)
|
16
|
+
|
17
|
+
assert_equal [%w(x 2 3), %w(4 5 6), %w(7 8 9)], @presentor.grid
|
18
|
+
end
|
19
|
+
end
|
data/test/game_test.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class GameTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
class PlayerMock
|
7
|
+
def initialize(move)
|
8
|
+
@move = move
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_move(_board)
|
12
|
+
move = @move
|
13
|
+
@move = nil
|
14
|
+
move
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_next_move?
|
18
|
+
!!@move
|
19
|
+
end
|
20
|
+
|
21
|
+
def letter
|
22
|
+
'x'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_grid
|
27
|
+
game = TicTacToe::Game.new
|
28
|
+
|
29
|
+
assert_equal game.grid, empty_grid
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_an_empty_game_is_not_solved
|
33
|
+
game = TicTacToe::Game.new
|
34
|
+
|
35
|
+
refute game.solved?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_a_full_grid_is_cats
|
39
|
+
# x o x
|
40
|
+
# x o x
|
41
|
+
# o x o
|
42
|
+
game = TicTacToe::Game.new([%w(x o x), %w(x o x), %w(o x o)])
|
43
|
+
|
44
|
+
assert game.cats?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_winner
|
48
|
+
game = TicTacToe::Game.new([%w(x x x), [nil,nil,nil], [nil, nil, nil]],
|
49
|
+
PlayerMock.new(nil), PlayerMock.new(nil))
|
50
|
+
|
51
|
+
assert_equal 'x', game.winner
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_setting_a_players_move
|
55
|
+
game = TicTacToe::Game.new(empty_grid, PlayerMock.new('1'), PlayerMock.new(nil))
|
56
|
+
game.start
|
57
|
+
|
58
|
+
assert_equal 'x', game.board.get_cell(0, 0)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_set_move_via_computer
|
62
|
+
game = TicTacToe::Game.new(empty_grid, PlayerMock.new([0,0]), PlayerMock.new([2,2]))
|
63
|
+
game.start
|
64
|
+
|
65
|
+
assert_equal 7, game.board.empty_positions.size
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_skip_a_players_turn
|
69
|
+
game = TicTacToe::Game.new(empty_grid, PlayerMock.new([0,0]), PlayerMock.new(nil))
|
70
|
+
game.start
|
71
|
+
|
72
|
+
assert game.board.only_one?
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def empty_grid(size=3)
|
77
|
+
Array.new(size) { Array.new(size) { nil } }
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PlayerPresenterTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@player_mock = OpenStruct.new(letter: 'x', type: 'mock')
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_move_json
|
9
|
+
assert_equal({letter: 'x', type: 'mock', move: '1'}.to_json,
|
10
|
+
TicTacToe::PlayerPresenter.new(@player_mock).move_json('1'))
|
11
|
+
end
|
12
|
+
end
|
data/test/player_test.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BoardMock; end
|
4
|
+
|
5
|
+
class PlayerTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_build_human_player
|
8
|
+
assert_equal TicTacToe::HumanPlayer,
|
9
|
+
TicTacToe::Player.build('type' => 'human').class
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_build_computer_player
|
13
|
+
assert_equal TicTacToe::ComputerPlayer,
|
14
|
+
TicTacToe::Player.build('type' => 'computer').class
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module SharedPlayerTests
|
19
|
+
def test_gets_move
|
20
|
+
assert_equal [0, 0], @player.get_move(BoardMock.new)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_letter
|
24
|
+
assert_equal 'x', @player.letter
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_has_next_move
|
28
|
+
assert @player.has_next_move?
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_has_type
|
32
|
+
refute @player.type.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class HumanPlayerTest < MiniTest::Unit::TestCase
|
38
|
+
def setup
|
39
|
+
@player = TicTacToe::HumanPlayer.new('letter' => "x", 'move' => [0,0])
|
40
|
+
end
|
41
|
+
|
42
|
+
include SharedPlayerTests
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class ComputerPlayerTest < MiniTest::Unit::TestCase
|
47
|
+
class SolverMock
|
48
|
+
def solve
|
49
|
+
[0, 0]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def setup
|
53
|
+
@player = TicTacToe::ComputerPlayer.new({'letter' => "x"}, SolverMock)
|
54
|
+
end
|
55
|
+
|
56
|
+
include SharedPlayerTests
|
57
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PotentialStateTest < MiniTest::Unit::TestCase
|
4
|
+
def test_solved
|
5
|
+
set_grid([ ['x', 'x', 'x'], [nil, nil, nil], [nil, nil, nil] ])
|
6
|
+
assert @state.solved?
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_fork_exists
|
10
|
+
set_grid([ ['x', nil, 'x'], [nil, 'x', nil], [nil, nil, nil] ])
|
11
|
+
assert @state.fork_exists?
|
12
|
+
|
13
|
+
set_grid([ ['x', nil, 'x'], [nil, 'o', nil], ['x', nil, nil] ])
|
14
|
+
assert @state.fork_exists?
|
15
|
+
|
16
|
+
set_grid([ ['o', nil, 'o'], [nil, 'x', nil], ['o', nil, nil] ])
|
17
|
+
refute @state.fork_exists?
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_forking_positions
|
22
|
+
# o | 2 | x |
|
23
|
+
# 4 | o | 6 |
|
24
|
+
# x | 8 | 9 |
|
25
|
+
set_grid([ ['o', nil, 'x'], [nil, 'o', nil], ['x', nil, nil] ])
|
26
|
+
assert @state.forking_positions.size == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_can_win_next_turn
|
30
|
+
set_grid([[ 'x', nil, 'x'], [nil, nil, nil], [nil, nil, nil] ])
|
31
|
+
assert @state.can_win_next_turn?
|
32
|
+
|
33
|
+
# 1 | 2 | x
|
34
|
+
# 4 | o | 6
|
35
|
+
# 7 | x | x
|
36
|
+
set_grid([[ nil, nil, 'x'], [nil, 'o', nil], [nil, 'x', 'x'] ])
|
37
|
+
assert @state.can_win_next_turn?
|
38
|
+
|
39
|
+
# o | 2 | x |
|
40
|
+
# 4 | o | 6 |
|
41
|
+
# x | 8 | 9 |
|
42
|
+
set_grid([ ['o', nil, 'x'], [nil, 'o', nil], ['x', nil, nil] ])
|
43
|
+
refute @state.can_win_next_turn?
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def set_grid(grid)
|
49
|
+
board = TicTacToe::Board.new
|
50
|
+
board.grid = grid
|
51
|
+
@state = TicTacToe::ThreeByThree::PotentialState.new(board, 'x')
|
52
|
+
end
|
53
|
+
end
|
data/test/solver_test.rb
CHANGED
@@ -1,131 +1,140 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module SharedSolverTests
|
4
|
+
def test_win_horizontally
|
5
|
+
refute @board.solved?
|
6
|
+
|
7
|
+
# Will win, when there is a winning move
|
8
|
+
set_grid([[ 'x', 'x', nil],
|
9
|
+
[ 'o', 'o', nil],
|
10
|
+
[ 'x', 'o', nil] ])
|
11
|
+
refute @board.solved? # Is not solved yet
|
12
|
+
solve!
|
13
|
+
assert !!@board.solved?, "Could not solve the board" # Solved it
|
14
|
+
assert_equal 'x', @board.get_cell(2, 0) # Placed the right letter
|
9
15
|
end
|
10
16
|
|
11
|
-
def
|
12
|
-
refute board.solved?
|
17
|
+
def test_wins_across
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
assert board.solved?
|
25
|
-
assert_equal 'x', board.get_cell(2, 2)
|
19
|
+
set_grid([[ 'x', 'o', nil],
|
20
|
+
[ nil, 'x', nil],
|
21
|
+
[ 'o', nil, nil] ])
|
22
|
+
refute @board.solved?
|
23
|
+
solve!
|
24
|
+
assert !!@board.solved?
|
25
|
+
assert_equal 'x', @board.get_cell(2, 2)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_wins_vertically
|
26
29
|
|
27
|
-
set_grid([[ 'x', nil,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
set_grid([[ 'x', nil, 'o'],
|
31
|
+
[nil, 'o', 'o'],
|
32
|
+
[ 'x', nil, nil] ])
|
33
|
+
refute @board.solved?
|
34
|
+
solve!
|
35
|
+
assert !!@board.solved?
|
36
|
+
assert_equal 'x', @board.get_cell(0, 1)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_does_not_win_unsolvable_board
|
32
40
|
|
33
41
|
# Can not win when there is no winning move
|
34
42
|
set_grid([[ 'o', nil, nil], [nil, nil, nil], ['o', nil, nil] ])
|
35
|
-
refute board.solved?
|
36
|
-
|
37
|
-
refute board.solved?
|
43
|
+
refute @board.solved?
|
44
|
+
solve!
|
45
|
+
refute @board.solved?
|
38
46
|
end
|
39
47
|
|
40
|
-
def
|
41
|
-
refute board.solved?
|
48
|
+
def test_blocks_horizontally
|
49
|
+
refute @board.solved?
|
42
50
|
|
43
51
|
# Will block when the opponent is about to win
|
44
|
-
set_grid([ ['o', 'o', nil],
|
45
|
-
|
46
|
-
|
47
|
-
refute board.solved?
|
52
|
+
set_grid([ ['o', 'o', nil],
|
53
|
+
[nil, 'x', nil],
|
54
|
+
[nil, 'x', nil]])
|
55
|
+
refute @board.solved?
|
56
|
+
solve!
|
57
|
+
refute @board.solved?
|
48
58
|
# Placed the right letter at the right place
|
49
|
-
assert_equal 'x', board.get_cell(2, 0)
|
59
|
+
assert_equal 'x', @board.get_cell(2, 0)
|
50
60
|
end
|
51
61
|
|
62
|
+
def test_blocks_vertically
|
63
|
+
|
64
|
+
set_grid([ ['x', 'o', nil],
|
65
|
+
[nil, nil, nil],
|
66
|
+
[nil, 'o', nil]])
|
67
|
+
solve!
|
68
|
+
assert_equal 'x', @board.get_cell(1, 1)
|
69
|
+
end
|
52
70
|
|
53
|
-
|
54
|
-
|
71
|
+
|
72
|
+
def test_forks_in_middle
|
73
|
+
refute @board.solved?
|
55
74
|
|
56
75
|
# Place letter in place where next turn is an automatic win
|
57
|
-
set_grid([ ['x',
|
58
|
-
|
59
|
-
|
60
|
-
refute board.solved?
|
61
|
-
|
76
|
+
set_grid([ ['x', 'o', 'x'],
|
77
|
+
[nil, nil, 'o'],
|
78
|
+
[nil, nil, nil]])
|
79
|
+
refute @board.solved?
|
80
|
+
solve!
|
81
|
+
refute @board.solved?
|
82
|
+
correct_cells = @board.get_cell(1, 1) || @board.get_cell(0, 2)
|
83
|
+
assert !!correct_cells
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_forks_in_corner
|
62
87
|
|
63
88
|
# 1 | 2 | x
|
64
89
|
# 4 | o | 6
|
65
90
|
# 7 | x | 9 <--
|
66
|
-
set_grid([ [nil,
|
67
|
-
|
68
|
-
|
69
|
-
refute board.solved?
|
70
|
-
|
91
|
+
set_grid([ [nil, 'o', 'x'],
|
92
|
+
[nil, 'o', nil],
|
93
|
+
[nil, 'x', nil]])
|
94
|
+
refute @board.solved?
|
95
|
+
solve!
|
96
|
+
refute @board.solved?
|
97
|
+
assert_equal 'x', @board.get_cell(2, 2)
|
71
98
|
end
|
72
99
|
|
73
|
-
def
|
74
|
-
# Will block an opponent if they will have a change to fork next turn
|
75
|
-
|
76
|
-
# 1 | 2 | o
|
77
|
-
# 4 | x | 6
|
78
|
-
# 7 | o | 9 <--
|
79
|
-
set_grid([ [nil, nil, 'o'], [nil, 'x',nil], [nil,'o',nil]])
|
80
|
-
refute board.solved?
|
81
|
-
@solver.next_move!
|
82
|
-
refute board.solved?
|
83
|
-
assert_equal 'x', board.get_cell(2, 2)
|
84
|
-
|
100
|
+
def test_does_not_create_fork
|
85
101
|
# 1 | 2 | o
|
86
102
|
# 4 | x | 6
|
87
103
|
# o | 8 | 9
|
88
|
-
set_grid([[nil,nil,'o'],
|
89
|
-
|
90
|
-
|
91
|
-
|
104
|
+
set_grid([[nil,nil,'o'],
|
105
|
+
[nil,'x',nil],
|
106
|
+
['o',nil,nil]])
|
107
|
+
solve!
|
108
|
+
assert_nil @board.get_cell(2,2)
|
109
|
+
assert_nil @board.get_cell(0,0)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_does_not_create_fork_in_the_future
|
92
113
|
|
93
114
|
# x | 2 | 3
|
94
115
|
# 4 | o | 6
|
95
116
|
# 7 | 8 | o
|
96
117
|
set_grid([ ['x',nil,nil], [nil,'o',nil], [nil,nil,'o'] ])
|
97
|
-
|
98
|
-
assert_nil board.get_cell(1, 0)
|
99
|
-
assert_nil board.get_cell(0, 1)
|
100
|
-
assert_nil board.get_cell(2, 1)
|
101
|
-
assert_nil board.get_cell(1, 2)
|
118
|
+
solve!
|
119
|
+
assert_nil @board.get_cell(1, 0)
|
120
|
+
assert_nil @board.get_cell(0, 1)
|
121
|
+
assert_nil @board.get_cell(2, 1)
|
122
|
+
assert_nil @board.get_cell(1, 2)
|
102
123
|
end
|
103
124
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
@
|
108
|
-
assert_equal 'x', board.center_cell
|
109
|
-
assert board.only_one?
|
125
|
+
def test_does_not_create_fork_in_the_far_future
|
126
|
+
set_grid([['o', nil, nil], [nil, nil, nil], [nil, nil, nil]])
|
127
|
+
solve!
|
128
|
+
assert_nil @board.get_cell(0, 2)
|
110
129
|
end
|
111
|
-
|
112
|
-
def test_oposite_corner
|
113
|
-
# 1 | 2 | o
|
114
|
-
# 4 | x | 6
|
115
|
-
# 7 | 8 | 9
|
116
|
-
set_grid([[nil,nil,'o'],[nil,'x',nil],[nil,nil,nil]])
|
117
|
-
@solver.next_move!
|
118
|
-
assert_equal 'x', board.get_cell(0, 2)
|
119
130
|
|
120
|
-
set_grid([['o',nil,nil],[nil,'x',nil],[nil,nil,nil]])
|
121
|
-
@solver.next_move!
|
122
|
-
assert_equal 'x', board.get_cell(2, 2)
|
123
|
-
end
|
124
131
|
|
125
132
|
def test_empty_corner
|
126
133
|
set_grid([[nil,nil,nil],[nil,'o',nil],[nil,nil,nil]])
|
127
|
-
|
128
|
-
|
134
|
+
solve!
|
135
|
+
played_corner = @board.get_cell(0,0) || @board.get_cell(0,2) ||
|
136
|
+
@board.get_cell(2,0) || @board.get_cell(2,2)
|
137
|
+
assert played_corner
|
129
138
|
end
|
130
139
|
|
131
140
|
def test_any_empty_position
|
@@ -133,17 +142,84 @@ class SolverTest < MiniTest::Unit::TestCase
|
|
133
142
|
# o | x | 6
|
134
143
|
# x | o | x
|
135
144
|
set_grid([['o', 'x', 'o'],['o','x',nil],['x','o','x']])
|
136
|
-
|
137
|
-
assert_equal 'x', board.get_cell(2, 1)
|
145
|
+
solve!
|
146
|
+
assert_equal 'x', @board.get_cell(2, 1)
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_raises_exception_on_full_board
|
150
|
+
set_grid([%w(x o x), %w(o o x), %w(o x o)])
|
151
|
+
assert_raises(RuntimeError) { solve! }
|
138
152
|
end
|
139
153
|
|
140
154
|
private
|
141
155
|
|
142
156
|
def set_grid(grid)
|
143
|
-
board.
|
157
|
+
@board.grid = grid
|
144
158
|
end
|
145
159
|
|
146
|
-
def
|
147
|
-
@solver.
|
160
|
+
def solve!
|
161
|
+
@board.play_at(*@solver.solve, 'x')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class MinimaxSolverTest < MiniTest::Unit::TestCase
|
166
|
+
def setup
|
167
|
+
@board = TicTacToe::Board.new
|
168
|
+
@solver = TicTacToe::MinimaxStrategy.new(@board, 'x')
|
169
|
+
end
|
170
|
+
|
171
|
+
include SharedSolverTests
|
172
|
+
end
|
173
|
+
|
174
|
+
class ThreeByThreeSolverTest < MiniTest::Unit::TestCase
|
175
|
+
def setup
|
176
|
+
@board = TicTacToe::Board.new
|
177
|
+
@solver = TicTacToe::ThreeByThreeStrategy.new(@board, 'x')
|
178
|
+
end
|
179
|
+
|
180
|
+
include SharedSolverTests
|
181
|
+
|
182
|
+
def test_block_fork
|
183
|
+
set_grid([['o', nil, nil], ['x', 'o', nil], [nil, nil, 'x']])
|
184
|
+
solve!
|
185
|
+
assert_equal 'x', @board.get_cell(1, 0)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_center
|
189
|
+
# Will play in the center if its an empty @board
|
190
|
+
assert @board.empty?
|
191
|
+
solve!
|
192
|
+
assert_equal 'x', @board.get_cell(@board.size/2, @board.size/2)
|
193
|
+
assert @board.only_one?
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_opposite_corner
|
197
|
+
# 1 | 2 | o
|
198
|
+
# 4 | x | 6
|
199
|
+
# 7 | 8 | 9
|
200
|
+
set_grid([[nil,nil,'o'],[nil,'x',nil],[nil,nil,nil]])
|
201
|
+
solve!
|
202
|
+
assert_equal 'x', @board.get_cell(0, 2)
|
203
|
+
|
204
|
+
set_grid([['o',nil,nil],[nil,'x',nil],[nil,nil,nil]])
|
205
|
+
solve!
|
206
|
+
assert_equal 'x', @board.get_cell(2, 2)
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_corners
|
210
|
+
set_grid([['x', nil, nil], [nil, 'o', nil], [nil, nil, nil]])
|
211
|
+
solve!
|
212
|
+
assert_equal 'x', @board.get_cell(2,0)
|
213
|
+
|
214
|
+
set_grid([['x', 'o', 'x'], [nil, 'o', nil], ['o', 'x', nil]])
|
215
|
+
solve!
|
216
|
+
assert_equal 'x', @board.get_cell(2, 2)
|
217
|
+
|
218
|
+
# x | o | x
|
219
|
+
# o | o | x
|
220
|
+
# | x | o
|
221
|
+
set_grid([['x', 'o', 'x'], ['o', 'o', 'x'], [nil, 'x', 'o']])
|
222
|
+
solve!
|
223
|
+
assert_equal 'x', @board.get_cell(0, 2)
|
148
224
|
end
|
149
225
|
end
|