tictactoe-core 0.1.1 → 0.1.2
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 +5 -2
- data/Rakefile +5 -1
- data/lib/tictactoe/boards/square.rb +39 -0
- data/lib/tictactoe/game.rb +18 -37
- data/lib/tictactoe/players/computer.rb +4 -0
- data/lib/tictactoe/players/perfect_computer.rb +30 -0
- data/lib/tictactoe/state.rb +3 -17
- data/spec/test_run.rb +9 -3
- data/spec/tictactoe/ai/perfect_intelligence_spec.rb +5 -6
- data/spec/tictactoe/boards/board_type_factory_spec.rb +56 -8
- data/spec/tictactoe/game_spec.rb +53 -10
- data/spec/tictactoe/players/computer_spec.rb +5 -1
- data/spec/tictactoe/state_spec.rb +4 -7
- data/tictactoe-core.gemspec +2 -2
- metadata +4 -8
- data/lib/tictactoe/boards/board_type_factory.rb +0 -15
- data/lib/tictactoe/boards/four_by_four_board.rb +0 -28
- data/lib/tictactoe/boards/three_by_three_board.rb +0 -27
- data/spec/tictactoe/boards/four_by_four_board_spec.rb +0 -30
- data/spec/tictactoe/boards/three_by_three_board_spec.rb +0 -30
- data/tictactoe-core-0.1.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6dee06d505fa1667d90e59b321748404c70e84c7
|
4
|
+
data.tar.gz: 22b34d8ea0156dbc37d4d22762877ed4ba092454
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb5318ea5259cedc41caf36ab1fc5d2be5d31265b85eb65a8042f8e421275d2338db1d3cddf9b5d8fd9f88176ecd546a93e94eed8c5474471dd5303eac2f3e92
|
7
|
+
data.tar.gz: 6649004de7c777e0c34e1c8dafd55f3dda18a5ff289d13f4a127675e5b093c7a7f5dd1411a0e35c01404172c7ae9cd437e9353aa221af7b4d49217bafd098da4
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -27,8 +27,12 @@ task :profile do
|
|
27
27
|
|
28
28
|
RubyProf.start
|
29
29
|
|
30
|
-
TestRun.new(4).game_winner
|
30
|
+
TestRun.new(4).game_winner
|
31
31
|
|
32
32
|
result = RubyProf.stop
|
33
33
|
RubyProf::GraphHtmlPrinter.new(result).print(STDOUT)
|
34
34
|
end
|
35
|
+
|
36
|
+
task :build do
|
37
|
+
sh 'gem build tictactoe-core.gemspec'
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Tictactoe
|
2
|
+
module Boards
|
3
|
+
class Square
|
4
|
+
def initialize(side_size)
|
5
|
+
self.side_size = side_size
|
6
|
+
end
|
7
|
+
|
8
|
+
def locations
|
9
|
+
@locations ||= (0..(side_size * side_size) -1).to_a
|
10
|
+
end
|
11
|
+
|
12
|
+
def lines
|
13
|
+
@lines ||= horizontal_lines + vertical_lines + diagonal_lines
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
attr_accessor :side_size
|
18
|
+
|
19
|
+
def horizontal_lines
|
20
|
+
locations.each_slice(side_size).to_a
|
21
|
+
end
|
22
|
+
|
23
|
+
def vertical_lines
|
24
|
+
horizontal_lines.transpose
|
25
|
+
end
|
26
|
+
|
27
|
+
def diagonal_lines
|
28
|
+
descending = (0..side_size - 1).map do |column|
|
29
|
+
column * (side_size + 1)
|
30
|
+
end
|
31
|
+
ascending = (1..side_size).map do |column|
|
32
|
+
column * (side_size - 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
[descending, ascending]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/tictactoe/game.rb
CHANGED
@@ -1,26 +1,17 @@
|
|
1
1
|
require 'tictactoe/state'
|
2
2
|
require 'tictactoe/sequence'
|
3
|
-
require 'tictactoe/boards/
|
4
|
-
require 'tictactoe/ai/perfect_intelligence'
|
5
|
-
require 'tictactoe/ai/random_chooser'
|
6
|
-
|
7
|
-
require 'tictactoe/players/factory'
|
8
|
-
require 'tictactoe/players/computer'
|
3
|
+
require 'tictactoe/boards/square'
|
9
4
|
|
10
5
|
module Tictactoe
|
11
6
|
class Game
|
12
|
-
attr_accessor :board_size, :x_type, :o_type, :random
|
13
7
|
attr_accessor :current_player, :state
|
8
|
+
attr_accessor :board_size, :x_type, :o_type
|
14
9
|
|
15
|
-
def initialize(board_size, x_type, o_type
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
def register_human_factory(factory)
|
23
|
-
players_factory.register(:human, factory)
|
10
|
+
def initialize(players_factory, board_size, x_type, o_type)
|
11
|
+
self.players_factory = players_factory
|
12
|
+
self.board_size = board_size
|
13
|
+
self.x_type = x_type
|
14
|
+
self.o_type = o_type
|
24
15
|
reset
|
25
16
|
end
|
26
17
|
|
@@ -32,6 +23,10 @@ module Tictactoe
|
|
32
23
|
end
|
33
24
|
end
|
34
25
|
|
26
|
+
def ready_to_tick?
|
27
|
+
!is_finished? && current_player.value.ready_to_move?
|
28
|
+
end
|
29
|
+
|
35
30
|
def is_finished?
|
36
31
|
state.is_finished?
|
37
32
|
end
|
@@ -49,6 +44,8 @@ module Tictactoe
|
|
49
44
|
end
|
50
45
|
|
51
46
|
private
|
47
|
+
attr_accessor :players_factory
|
48
|
+
|
52
49
|
def is_valid?(move)
|
53
50
|
move && state.available_moves.include?(move)
|
54
51
|
end
|
@@ -72,31 +69,15 @@ module Tictactoe
|
|
72
69
|
|
73
70
|
def reset_players
|
74
71
|
first_mark = Sequence.new([:x, :o]).first
|
72
|
+
players = [first_mark, first_mark.next].zip([x_type, o_type]).map do |mark, type|
|
73
|
+
players_factory.create(type, mark)
|
74
|
+
end
|
75
75
|
|
76
|
-
|
77
|
-
o_player = players_factory.create(o_type, first_mark.next)
|
78
|
-
|
79
|
-
self.current_player = Sequence.new([x_player, o_player]).first
|
80
|
-
end
|
81
|
-
|
82
|
-
def players_factory
|
83
|
-
@players_factory ||= create_players_factory
|
84
|
-
end
|
85
|
-
|
86
|
-
def create_players_factory
|
87
|
-
factory = Players::Factory.new()
|
88
|
-
factory.register(:computer, computer_factory)
|
89
|
-
factory
|
90
|
-
end
|
91
|
-
|
92
|
-
def computer_factory
|
93
|
-
intelligence = Ai::PerfectIntelligence.new
|
94
|
-
chooser = Ai::RandomChooser.new(random)
|
95
|
-
lambda {|mark| Players::Computer.new(mark, intelligence, chooser)}
|
76
|
+
self.current_player = Sequence.new(players).first
|
96
77
|
end
|
97
78
|
|
98
79
|
def reset_state
|
99
|
-
self.state = State.new(Boards::
|
80
|
+
self.state = State.new(Boards::Square.new(board_size))
|
100
81
|
end
|
101
82
|
end
|
102
83
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'tictactoe/players/computer'
|
2
|
+
require 'tictactoe/ai/perfect_intelligence'
|
3
|
+
require 'tictactoe/ai/random_chooser'
|
4
|
+
|
5
|
+
module Tictactoe
|
6
|
+
module Players
|
7
|
+
class PerfectComputer
|
8
|
+
def initialize(mark, random = Random.new)
|
9
|
+
intelligence = Tictactoe::Ai::PerfectIntelligence.new
|
10
|
+
chooser = Tictactoe::Ai::RandomChooser.new(random)
|
11
|
+
self.player = Tictactoe::Players::Computer.new(mark, intelligence, chooser)
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_move(state)
|
15
|
+
player.get_move(state)
|
16
|
+
end
|
17
|
+
|
18
|
+
def mark
|
19
|
+
player.mark
|
20
|
+
end
|
21
|
+
|
22
|
+
def ready_to_move?
|
23
|
+
player.ready_to_move?
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
attr_accessor :player
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/tictactoe/state.rb
CHANGED
@@ -21,10 +21,6 @@ module Tictactoe
|
|
21
21
|
self.class.new(board, new_marks)
|
22
22
|
end
|
23
23
|
|
24
|
-
def when_finished(&block)
|
25
|
-
yield winner if is_finished?
|
26
|
-
end
|
27
|
-
|
28
24
|
def is_finished?
|
29
25
|
is_full? || has_winner?
|
30
26
|
end
|
@@ -43,19 +39,9 @@ module Tictactoe
|
|
43
39
|
end
|
44
40
|
|
45
41
|
def find_winner
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
for location in line
|
51
|
-
mark = marks[location]
|
52
|
-
first_mark_in_line ||= mark
|
53
|
-
|
54
|
-
is_winner = mark && mark == first_mark_in_line
|
55
|
-
break if !is_winner
|
56
|
-
end
|
57
|
-
|
58
|
-
return first_mark_in_line if is_winner
|
42
|
+
board.lines.each do |line|
|
43
|
+
line_marks = line.map{|location| marks[location]}
|
44
|
+
return line_marks.first if line_marks.all?{|mark| mark && mark == line_marks.first}
|
59
45
|
end
|
60
46
|
|
61
47
|
nil
|
data/spec/test_run.rb
CHANGED
@@ -2,18 +2,24 @@ dirname = File.expand_path(File.dirname(File.dirname(__FILE__))) + "/lib"
|
|
2
2
|
$LOAD_PATH.unshift(dirname) unless $LOAD_PATH.include?(dirname)
|
3
3
|
|
4
4
|
require 'tictactoe/game'
|
5
|
+
require 'tictactoe/players/factory'
|
6
|
+
require 'tictactoe/players/perfect_computer'
|
5
7
|
|
6
8
|
class TestRun
|
7
9
|
attr_reader :board_size, :random
|
10
|
+
|
8
11
|
def initialize(board_size, random = Random.new)
|
9
12
|
@board_size = board_size
|
10
13
|
@random = random
|
11
14
|
end
|
12
15
|
|
13
16
|
def game_winner
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
factory = Tictactoe::Players::Factory.new
|
18
|
+
factory.register(:computer, lambda { |mark| Tictactoe::Players::PerfectComputer.new(mark, random) })
|
19
|
+
|
20
|
+
game = Tictactoe::Game.new(factory, board_size, :computer, :computer)
|
21
|
+
|
22
|
+
game.tick until game.is_finished?
|
17
23
|
game.winner
|
18
24
|
end
|
19
25
|
end
|
@@ -2,12 +2,11 @@ require 'spec_helper'
|
|
2
2
|
require 'tictactoe/ai/perfect_intelligence'
|
3
3
|
require 'tictactoe/state'
|
4
4
|
require 'tictactoe/sequence'
|
5
|
-
require 'tictactoe/boards/
|
6
|
-
require 'tictactoe/boards/four_by_four_board'
|
5
|
+
require 'tictactoe/boards/square'
|
7
6
|
|
8
7
|
RSpec.describe Tictactoe::Ai::PerfectIntelligence do
|
9
8
|
def board(*marks)
|
10
|
-
state = Tictactoe::State.new(Tictactoe::Boards::
|
9
|
+
state = Tictactoe::State.new(Tictactoe::Boards::Square.new(3))
|
11
10
|
marks.each_with_index do |mark, location|
|
12
11
|
state = state.make_move(location, mark)
|
13
12
|
end
|
@@ -36,7 +35,7 @@ RSpec.describe Tictactoe::Ai::PerfectIntelligence do
|
|
36
35
|
)
|
37
36
|
expect(play(state)).to eq [4]
|
38
37
|
end
|
39
|
-
|
38
|
+
|
40
39
|
it 'given the possibility to lose, should block, not matter if there is a fork comming' do
|
41
40
|
state = board(
|
42
41
|
:x, nil, nil,
|
@@ -50,7 +49,7 @@ RSpec.describe Tictactoe::Ai::PerfectIntelligence do
|
|
50
49
|
state = board(
|
51
50
|
:x, :o, :x,
|
52
51
|
:o, :x, :o,
|
53
|
-
nil, nil, :o
|
52
|
+
nil, nil, :o
|
54
53
|
)
|
55
54
|
expect(play(state)).to eq [6]
|
56
55
|
end
|
@@ -103,7 +102,7 @@ RSpec.describe Tictactoe::Ai::PerfectIntelligence do
|
|
103
102
|
end
|
104
103
|
|
105
104
|
def board4(*marks)
|
106
|
-
state = Tictactoe::State.new(Tictactoe::Boards::
|
105
|
+
state = Tictactoe::State.new(Tictactoe::Boards::Square.new(4))
|
107
106
|
marks.each_with_index do |mark, location|
|
108
107
|
state = state.make_move(location, mark)
|
109
108
|
end
|
@@ -1,16 +1,64 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'tictactoe/boards/
|
2
|
+
require 'tictactoe/boards/square'
|
3
3
|
|
4
|
-
RSpec.describe Tictactoe::Boards::
|
4
|
+
RSpec.describe Tictactoe::Boards::Square do
|
5
5
|
def create(side_size)
|
6
|
-
described_class.new
|
6
|
+
described_class.new(side_size)
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
describe 'given size 3' do
|
10
|
+
let(:board) { create(3) }
|
11
|
+
|
12
|
+
it "should know the available locations" do
|
13
|
+
expect(board.locations).to eq([0, 1, 2, 3, 4, 5, 6, 7, 8])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should know the lines" do
|
17
|
+
expected_lines = [
|
18
|
+
[0, 1, 2],
|
19
|
+
[3, 4, 5],
|
20
|
+
[6, 7, 8],
|
21
|
+
|
22
|
+
[0, 3, 6],
|
23
|
+
[1, 4, 7],
|
24
|
+
[2, 5, 8],
|
25
|
+
|
26
|
+
[0, 4, 8],
|
27
|
+
[2, 4, 6],
|
28
|
+
]
|
29
|
+
actual_lines = board.lines
|
30
|
+
|
31
|
+
expect(actual_lines).to match_array(expected_lines)
|
32
|
+
end
|
11
33
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
34
|
+
|
35
|
+
describe 'given size 4' do
|
36
|
+
let(:board) { create(4) }
|
37
|
+
|
38
|
+
it 'has the possible locations' do
|
39
|
+
expect(board.locations).to eq([
|
40
|
+
0, 1, 2, 3,
|
41
|
+
4, 5, 6, 7,
|
42
|
+
8, 9, 10, 11,
|
43
|
+
12, 13, 14, 15
|
44
|
+
])
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should know the lines' do
|
48
|
+
expect(board.lines).to eq([
|
49
|
+
[0, 1, 2, 3],
|
50
|
+
[4, 5, 6, 7],
|
51
|
+
[8, 9, 10, 11],
|
52
|
+
[12, 13, 14, 15],
|
53
|
+
|
54
|
+
[0, 4, 8, 12],
|
55
|
+
[1, 5, 9, 13],
|
56
|
+
[2, 6, 10, 14],
|
57
|
+
[3, 7, 11, 15],
|
58
|
+
|
59
|
+
[0, 5, 10, 15],
|
60
|
+
[3, 6, 9, 12]
|
61
|
+
])
|
62
|
+
end
|
15
63
|
end
|
16
64
|
end
|
data/spec/tictactoe/game_spec.rb
CHANGED
@@ -1,34 +1,51 @@
|
|
1
1
|
require 'tictactoe/game'
|
2
|
+
require 'tictactoe/players/factory'
|
3
|
+
require 'tictactoe/players/perfect_computer'
|
2
4
|
|
3
5
|
RSpec.describe Tictactoe::Game do
|
4
6
|
class Human
|
5
7
|
attr_reader :mark
|
6
8
|
|
7
9
|
def initialize(mark, moves)
|
8
|
-
@mark = mark
|
10
|
+
@mark = mark
|
9
11
|
@moves = moves
|
10
12
|
end
|
11
13
|
|
12
14
|
def get_move(state)
|
13
15
|
@moves.pop
|
14
16
|
end
|
17
|
+
|
18
|
+
def ready_to_move?
|
19
|
+
!@moves.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class FixedRandom
|
24
|
+
def rand
|
25
|
+
0.0
|
26
|
+
end
|
15
27
|
end
|
16
28
|
|
17
|
-
let(:moves){[]}
|
29
|
+
let(:moves) { [] }
|
18
30
|
|
19
31
|
def create(board_size, x_type, o_type)
|
20
|
-
|
21
|
-
|
22
|
-
|
32
|
+
computer_factory = lambda { |mark| Tictactoe::Players::PerfectComputer.new(mark, FixedRandom.new) }
|
33
|
+
human_factory = lambda { |mark| Human.new(mark, moves) }
|
34
|
+
|
35
|
+
factory = Tictactoe::Players::Factory.new
|
36
|
+
factory.register(:computer, computer_factory)
|
37
|
+
factory.register(:human, human_factory)
|
38
|
+
|
39
|
+
described_class.new(factory, board_size, x_type, o_type)
|
23
40
|
end
|
24
41
|
|
25
42
|
def human_tick_playing_to(game, loc)
|
26
43
|
moves << loc
|
27
|
-
game.tick
|
44
|
+
game.tick
|
28
45
|
end
|
29
|
-
|
46
|
+
|
30
47
|
def computer_tick(game)
|
31
|
-
game.tick
|
48
|
+
game.tick
|
32
49
|
end
|
33
50
|
|
34
51
|
def expect_amount_of_marks(game, mark, expected_count)
|
@@ -41,6 +58,32 @@ RSpec.describe Tictactoe::Game do
|
|
41
58
|
expect(game.is_finished?).to eq(false)
|
42
59
|
end
|
43
60
|
|
61
|
+
it 'is not ready to tick when the player is not ready to move' do
|
62
|
+
game = create(3, :human, :human)
|
63
|
+
expect(game.ready_to_tick?).to eq false
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'is ready to tick when the player is ready to move' do
|
67
|
+
game = create(3, :human, :human)
|
68
|
+
moves << 0
|
69
|
+
expect(game.ready_to_tick?).to eq true
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'is not ready to tick when the player is ready to move but the game has finished' do
|
73
|
+
game = create(3, :human, :human)
|
74
|
+
human_tick_playing_to(game, 0)
|
75
|
+
human_tick_playing_to(game, 1)
|
76
|
+
human_tick_playing_to(game, 2)
|
77
|
+
human_tick_playing_to(game, 5)
|
78
|
+
human_tick_playing_to(game, 3)
|
79
|
+
human_tick_playing_to(game, 6)
|
80
|
+
human_tick_playing_to(game, 4)
|
81
|
+
human_tick_playing_to(game, 8)
|
82
|
+
human_tick_playing_to(game, 7)
|
83
|
+
moves << 0
|
84
|
+
expect(game.ready_to_tick?).to eq false
|
85
|
+
end
|
86
|
+
|
44
87
|
describe 'can be observed' do
|
45
88
|
it 'initial game size 3' do
|
46
89
|
game = create(3, :human, :human)
|
@@ -70,7 +113,7 @@ RSpec.describe Tictactoe::Game do
|
|
70
113
|
nil, nil, nil
|
71
114
|
])
|
72
115
|
end
|
73
|
-
|
116
|
+
|
74
117
|
it 'first play of o on size 3' do
|
75
118
|
game = create(3, :human, :human)
|
76
119
|
human_tick_playing_to(game, 0)
|
@@ -126,7 +169,7 @@ RSpec.describe Tictactoe::Game do
|
|
126
169
|
human_tick_playing_to(game, 6)
|
127
170
|
expect(game.is_finished?).to eq(false)
|
128
171
|
end
|
129
|
-
|
172
|
+
|
130
173
|
it do
|
131
174
|
game = create(3, :human, :human)
|
132
175
|
human_tick_playing_to(game, 0)
|
@@ -27,8 +27,12 @@ RSpec.describe Tictactoe::Players::Computer do
|
|
27
27
|
|
28
28
|
it 'has a mark' do
|
29
29
|
computer = create(:x)
|
30
|
-
expect(computer.mark).to eq(:x)
|
30
|
+
expect(computer.mark).to eq(:x)
|
31
|
+
end
|
31
32
|
|
33
|
+
it 'is ready to move' do
|
34
|
+
computer = create(:x)
|
35
|
+
expect(computer.ready_to_move?).to eq(true)
|
32
36
|
end
|
33
37
|
|
34
38
|
it 'can make a move' do
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'tictactoe/state'
|
3
|
-
require 'tictactoe/boards/three_by_three_board'
|
4
3
|
|
5
4
|
RSpec.describe Tictactoe::State do
|
6
5
|
def look_at(state, location)
|
@@ -12,18 +11,16 @@ RSpec.describe Tictactoe::State do
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def expect_finished(expected)
|
15
|
-
|
16
|
-
expect(finished).to eq(expected)
|
14
|
+
expect(@state.is_finished?).to eq(expected)
|
17
15
|
end
|
18
16
|
|
19
17
|
def expect_winner(expected)
|
20
|
-
|
21
|
-
expect(actual_winner).to eq(expected)
|
18
|
+
expect(@state.winner).to eq(expected)
|
22
19
|
end
|
23
20
|
|
24
21
|
describe "given a 3x3 board" do
|
25
22
|
before(:each) do
|
26
|
-
@board = Tictactoe::Boards::
|
23
|
+
@board = Tictactoe::Boards::Square.new(3)
|
27
24
|
@state = described_class.new(@board)
|
28
25
|
end
|
29
26
|
|
@@ -73,7 +70,7 @@ RSpec.describe Tictactoe::State do
|
|
73
70
|
end
|
74
71
|
end
|
75
72
|
|
76
|
-
Tictactoe::Boards::
|
73
|
+
Tictactoe::Boards::Square.new(3).lines.each do |line|
|
77
74
|
describe "with a line for player a" do
|
78
75
|
before(:each) do
|
79
76
|
line.each do |l|
|
data/tictactoe-core.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "tictactoe-core"
|
3
|
-
s.version = "0.1.
|
4
|
-
s.date = %q{2015-
|
3
|
+
s.version = "0.1.2"
|
4
|
+
s.date = %q{2015-06-11}
|
5
5
|
|
6
6
|
s.summary = "The core logic of a tic-tac-toe implementation"
|
7
7
|
s.description = "The core logic of a tic-tac-toe implementation written as part of 8th Light's apprenticeship"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tictactoe-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mateu Adsuara
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The core logic of a tic-tac-toe implementation written as part of 8th
|
14
14
|
Light's apprenticeship
|
@@ -27,12 +27,11 @@ files:
|
|
27
27
|
- lib/tictactoe/ai/perfect_intelligence.rb
|
28
28
|
- lib/tictactoe/ai/random_chooser.rb
|
29
29
|
- lib/tictactoe/ai/tree.rb
|
30
|
-
- lib/tictactoe/boards/
|
31
|
-
- lib/tictactoe/boards/four_by_four_board.rb
|
32
|
-
- lib/tictactoe/boards/three_by_three_board.rb
|
30
|
+
- lib/tictactoe/boards/square.rb
|
33
31
|
- lib/tictactoe/game.rb
|
34
32
|
- lib/tictactoe/players/computer.rb
|
35
33
|
- lib/tictactoe/players/factory.rb
|
34
|
+
- lib/tictactoe/players/perfect_computer.rb
|
36
35
|
- lib/tictactoe/sequence.rb
|
37
36
|
- lib/tictactoe/state.rb
|
38
37
|
- runtests.sh
|
@@ -48,14 +47,11 @@ files:
|
|
48
47
|
- spec/tictactoe/ai/perfect_intelligence_spec.rb
|
49
48
|
- spec/tictactoe/ai/random_choser_spec.rb
|
50
49
|
- spec/tictactoe/boards/board_type_factory_spec.rb
|
51
|
-
- spec/tictactoe/boards/four_by_four_board_spec.rb
|
52
|
-
- spec/tictactoe/boards/three_by_three_board_spec.rb
|
53
50
|
- spec/tictactoe/game_spec.rb
|
54
51
|
- spec/tictactoe/players/computer_spec.rb
|
55
52
|
- spec/tictactoe/players/factory_spec.rb
|
56
53
|
- spec/tictactoe/sequence_spec.rb
|
57
54
|
- spec/tictactoe/state_spec.rb
|
58
|
-
- tictactoe-core-0.1.0.gem
|
59
55
|
- tictactoe-core.gemspec
|
60
56
|
homepage: https://github.com/demonh3x/tictactoe-core.rb
|
61
57
|
licenses:
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'tictactoe/boards/three_by_three_board'
|
2
|
-
require 'tictactoe/boards/four_by_four_board'
|
3
|
-
|
4
|
-
module Tictactoe
|
5
|
-
module Boards
|
6
|
-
class BoardTypeFactory
|
7
|
-
def create(side_size)
|
8
|
-
case side_size
|
9
|
-
when 3 then ThreeByThreeBoard.new
|
10
|
-
when 4 then FourByFourBoard.new
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Tictactoe
|
2
|
-
module Boards
|
3
|
-
class FourByFourBoard
|
4
|
-
LOCATIONS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
5
|
-
|
6
|
-
HORIZONTAL_LINES = [
|
7
|
-
[0, 1, 2, 3],
|
8
|
-
[4, 5, 6, 7],
|
9
|
-
[8, 9, 10, 11],
|
10
|
-
[12, 13, 14, 15],
|
11
|
-
]
|
12
|
-
VERTICAL_LINES = HORIZONTAL_LINES.transpose
|
13
|
-
DIAGONALS = [
|
14
|
-
[0, 5, 10, 15],
|
15
|
-
[3, 6, 9, 12],
|
16
|
-
]
|
17
|
-
LINES = HORIZONTAL_LINES + VERTICAL_LINES + DIAGONALS
|
18
|
-
|
19
|
-
def locations
|
20
|
-
LOCATIONS
|
21
|
-
end
|
22
|
-
|
23
|
-
def lines
|
24
|
-
LINES
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Tictactoe
|
2
|
-
module Boards
|
3
|
-
class ThreeByThreeBoard
|
4
|
-
LOCATIONS = [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
5
|
-
|
6
|
-
HORIZONTAL_LINES = [
|
7
|
-
[0, 1, 2],
|
8
|
-
[3, 4, 5],
|
9
|
-
[6, 7, 8],
|
10
|
-
]
|
11
|
-
VERTICAL_LINES = HORIZONTAL_LINES.transpose
|
12
|
-
DIAGONALS = [
|
13
|
-
[0, 4, 8],
|
14
|
-
[2, 4, 6],
|
15
|
-
]
|
16
|
-
LINES = HORIZONTAL_LINES + VERTICAL_LINES + DIAGONALS
|
17
|
-
|
18
|
-
def locations
|
19
|
-
LOCATIONS
|
20
|
-
end
|
21
|
-
|
22
|
-
def lines
|
23
|
-
LINES
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'tictactoe/boards/four_by_four_board'
|
3
|
-
|
4
|
-
RSpec.describe Tictactoe::Boards::FourByFourBoard do
|
5
|
-
it 'has the possible locations' do
|
6
|
-
expect(described_class.new.locations).to eq([
|
7
|
-
0, 1, 2, 3,
|
8
|
-
4, 5, 6, 7,
|
9
|
-
8, 9, 10, 11,
|
10
|
-
12, 13, 14, 15
|
11
|
-
])
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should know the lines' do
|
15
|
-
expect(described_class.new.lines).to eq([
|
16
|
-
[0, 1, 2, 3],
|
17
|
-
[4, 5, 6, 7],
|
18
|
-
[8, 9, 10, 11],
|
19
|
-
[12, 13, 14, 15],
|
20
|
-
|
21
|
-
[0, 4, 8, 12],
|
22
|
-
[1, 5, 9, 13],
|
23
|
-
[2, 6, 10, 14],
|
24
|
-
[3, 7, 11, 15],
|
25
|
-
|
26
|
-
[0, 5, 10, 15],
|
27
|
-
[3, 6, 9, 12]
|
28
|
-
])
|
29
|
-
end
|
30
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'tictactoe/boards/three_by_three_board'
|
3
|
-
|
4
|
-
RSpec.describe Tictactoe::Boards::ThreeByThreeBoard do
|
5
|
-
before(:each) do
|
6
|
-
@board = described_class.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should know the available locations" do
|
10
|
-
expect(@board.locations).to eq([0, 1, 2, 3, 4, 5, 6, 7, 8])
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should know the lines" do
|
14
|
-
expected_lines = [
|
15
|
-
[0, 1, 2],
|
16
|
-
[3, 4, 5],
|
17
|
-
[6, 7, 8],
|
18
|
-
|
19
|
-
[0, 3, 6],
|
20
|
-
[1, 4, 7],
|
21
|
-
[2, 5, 8],
|
22
|
-
|
23
|
-
[0, 4, 8],
|
24
|
-
[2, 4, 6],
|
25
|
-
]
|
26
|
-
actual_lines = @board.lines
|
27
|
-
|
28
|
-
expect(actual_lines).to match_array(expected_lines)
|
29
|
-
end
|
30
|
-
end
|
data/tictactoe-core-0.1.0.gem
DELETED
Binary file
|