def play()
  # draw the inital (empty) game grid
  Canvas.init(90,90,"TicTacToe")

  grid = new_grid()
  display_grid(grid)
  player = 0

  9.times {
    # keep on asking for rows/columns until the user inputs a valid move
    # add a mark to the correct cell
    repeat = true
    while repeat == true do
      row = input_num("Player " + player.to_s + ": Which row (0-2)? ")
      col = input_num("Player " + player.to_s + ": Which column (0-2)? ")

      if add_mark!(grid, row, col, player) then
        repeat = false
      else
        puts "Grid position (row=" + row.to_s + ", column=" + col.to_s +
          ") is already occupied."
      end
    end

    # redisplay grid with new mark
    display_grid(grid)

    if check_win(grid) then
      puts "Player " + player.to_s + " won!"
      return
    end

    # alternate between player 0 and player 1
    player = (player + 1) % 2
  }

  # If no-one wins in 9 moves, the game is a tie.
  puts "The game ended in a tie."
end


# input_num(prompt)
# This function gets user input and normally returns 0, 1, or 2 based on
# the input.  If, however, the user enters the word "quit", it raises an 
# exception, which causes the program to stop immediately.
def input_num(prompt)
  while true do
    s = Readline::readline(prompt).chomp
    raise "quit" if s == "quit"
    return 0 if s == "0"
    return 1 if s == "1"
    return 2 if s == "2"
    print "input must be a number between 0 and 2 (inclusive)", "\n"
  end
end


# This is a stub definition of new_grid.
# you should replace it's body with actual code
def new_grid()
  return nil
end


# This is a stub definition of add_mark
# you should replace it's body with actual code
def add_mark!(grid, row, col, player)
  return nil
end


# This is a stub definition of display_grid.
# You should replace it's body with actual code.
def display_grid(grid)
  return nil
end


# This is a stub definition of check_win_horiz
# You should replace it's body with actual code.
def check_win_horiz(grid, row)
  return false
end


# This is a stub definition of check_win_vert
# You should replace it's body with actual code.
def check_win_vert(grid, column)
  return false
end


# This is a stub definition of check_diagonal1
# You should replace it's body with actual code.
def check_win_diagonal1(grid, column)
  return false
end


# This is a stub definition of check_diagonal2
# You should replace it's body with actual code.
def check_win_diagonal2(grid, column)
  return false
end


# This is a stub definition of check_win.
# You should replace it's body with actual code
def check_win(grid)
  return false
end
