Skip to content

Instantly share code, notes, and snippets.

@stevenleeg
Created April 11, 2019 19:14
Show Gist options
  • Save stevenleeg/73634f2fad612a2daae5b627d75344e8 to your computer and use it in GitHub Desktop.
Save stevenleeg/73634f2fad612a2daae5b627d75344e8 to your computer and use it in GitHub Desktop.
Tic tac toe, in Ruby!
# A nice helper
class String
def is_number?
true if Float(self) rescue false
end
end
class Board
def initialize
@board = [
[nil, nil, nil],
[nil, nil, nil],
[nil, nil, nil],
]
@moves = 0
end
def mark(team, x, y)
# Some validation
throw :err, "Invalid team specified to mark!" if ![:x, :o].include?(team)
throw :err, "Space already taken" if @board[y][x] != nil
throw :err, "Invalid space" if x < 0 || y < 0 || x >= @board.length || y >= @board.length
@board[y][x] = team
@moves += 1
# Check for any endgame states, starting with the row
([email protected]).each do |check_x|
break if @board[y][check_x] != team
return team if check_x == @board.length - 1
end
# Column
([email protected]).each do |check_y|
break if @board[check_y][x] != team
return team if check_y == @board.length - 1
end
# Diagonal
if x == y
([email protected]).each do |check_n|
break if @board[check_n][check_n] != team
return team if check_n == @board.length - 1
end
end
# Draw?
if @moves == @board.length ** 2
return false
end
return nil
end
def to_s
marks = {nil => " ", :x => "X", :o => "O"}
@board.inject("") do |row_str, row|
str = row.each.inject("") do |col_str, col|
"#{col_str}[#{marks[col]}] "
end
"#{row_str}#{str}\n"
end
end
end
b = Board.new
puts "Let's play a game of tic tac toe!"
active_team = :x
while true
puts "\n#{b.to_s}"
puts "#{active_team} is up. Enter a comma separated coordinate pair:"
x, y = gets.split(",")
if !x.is_number? || !y.is_number?
puts "Invalid coordinate!"
next
end
end_state = nil
error_msg = catch :err do
end_state = b.mark(active_team, x.to_i, y.to_i)
nil
end
if !error_msg.nil?
puts error_msg
next
elsif end_state == false
puts b.to_s
puts "Drat! There was a draw."
break
elsif !end_state.nil?
puts b.to_s
puts "#{end_state} wins!"
break
end
# Toggle teams
active_team = active_team == :x ? :o : :x
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment