Class: Tic

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-tic-tac-toe.rb

Instance Method Summary collapse

Constructor Details

#initializeTic

Returns a new instance of Tic.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ruby-tic-tac-toe.rb', line 5

def initialize
  #map of all places that are possible wins
  @columns = [      
    [:a1,:a2,:a3],
    [:b1,:b2,:b3],
    [:c1,:c2,:c3],
    
    [:a1,:b1,:c1],
    [:a2,:b2,:c2],
    [:a3,:b3,:c3],
    
    [:a1,:b2,:c3],
    [:c1,:b2,:a3]
  ]
  
  @cpu = rand() > 0.5 ? 'X' : 'O'
  @user = @cpu == 'X' ? 'O' : 'X'
  
  @cpu_name = "Ruby"
  put_line
  puts "\n  RUBY TIC TAC TOE".purple
  print "\n What is your name? ".neon
  STDOUT.flush
  @user_name = gets.chomp
  put_bar

  @user_score = 0
  @cpu_score = 0
  
  start_game(@user == 'X')
end

Instance Method Details

#ask_to_play_again(user_goes_first) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/ruby-tic-tac-toe.rb', line 241

def ask_to_play_again(user_goes_first)
  print " Play again? (Yn): "
  STDOUT.flush
  response = gets.chomp.downcase
  case response
  when "y"   then restart_game(user_goes_first)
  when "yes" then restart_game(user_goes_first)
  when "n"   then #do nothing
  when "no"  then #do nothing
  else ask_to_play_again(user_goes_first)
  end
end

#check_game(next_turn) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/ruby-tic-tac-toe.rb', line 194

def check_game(next_turn)

  game_over = nil
  
  @columns.each do |column|
    # see if cpu has won
    if times_in_column(column, @cpu) == 3
      put_line
      draw_game
      put_line
      puts ""
      puts " Game Over -- #{@cpu_name} WINS!!!\n".blue
      game_over = true
      @cpu_score += 1
      ask_to_play_again(false)
    end
    # see if user has won
    if times_in_column(column, @user) == 3
      put_line
      draw_game
      put_line
      puts ""
      puts " Game Over -- #{@user_name} WINS!!!\n".blue
      game_over = true
      @user_score += 1
      ask_to_play_again(true)
    end
  end
  
  unless game_over
    if(moves_left > 0)
      if(next_turn == @user)
        user_turn
      else
        cpu_turn
      end
    else
      put_line
      draw_game
      put_line
      puts ""
      puts " Game Over -- DRAW!\n".blue
      ask_to_play_again(rand() > 0.5)
    end
  end
end

#cpu_find_moveObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/ruby-tic-tac-toe.rb', line 90

def cpu_find_move

  # see if cpu can win
  #see if any columns already have 2 (cpu)
  @columns.each do |column|
    if times_in_column(column, @cpu) == 2
      return empty_in_column column
    end
  end
  
  # see if user can win
  #see if any columns already have 2 (user)
  @columns.each do |column|
    if times_in_column(column, @user) == 2
      return empty_in_column column
    end
  end
  
  #see if any columns aready have 1 (cpu)
  @columns.each do |column|
    if times_in_column(column, @cpu) == 1
      return empty_in_column column
    end
  end
  
  #no strategic spot found so just find a random empty
  k = @places.keys;
  i = rand(k.length)
  if @places[k[i]] == " "
    return k[i]
  else
    #random selection is taken so just find the first empty slot
    @places.each { |k,v| return k if v == " " }
  end
end

#cpu_turnObject



82
83
84
85
86
87
88
# File 'lib/ruby-tic-tac-toe.rb', line 82

def cpu_turn
  move = cpu_find_move
  @places[move] = @cpu
  put_line
  puts " #{@cpu_name} marks #{move.to_s.upcase.green}".neon
  check_game(@user)
end

#draw_gameObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ruby-tic-tac-toe.rb', line 66

