Class: Tictactoe

Inherits:
Object
  • Object
show all
Defined in:
lib/tictactoe.rb

Instance Method Summary collapse

Constructor Details

#initializeTictactoe

Returns a new instance of Tictactoe.



5
6
7
8
9
10
11
# File 'lib/tictactoe.rb', line 5

def initialize
  @moves = (0..8).to_a
  @computer_move = 4
  @playing = true
  @message = "Please enter your move".blue
  @continue = true
end

Instance Method Details

#best_move(check_moves_of, replace_with) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/tictactoe.rb', line 175

def best_move(check_moves_of, replace_with)
  score_values.each do |v|
    result  = @moves.values_at(v[0], v[1], v[2])
    if result.include?("#{check_moves_of}") && result.count("#{check_moves_of}") == 2
      result.delete("#{check_moves_of}")
      if result.first == "#{replace_with}"
        @move = nil
      else
        @move = result.first
      end
    end
  end
  @move
end

#boardObject



217
218
219
# File 'lib/tictactoe.rb', line 217

def board
  (0..8).each_slice(3).to_a
end

#competitor_best_moveObject



194
195
196
# File 'lib/tictactoe.rb', line 194

def competitor_best_move
  best_move('O', 'X')
end

#competitor_playsObject



67
68
69
70
71
72
73
74
# File 'lib/tictactoe.rb', line 67

def competitor_plays
  if @continue
    puts @message
    move = gets.chomp
    play(move)
    @continue = continue_playing
  end
end

#computer_best_moveObject



190
191
192
# File 'lib/tictactoe.rb', line 190

def computer_best_move
  best_move('X', 'O')
end

#computer_movesObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/tictactoe.rb', line 105

def computer_moves
  temp_moves = @moves.clone
  temp_moves.delete("O")
  temp_moves.delete("X")
  if temp_moves.size == @moves.size
    @moves[4] = "X"
  elsif computer_best_move
    @computer_move = computer_best_move
    @moves[computer_best_move] = "X"
  elsif competitor_best_move
    @computer_move = competitor_best_move
    @moves[competitor_best_move] = "X"
  else
    indexes = temp_moves.inject([]) do |result, element|
      result << @moves.index(element)
      result
    end
    position_index = rand(0...indexes.size)
    values_position = indexes.values_at(position_index).first
    @computer_move = values_position
    @moves[values_position] = "X"
  end
end

#computer_playsObject



60
61
62
63
64
65
# File 'lib/tictactoe.rb', line 60

def computer_plays
  if @playing
    computer_moves
    @continue = continue_playing
  end
end

#continue_playingObject



76
77
78
79
80
81
82
# File 'lib/tictactoe.rb', line 76

def continue_playing
  if (play_until_win || play_until_draw)
    false
  else
    true
  end
end

#display_boardObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/tictactoe.rb', line 129

def display_board
  board = ""
  @moves.each_with_index do |move, index|
    case move
    when 'X'
      color_moves = "#{move}".purple
    when 'O'
      color_moves = "#{move}".yellow
    else
      color_moves = "#{move}"
    end
    new_line = (index == 3 || index == 6) ? "\n" : ""
    board += new_line + color_moves
    board += "|"
  end
  puts "#{board}"
end

#generate_diagonal(board) ⇒ Object



209
210
211
212
213
214
215
# File 'lib/tictactoe.rb', line 209

def generate_diagonal(board)
  diagonals = []
  board.each_with_index do |element, index|
    diagonals << element[index]
  end
  diagonals
end

#get_valuesObject



168
169
170
171
172
173
# File 'lib/tictactoe.rb', line 168

def get_values
  score_values.inject([]) do |result, v|
    result << @moves.values_at(v[0], v[1], v[2]).uniq
    result
  end
end

#interactiveObject



55
56
57
58
# File 'lib/tictactoe.rb', line 55

def interactive
  puts 'Do you want to play first? enter y/n and q to quit'.purple
  @start_game = gets.chomp
end

#is_numeric(move) ⇒ Object



221
222
223
# File 'lib/tictactoe.rb', line 221

def is_numeric(move)
  move.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

#play(move) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/tictactoe.rb', line 84

def play(move)
  if move.size > 1
    @playing = false
    @message = "Please enter appropriate move".red
    puts @message
  elsif @moves.values_at(move.to_i).first == "X" || @moves.values_at(move.to_i).first == "O"
    @playing = false
    @message = "Please choose another move, it's already taken".red
    puts @message
  elsif !is_numeric(move)
    @playing = false
    @message = "Please enter correct move".red
    puts @message
  else
    position = @moves.index(move.to_i)
    @playing = true
    @message = "Please enter your move".blue
    @moves[position] = "O"
  end
end

#play_gameObject



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/tictactoe.rb', line 13

def play_game
  play_tictactoe
  if play_until_win
    who_won = winner.first == 'X' ? 'Computer' : 'You'
    puts '********************'
    display_board
    puts "#{who_won} Won".neon
  elsif play_until_draw
    puts '********************'
    display_board
    puts "It's a draw".neon
  end
end

#play_tictactoeObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/tictactoe.rb', line 27

def play_tictactoe
  display_board
  @start_game = interactive
  while @continue
    print "\e[2J\e[f" # clear screen
    case @start_game
    when 'y'
      display_board
      competitor_plays
      break if !@continue
      computer_plays
      break if !@continue
    when 'q'
      break
    when 'n'
      computer_plays
      display_board
      break if !@continue
      competitor_plays
      break if !@continue
    else
      display_board
      puts 'Please enter appropriate options'.red
      interactive
    end
  end
end

#play_until_drawObject



161
162
163
164
165
166
# File 'lib/tictactoe.rb', line 161

def play_until_draw
  unmoved = @moves.select do |move|
    (0..10).include?(move)
  end
  !(unmoved.any?)
end

#play_until_winObject



153
154
155
156
157
158
159
# File 'lib/tictactoe.rb', line 153

def play_until_win
  if winner
    true
  else
    false
  end
end

#score_valuesObject



198
199
200
201
202
203
204
205
206
207
# File 'lib/tictactoe.rb', line 198

def score_values
  rows = board
  columns = rows.transpose
  columns.each do |column|
    rows.push(column)
  end
  rows.push(generate_diagonal(board))
  rows.push(generate_diagonal(board.reverse))
  rows
end

#winnerObject



147
148
149
150
151
# File 'lib/tictactoe.rb', line 147

def winner
  get_values.detect do |value|
    value.one?
  end
end