Session 7

Writing Methods

Methods are used to package up code for reuse. They are sometimes used to reorganize or "self-comment" code.

The keyword 'def' starts a method definition. You must define methods before you can use them.

def say_hello
  puts "Hello!"
end
 
say_hello

Methods can take parameters (aka arguments). These are tell the method how to do its job. Parameters can be any object and you can have as many as you like.

def say_hello2(name)
  puts "Hello, #{name}"
end
 
def greet_room(names)
  names.each do |name|
    say_hello2(name)
  end
end
 
say_hello2('Ed')
greet_room( ['Anne','Bennie','Chad'] )

Methods can return values. They return the result of the last expression they evaluate or whatever you tell them to return

def max(a,b)
  a >= b ? a : b
end
 
def min(a,b)
  if a <= b
    return a
  else
    return b
  end
end
 
high = max(5,10)
low = min(5,10)

You'll notice that sometimes I put parens around the parameters and sometimes I don't. They are optional in Ruby (usually). I usually only use them for clarity.

Local Variables

Methods can have their own variables. These variables only exist inside the method. They are said to be local variables because they are local to the method. If you have a global (outside the method) variable with the same name as a method's local variable, the method's local variable "masks" or hides the global variable. This can sometimes be confusing. So try not to use different names.

def double(number)
  times_two = number * 2
  puts "double #{number} is #{times_two}"
end
 
number = 10
double(number)
puts times_two # this throws an error
 
# now go back set times_two to 500 above the double method definition and see what happens

Tic Tac Toe

def new_board
  return [['-','-','-'],['-','-','-'],['-','-','-']]
end
 
def make_move(board, square, player)
  row, column = square_to_row_column square
  # puts row.to_s + " " + column.to_s
  board[row][column] = player
end
 
def print_board(board)
  puts board[0].join('|')
  puts board[1].join('|')
  puts board[2].join('|')
  puts
end
 
def print_help
  help = [[1,2,3],[4,5,6],[7,8,9]]
  print_board help
end
 
def valid_move?(square, board)
  row, column = square_to_row_column square
 
  if board[row][column] == '-'
    return true
  else
    return false
  end
end
 
def square_to_row_column(square)
  row = (square - 1).div 3  # I didn't use slash for division here because of the wiki markup
  column = (square - 1) % 3
  return row, column
end
 
def board_full?(board)
  if board.flatten.include?('-')
    return false
  else
    return true
  end
end
 
def check_for_winner(board)
 
  [0,1,2].each do |index|
 
    # check for row wins
    if board[index][0] != '-' && board[index][0] == board[index][1] && board[index][1] == board[index][2]
      return board[index][0]
 
    # check for column wins
    elsif board[0][index] != '-' && board[0][index] == board[1][index] && board[1][index] == board[2][index]
      return board[0][index]
    end
  end
 
  # check for 1 5 9 diagonal win
  if board[0][0] != '-' && board[0][0] == board[1][1] && board[1][1] == board[2][2]
    return board[0][0]
  end
 
  # check for 3 5 7 diagonal win
  if board[0][2] != '-' && board[0][2] == board[1][1] && board [1][1] == board[2][0]
    return board[0][0]
  end
 
  # check for tie
  if board_full?(board)
    return 'cat'
  end
 
  # nobody's won yet
  return nil
end 
 
def prompt_x_or_o
  player = nil
  while player.nil? || (player.upcase != 'X' && player.upcase != 'O')
    puts "Do you want X or O?: "
    player = gets.chomp
  end
  puts
  return player.upcase
end
 
def prompt_new_game
  puts "Play again? (Type y for yes): "
  answer = gets.chomp
  puts
  if answer.downcase == 'y'
    return true
  else
    return false
  end
end
 
def prompt_move
    puts "Pick a square: "
    move = gets.chomp.to_i
    puts
    return move
end
 
def random_move(board)
  move = rand(9) + 1
  while !valid_move?(move, board)
    move = rand(9) + 1
  end
 
  return move
end
 
# main program
 
keep_playing = true
while keep_playing == true
 
  board = new_board
  player = prompt_x_or_o
  computer = player == 'X' ? 'O' : 'X'
 
  winner = nil
  while winner.nil?
    print_board board
    print_help
 
    player_move = prompt_move
    while valid_move?(player_move, board) == false
      player_move = prompt_move
    end
 
    make_move board, player_move, player
 
    # see if player has just won
    winner = check_for_winner board
    break if !winner.nil?
 
    # otherwise let the computer move
    computer_move = random_move board
    make_move board, computer_move, computer
 
    winner = check_for_winner board
  end
 
  puts "Winner: #{winner}"
  puts
  print_board board
  keep_playing = prompt_new_game
end
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License