erics_tic_tac_toe 0.1.0 → 0.5.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.
- 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
|