ttt_gem_8thlight 1.0.0 → 1.0.1
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/lib/ttt/ai/unbeatable_ai.rb +8 -7
- data/lib/ttt/board.rb +20 -44
- data/lib/ttt/game.rb +2 -2
- data/spec/board_spec.rb +7 -7
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a677010854cc94da21784a121e50e2f93449fde6
|
4
|
+
data.tar.gz: f07cd54a50011d6aff03b47701f5b6595ed72b94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61c3414113113fb0f6a86bf1d4593bb110c77bea70198f3d0ca73fc7670e77a1ca28cdcaf6d057b13523a3770fc390766253c5f0426797f97d2127f44e0c939a
|
7
|
+
data.tar.gz: cf79de88dee160f84cc6f5e3c300ad94fdb112fe2c6cc3ecab76c81eb9ab29730ca59ea2694ea1d8af845a2a2fd4c2bbbf586bda301a8de1d08949a5bfd5a178
|
data/lib/ttt/ai/unbeatable_ai.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
module TicTacToe
|
2
2
|
module AIRules
|
3
3
|
class UnbeatableAI
|
4
|
-
|
5
|
-
|
4
|
+
MAX_SCORE = 100
|
5
|
+
MIN_SCORE = -100
|
6
|
+
TIED_SCORE = 0
|
6
7
|
|
7
8
|
def self.make_move(board, mark)
|
8
|
-
best_score =
|
9
|
+
best_score = MIN_SCORE
|
9
10
|
best_space = 0
|
10
11
|
opponent_mark = mark == "X" ? "O" : "X"
|
11
12
|
|
12
13
|
board.empty_spaces.each do |space|
|
13
14
|
board.place_move(mark, space)
|
14
|
-
score = minimax(board, opponent_mark, 0,
|
15
|
+
score = minimax(board, opponent_mark, 0, MIN_SCORE, MAX_SCORE, false, -1)
|
15
16
|
board.undo_move(space)
|
16
17
|
|
17
18
|
if score > best_score
|
@@ -48,9 +49,9 @@ module TicTacToe
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def self.check_game_state(board, mark, depth)
|
51
|
-
return
|
52
|
-
return
|
53
|
-
|
52
|
+
return TIED_SCORE if board.tied_game?
|
53
|
+
return MAX_SCORE + depth if board.winner == mark
|
54
|
+
MIN_SCORE + depth
|
54
55
|
end
|
55
56
|
|
56
57
|
def self.game_done?(board, depth)
|
data/lib/ttt/board.rb
CHANGED
@@ -8,18 +8,18 @@ module TicTacToe
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.parse(board)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
if
|
16
|
-
|
11
|
+
new_board_for_translation = self.new
|
12
|
+
translated_board_spaces = []
|
13
|
+
new_spaces_for_translation = board.split('')
|
14
|
+
new_spaces_for_translation.each_index do |index|
|
15
|
+
if new_spaces_for_translation[index] == '_' || new_spaces_for_translation[index].to_i != 0
|
16
|
+
translated_board_spaces << (index + 1).to_s
|
17
17
|
else
|
18
|
-
|
18
|
+
translated_board_spaces << new_spaces_for_translation[index]
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
|
21
|
+
new_board_for_translation.spaces = translated_board_spaces
|
22
|
+
new_board_for_translation
|
23
23
|
end
|
24
24
|
|
25
25
|
def to_s
|
@@ -27,11 +27,11 @@ module TicTacToe
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def get(space)
|
30
|
-
@spaces[space-1]
|
30
|
+
@spaces[(space.to_i)-1]
|
31
31
|
end
|
32
32
|
|
33
|
-
def place_move(piece, *
|
34
|
-
|
33
|
+
def place_move(piece, *indices)
|
34
|
+
indices.each do |space|
|
35
35
|
@spaces[(space.to_i)-1] = piece
|
36
36
|
end
|
37
37
|
end
|
@@ -40,7 +40,7 @@ module TicTacToe
|
|
40
40
|
@spaces[(space.to_i)-1] = space.to_s
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
43
|
+
def is_space_taken?(space)
|
44
44
|
@spaces[(space.to_i) - 1].to_i == 0
|
45
45
|
end
|
46
46
|
|
@@ -57,16 +57,14 @@ module TicTacToe
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def has_winner?
|
60
|
-
|
61
|
-
@solutions.each { |sol| has_winner = true if unique?(sol)}
|
62
|
-
has_winner
|
60
|
+
@solutions.find { |sol| is_solution_found?(sol)}
|
63
61
|
end
|
64
62
|
|
65
|
-
def
|
63
|
+
def is_solution_found?(spaces)
|
66
64
|
spaces.map { |s| @spaces[s-1]}.uniq.length == 1
|
67
65
|
end
|
68
66
|
|
69
|
-
def
|
67
|
+
def translate_board_to_string
|
70
68
|
@spaces.reduce("") do |blank_spaces, spaces|
|
71
69
|
if !spaces.to_i.zero?
|
72
70
|
blank_spaces << '_'
|
@@ -80,37 +78,15 @@ module TicTacToe
|
|
80
78
|
@spaces.select { |x| x.to_i != 0}
|
81
79
|
end
|
82
80
|
|
83
|
-
def row_win
|
84
|
-
(@spaces.map { |space| space.to_i }).each_slice(3) { |nums| @solutions.push(nums)}
|
85
|
-
end
|
86
|
-
|
87
|
-
def column_win
|
88
|
-
3.times do |check|
|
89
|
-
((check+1)..(9)).step(3).each_slice(3) do |nums|
|
90
|
-
@solutions.push(nums)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def diagonal_win
|
96
|
-
(1..(9)).step(4).each_slice(3) do |nums|
|
97
|
-
@solutions.push(nums)
|
98
|
-
end
|
99
|
-
((3)..(9)-1).step(2).each_slice(3) do |nums|
|
100
|
-
@solutions.push(nums)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
81
|
def winning_solutions
|
105
|
-
@solutions = []
|
106
|
-
|
107
|
-
|
108
|
-
diagonal_win
|
82
|
+
@solutions = [[1,2,3], [4,5,6], [7,8,9],
|
83
|
+
[1,4,7], [2,5,8], [3,6,9],
|
84
|
+
[1,5,9], [3,5,7]]
|
109
85
|
end
|
110
86
|
|
111
87
|
def winner
|
112
88
|
winner = ""
|
113
|
-
@solutions.each { |sol| winner = @spaces[sol[0]-1] if
|
89
|
+
@solutions.each { |sol| winner = @spaces[sol[0]-1] if is_solution_found?(sol)}
|
114
90
|
winner
|
115
91
|
end
|
116
92
|
end
|
data/lib/ttt/game.rb
CHANGED
@@ -71,7 +71,7 @@ module TicTacToe
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def valid_move?(space)
|
74
|
-
!@board.
|
74
|
+
!@board.is_space_taken?(space)
|
75
75
|
end
|
76
76
|
|
77
77
|
def ask_move(player)
|
@@ -92,7 +92,7 @@ module TicTacToe
|
|
92
92
|
@ui.print_board(@board) if @player_two.class == Human
|
93
93
|
moves[:player_two] = get_move(@player_two)
|
94
94
|
place_move(@player_two.mark, moves[:player_two])
|
95
|
-
@ui.print_board(@
|
95
|
+
@ui.print_board(@board)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
data/spec/board_spec.rb
CHANGED
@@ -11,14 +11,14 @@ describe TicTacToe::Board do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
describe "#
|
15
|
-
it "makes the board
|
16
|
-
board.
|
14
|
+
describe "#translate_board_to_string" do
|
15
|
+
it "makes the board representation a string" do
|
16
|
+
board.translate_board_to_string.should == '_________'
|
17
17
|
end
|
18
18
|
|
19
19
|
it "doesn't replace moves with spaces" do
|
20
20
|
board.spaces[3] = "X"
|
21
|
-
board.
|
21
|
+
board.translate_board_to_string.should == '___X_____'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -46,14 +46,14 @@ describe TicTacToe::Board do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
describe "#
|
49
|
+
describe "#is_space_taken?" do
|
50
50
|
it "is false when the space isn't taken" do
|
51
|
-
board.
|
51
|
+
board.is_space_taken?(5).should be_false
|
52
52
|
end
|
53
53
|
|
54
54
|
it "is true when the space is taken" do
|
55
55
|
board.place_move('X', 6)
|
56
|
-
board.
|
56
|
+
board.is_space_taken?(6).should be_true
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ttt_gem_8thlight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Meagan Waller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
version: '0'
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
85
|
+
rubygems_version: 2.0.3
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: My Tic Tac Toe engine with unbeatable AI
|