def draw_game
  puts ""
  puts " Wins: #{@cpu_name}:#{@cpu_score} #{@user_name}:#{@user_score}".gray
  puts ""
  puts " #{@cpu_name}: #{@cpu.green}"
  puts " #{@user_name}: #{@user.green}"
  puts ""
  puts "     a   b   c".gray
  puts ""
  puts " 1   #{@places[:a1].green} | #{@places[:b1].green} | #{@places[:c1].green} ".gray
  puts "    --- --- ---"
  puts " 2   #{@places[:a2].green} | #{@places[:b2].green} | #{@places[:c2].green} ".gray
  puts "    --- --- ---"
  puts " 3   #{@places[:a3].green} | #{@places[:b3].green} | #{@places[:c3].green} ".gray
end

#empty_in_column(arr) ⇒ Object



139
140
141
142
143
144
145
# File 'lib/ruby-tic-tac-toe.rb', line 139

def empty_in_column arr
  arr.each do |i| 
    if @places[i] == " "
      return i
    end
  end
end

#moves_leftObject



190
191
192
# File 'lib/ruby-tic-tac-toe.rb', line 190

def moves_left
  @places.values.select{ |v| v == " " }.length
end

#put_barObject



61
62
63
64
# File 'lib/ruby-tic-tac-toe.rb', line 61

def put_bar
  puts ("#" * 80).gray
  puts ("#" * 80).gray
end

#put_lineObject



57
58
59
# File 'lib/ruby-tic-tac-toe.rb', line 57

def put_line
  puts ("-" * 80).gray
end

#restart_game(user_goes_first) ⇒ Object



52
53
54
55
# File 'lib/ruby-tic-tac-toe.rb', line 52

def restart_game(user_goes_first)
  (1...20).each { |i| put_line }
  start_game(user_goes_first)
end

#start_game(user_goes_first) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ruby-tic-tac-toe.rb', line 37

def start_game(user_goes_first)
  #the tic tac toe slots
  @places = {
    a1:" ",a2:" ",a3:" ",
    b1:" ",b2:" ",b3:" ",
    c1:" ",c2:" ",c3:" "
  }

  if user_goes_first
    user_turn
  else
    cpu_turn
  end
end

#times_in_column(arr, item) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ruby-tic-tac-toe.rb', line 126

def times_in_column arr, item
  times = 0
  arr.each do |i| 
    times += 1 if @places[i] == item
    unless @places[i] == item || @places[i] == " "
      #oppisite piece is in column so column cannot be used for win.
      #therefore, the strategic thing to do is choose a dif column so return 0.
      return 0
    end
  end
  times
end

#user_turnObject



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/ruby-tic-tac-toe.rb', line 147

def user_turn
  put_line
  puts "\n  RUBY TIC TAC TOE".purple
  draw_game
  print "\n #{@user_name}, please make a move or type 'exit' to quit: ".neon
  STDOUT.flush
  input = gets.chomp.downcase.to_sym
  put_bar
  if input.length == 2
    a = input.to_s.split("")
    if(['a','b','c'].include? a[0])
      if(['1','2','3'].include? a[1])
        if @places[input] == " "
          @places[input] = @user
          put_line
          puts " #{@user_name} marks #{input.to_s.upcase.green}".neon
          check_game(@cpu)
        else
          wrong_move
        end
      else
        wrong_input
      end
    else
      wrong_input
    end
  else
    wrong_input unless input == :exit
  end
end

#wrong_inputObject



178
179
180
181
182
# File 'lib/ruby-tic-tac-toe.rb', line 178

def wrong_input
  put_line
  puts " Please specify a move with the format 'A1' , 'B3' , 'C2' etc.".red
  user_turn
end

#wrong_moveObject



184
185
186
187
188
# File 'lib/ruby-tic-tac-toe.rb', line 184

def wrong_move
  put_line
  puts " You must choose an empty slot".red
  user_turn
end