tea-tictactoe 0.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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +8 -0
  3. data/bin/play_tictactoe +4 -0
  4. data/lib/tictactoe.rb +226 -0
  5. metadata +59 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b32259e055b40072c1ce1a7fee649012c6f5c65fe768f6b23df3ee9fda0d2554
4
+ data.tar.gz: 709c61732ed572258f9d16f9f1f61f32f2e3ddbccb7e496fad6115ef33c6d0a9
5
+ SHA512:
6
+ metadata.gz: '096caffe7ffb8eb7ec4847f0bae5956e0db7f1acd92ee67799fed25f9bd9f7dcf0acb5404a16b956b8ca0cfcd1afc8d411e317268cf3fddc0f9f87a270e2ed4d'
7
+ data.tar.gz: f645c81272f2e60adc62c9669b8a10aba90e5c1307e628860b475619eb49941c438be8ccc7a17654e92446f6e47c29051ecfe5165c02beb7297a771d32b206e8
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tictactoe'
4
+ Tictactoe.new.play_game
data/lib/tictactoe.rb ADDED
@@ -0,0 +1,226 @@
1
+ require "color_text"
2
+
3
+ class Tictactoe
4
+
5
+ def initialize
6
+ @moves = (0..8).to_a
7
+ @computer_move = 4
8
+ @playing = true
9
+ @message = "Please enter your move".blue
10
+ @continue = true
11
+ end
12
+
13
+ def play_game
14
+ play_tictactoe
15
+ if play_until_win
16
+ who_won = winner.first == 'X' ? 'Computer' : 'You'
17
+ puts '********************'
18
+ display_board
19
+ puts "#{who_won} Won".neon
20
+ elsif play_until_draw
21
+ puts '********************'
22
+ display_board
23
+ puts "It's a draw".neon
24
+ end
25
+ end
26
+
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
54
+ end
55
+ end
56
+
57
+ def interactive
58
+ puts 'Do you want to play first? enter y/n and q to quit'.purple
59
+ @start_game = gets.chomp
60
+ end
61
+
62
+ def computer_plays
63
+ if @playing
64
+ computer_moves
65
+ @continue = continue_playing
66
+ end
67
+ end
68
+
69
+ def competitor_plays
70
+ if @continue
71
+ puts @message
72
+ move = gets.chomp
73
+ play(move)
74
+ @continue = continue_playing
75
+ end
76
+ end
77
+
78
+ def continue_playing
79
+ if (play_until_win || play_until_draw)
80
+ false
81
+ else
82
+ true
83
+ end
84
+ end
85
+
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"
104
+ end
105
+ end
106
+
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"
119
+ else
120
+ indexes = temp_moves.inject([]) do |result, element|
121
+ result << @moves.index(element)
122
+ result
123
+ end
124
+ position_index = Random.new.rand(0...indexes.size)
125
+ values_position = indexes.values_at(position_index).first
126
+ @computer_move = values_position
127
+ @moves[values_position] = "X"
128
+ end
129
+ end
130
+
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}"
147
+ end
148
+
149
+ def winner
150
+ get_values.detect do |value|
151
+ value.one?
152
+ end
153
+ end
154
+
155
+ def play_until_win
156
+ if winner
157
+ true
158
+ else
159
+ false
160
+ end
161
+ end
162
+
163
+ def play_until_draw
164
+ unmoved = @moves.select do |move|
165
+ (0..10).include?(move)
166
+ end
167
+ !(unmoved.any?)
168
+ end
169
+
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
187
+ end
188
+ end
189
+ @move
190
+ end
191
+
192
+ def computer_best_move
193
+ best_move('X', 'O')
194
+ end
195
+
196
+ def competitor_best_move
197
+ best_move('O', 'X')
198
+ end
199
+
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
209
+ end
210
+
211
+ def generate_diagonal(board)
212
+ diagonals = []
213
+ board.each_with_index do |element, index|
214
+ diagonals << element[index]
215
+ end
216
+ diagonals
217
+ end
218
+
219
+ def board
220
+ (0..8).each_slice(3).to_a
221
+ end
222
+
223
+ def is_numeric(move)
224
+ move.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
225
+ end
226
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tea-tictactoe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - ClownG
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: color_text
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.3
27
+ description: A simple tictactoe game gem to play in your terminal
28
+ email:
29
+ executables:
30
+ - play_tictactoe
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Rakefile
35
+ - bin/play_tictactoe
36
+ - lib/tictactoe.rb
37
+ homepage: ''
38
+ licenses: []
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 3.3.5
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Enter play_tictactoe command in your terminal to play
59
+ test_files: []