tictactoe 0.0.2 → 0.0.3
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/lib/tictactoe.rb +162 -160
- metadata +2 -2
data/lib/tictactoe.rb
CHANGED
@@ -24,201 +24,203 @@ class Tictactoe
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
27
|
+
private
|
28
|
+
|
29
|
+
def play_tictactoe
|
30
|
+
display_board
|
31
|
+
@start_game = interactive
|
32
|
+
while @continue
|
33
|
+
print "\e[2J\e[f" # clear screen
|
34
|
+
case @start_game
|
35
|
+
when 'y'
|
36
|
+
display_board
|
37
|
+
competitor_plays
|
38
|
+
break if !@continue
|
39
|
+
computer_plays
|
40
|
+
break if !@continue
|
41
|
+
when 'q'
|
42
|
+
break
|
43
|
+
when 'n'
|
44
|
+
computer_plays
|
45
|
+
display_board
|
46
|
+
break if !@continue
|
47
|
+
competitor_plays
|
48
|
+
break if !@continue
|
49
|
+
else
|
50
|
+
display_board
|
51
|
+
puts 'Please enter appropriate options'.red
|
52
|
+
interactive
|
53
|
+
end
|
51
54
|
end
|
52
55
|
end
|
53
|
-
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
def computer_plays
|
61
|
-
if @playing
|
62
|
-
computer_moves
|
63
|
-
@continue = continue_playing
|
57
|
+
def interactive
|
58
|
+
puts 'Do you want to play first? enter y/n and q to quit'.purple
|
59
|
+
@start_game = gets.chomp
|
64
60
|
end
|
65
|
-
end
|
66
61
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
@continue = continue_playing
|
62
|
+
def computer_plays
|
63
|
+
if @playing
|
64
|
+
computer_moves
|
65
|
+
@continue = continue_playing
|
66
|
+
end
|
73
67
|
end
|
74
|
-
end
|
75
68
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
69
|
+
def competitor_plays
|
70
|
+
if @continue
|
71
|
+
puts @message
|
72
|
+
move = gets.chomp
|
73
|
+
play(move)
|
74
|
+
@continue = continue_playing
|
75
|
+
end
|
81
76
|
end
|
82
|
-
end
|
83
77
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
@playing = false
|
91
|
-
@message = "Please choose another move, it's already taken".red
|
92
|
-
puts @message
|
93
|
-
elsif !is_numeric(move)
|
94
|
-
@playing = false
|
95
|
-
@message = "Please enter correct move".red
|
96
|
-
puts @message
|
97
|
-
else
|
98
|
-
position = @moves.index(move.to_i)
|
99
|
-
@playing = true
|
100
|
-
@message = "Please enter your move".blue
|
101
|
-
@moves[position] = "O"
|
78
|
+
def continue_playing
|
79
|
+
if (play_until_win || play_until_draw)
|
80
|
+
false
|
81
|
+
else
|
82
|
+
true
|
83
|
+
end
|
102
84
|
end
|
103
|
-
end
|
104
85
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
@moves
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
86
|
+
def play(move)
|
87
|
+
if move.size > 1
|
88
|
+
@playing = false
|
89
|
+
@message = "Please enter appropriate move".red
|
90
|
+
puts @message
|
91
|
+
elsif @moves.values_at(move.to_i).first == "X" || @moves.values_at(move.to_i).first == "O"
|
92
|
+
@playing = false
|
93
|
+
@message = "Please choose another move, it's already taken".red
|
94
|
+
puts @message
|
95
|
+
elsif !is_numeric(move)
|
96
|
+
@playing = false
|
97
|
+
@message = "Please enter correct move".red
|
98
|
+
puts @message
|
99
|
+
else
|
100
|
+
position = @moves.index(move.to_i)
|
101
|
+
@playing = true
|
102
|
+
@message = "Please enter your move".blue
|
103
|
+
@moves[position] = "O"
|
121
104
|
end
|
122
|
-
position_index = rand(0...indexes.size)
|
123
|
-
values_position = indexes.values_at(position_index).first
|
124
|
-
@computer_move = values_position
|
125
|
-
@moves[values_position] = "X"
|
126
105
|
end
|
127
|
-
end
|
128
106
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
107
|
+
def computer_moves
|
108
|
+
temp_moves = @moves.clone
|
109
|
+
temp_moves.delete("O")
|
110
|
+
temp_moves.delete("X")
|
111
|
+
if temp_moves.size == @moves.size
|
112
|
+
@moves[4] = "X"
|
113
|
+
elsif computer_best_move
|
114
|
+
@computer_move = computer_best_move
|
115
|
+
@moves[computer_best_move] = "X"
|
116
|
+
elsif competitor_best_move
|
117
|
+
@computer_move = competitor_best_move
|
118
|
+
@moves[competitor_best_move] = "X"
|
137
119
|
else
|
138
|
-
|
120
|
+
indexes = temp_moves.inject([]) do |result, element|
|
121
|
+
result << @moves.index(element)
|
122
|
+
result
|
123
|
+
end
|
124
|
+
position_index = rand(0...indexes.size)
|
125
|
+
values_position = indexes.values_at(position_index).first
|
126
|
+
@computer_move = values_position
|
127
|
+
@moves[values_position] = "X"
|
139
128
|
end
|
140
|
-
new_line = (index == 3 || index == 6) ? "\n" : ""
|
141
|
-
board += new_line + color_moves
|
142
|
-
board += "|"
|
143
129
|
end
|
144
|
-
puts "#{board}"
|
145
|
-
end
|
146
130
|
|
147
|
-
|
148
|
-
|
149
|
-
|
131
|
+
def display_board
|
132
|
+
board = ""
|
133
|
+
@moves.each_with_index do |move, index|
|
134
|
+
case move
|
135
|
+
when 'X'
|
136
|
+
color_moves = "#{move}".purple
|
137
|
+
when 'O'
|
138
|
+
color_moves = "#{move}".yellow
|
139
|
+
else
|
140
|
+
color_moves = "#{move}"
|
141
|
+
end
|
142
|
+
new_line = (index == 3 || index == 6) ? "\n" : ""
|
143
|
+
board += new_line + color_moves
|
144
|
+
board += "|"
|
145
|
+
end
|
146
|
+
puts "#{board}"
|
150
147
|
end
|
151
|
-
end
|
152
148
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
false
|
149
|
+
def winner
|
150
|
+
get_values.detect do |value|
|
151
|
+
value.one?
|
152
|
+
end
|
158
153
|
end
|
159
|
-
end
|
160
154
|
|
161
|
-
|
162
|
-
|
163
|
-
|
155
|
+
def play_until_win
|
156
|
+
if winner
|
157
|
+
true
|
158
|
+
else
|
159
|
+
false
|
160
|
+
end
|
164
161
|
end
|
165
|
-
!(unmoved.any?)
|
166
|
-
end
|
167
162
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
163
|
+
def play_until_draw
|
164
|
+
unmoved = @moves.select do |move|
|
165
|
+
(0..10).include?(move)
|
166
|
+
end
|
167
|
+
!(unmoved.any?)
|
172
168
|
end
|
173
|
-
end
|
174
169
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
170
|
+
def get_values
|
171
|
+
score_values.inject([]) do |result, v|
|
172
|
+
result << @moves.values_at(v[0], v[1], v[2]).uniq
|
173
|
+
result
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def best_move(check_moves_of, replace_with)
|
178
|
+
score_values.each do |v|
|
179
|
+
result = @moves.values_at(v[0], v[1], v[2])
|
180
|
+
if result.include?("#{check_moves_of}") && result.count("#{check_moves_of}") == 2
|
181
|
+
result.delete("#{check_moves_of}")
|
182
|
+
if result.first == "#{replace_with}"
|
183
|
+
@move = nil
|
184
|
+
else
|
185
|
+
@move = result.first
|
186
|
+
end
|
184
187
|
end
|
185
188
|
end
|
189
|
+
@move
|
186
190
|
end
|
187
|
-
@move
|
188
|
-
end
|
189
191
|
|
190
|
-
|
191
|
-
|
192
|
-
|
192
|
+
def computer_best_move
|
193
|
+
best_move('X', 'O')
|
194
|
+
end
|
193
195
|
|
194
|
-
|
195
|
-
|
196
|
-
|
196
|
+
def competitor_best_move
|
197
|
+
best_move('O', 'X')
|
198
|
+
end
|
197
199
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
200
|
+
def score_values
|
201
|
+
rows = board
|
202
|
+
columns = rows.transpose
|
203
|
+
columns.each do |column|
|
204
|
+
rows.push(column)
|
205
|
+
end
|
206
|
+
rows.push(generate_diagonal(board))
|
207
|
+
rows.push(generate_diagonal(board.reverse))
|
208
|
+
rows
|
203
209
|
end
|
204
|
-
rows.push(generate_diagonal(board))
|
205
|
-
rows.push(generate_diagonal(board.reverse))
|
206
|
-
rows
|
207
|
-
end
|
208
210
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
211
|
+
def generate_diagonal(board)
|
212
|
+
diagonals = []
|
213
|
+
board.each_with_index do |element, index|
|
214
|
+
diagonals << element[index]
|
215
|
+
end
|
216
|
+
diagonals
|
213
217
|
end
|
214
|
-
diagonals
|
215
|
-
end
|
216
218
|
|
217
|
-
|
218
|
-
|
219
|
-
|
219
|
+
def board
|
220
|
+
(0..8).each_slice(3).to_a
|
221
|
+
end
|
220
222
|
|
221
|
-
|
222
|
-
|
223
|
-
|
223
|
+
def is_numeric(move)
|
224
|
+
move.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
|
225
|
+
end
|
224
226
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tictactoe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -37,7 +37,7 @@ files:
|
|
37
37
|
- Rakefile
|
38
38
|
- lib/tictactoe.rb
|
39
39
|
- bin/play_tictactoe
|
40
|
-
homepage: http://
|
40
|
+
homepage: http://www.swathik.com/2012/10/command-line-tictactoe-game-using-ruby.html
|
41
41
|
licenses: []
|
42
42
|
post_install_message:
|
43
43
|
rdoc_options: []
|