Skip to content

Instantly share code, notes, and snippets.

@adaedra
Last active January 9, 2016 23:15
Show Gist options
  • Save adaedra/61be79cb0c52d2a9d711 to your computer and use it in GitHub Desktop.
Save adaedra/61be79cb0c52d2a9d711 to your computer and use it in GitHub Desktop.
class TicTacToe
PLAYERS = 2
MARKERS = "×○"
COLOR_NUM = 7
def initialize
@game = Array.new(9)
@winner = nil
end
def play
player = 0
while @winner.nil?
turn player
player = (player + 1) % PLAYERS
end
show_grid
if @winner
puts "Congratulation, player #{@winner + 1}: you won!"
else
puts "No winner this time."
end
end
def turn(player)
show_grid
place_marker player
check_win
end
def place_marker(player)
puts "Player #{player + 1} (#{MARKERS[player]}) is on!"
sel = loop do
sel = get_input
break sel if is_valid?(sel)
$stderr.puts "This cell is either full or out of the map. Try another one."
end
mark_on_grid player, sel
end
def show_grid
rows = @game.map.with_index do |player, n|
if player
"\e[3#{player + 1}m#{MARKERS[player]}\e[0m"
else
"\e[3#{COLOR_NUM}m#{n + 1}\e[0m"
end
end.each_slice(3).map { |e| ([nil] + e + ["\n"]).join '|' }
puts ([nil] + rows + ["\n"]).join("+-+-+-+\n")
end
def mark_on_grid(player, sel)
@game[sel - 1] = player
end
def get_input
loop do
begin
$stdout.write "Your play: "
$stdout.flush
break Integer(gets.strip)
rescue ArgumentError
$stderr.puts "Invalid input."
end
end
end
def is_valid?(choice)
choice.between?(1, 9) && @game[choice - 1].nil?
end
def check_win
row_checker = lambda do |row|
if row.each_cons(2).all? { |a, b| a == b } && row.first
@winner = row.first
return
end
end
# Horizontal
@game.each_slice(3, &row_checker)
# Vertical
@game.each_slice(3).to_a.transpose.each(&row_checker)
# Diagonal
[[0,4,8],[2,4,6]].each do |e|
e.map { |i| @game[i] }.tap(&row_checker)
end
# All full
if @game.all?(&:itself)
@winner = false
end
end
end
TicTacToe.new.tap do |game|
game.play
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment