rubymultiple-choice

stuck on a multiple choice game on ruby


I am just starting with ruby and tried to create a multiple choice game. I can't seem to see where i get something wrong which makes it so that it either repeats the generic line for a room instead of showing the resulting option.

just for info, the options in the hall are either "north", "look" or "quit" then in the study, options are "look", "look at desk", "south", "quit", "enter combination 2451"

code below:

def hall_begin
#first line you see
  puts "you can either look around or move north"
  gets.chomp
end

def look_hall
# first option to look around in the hall
  puts "You are standing in a hall with a marble floor. You see a door."
  hall_begin
end

def onwards_study
# second option to go forwards into the next room from the hall
  puts "You are in the study, you can either look around of move back south"
  gets.chomp
end

def back_to_hall
# moving back into the hall from the study
  puts "You are back in the hall, either look around or go north"
  gets.chomp
end

def look_study
# looking around the study to find the desk and safe
  puts "You are in a warm and cosy study. You see a safe. You see a desk."
  onwards_study
end

def study_desk
# looking on the study desk to find the combination
  puts "You see a piece of paper that reads, The combination is 2451."
  onwards_study
end

def study_safe
# if you open the safe with combination
  puts "You see some diamonds in the safe, pick them up and make your escape"
end


def first_choice
# all the choices whilst in the hall
  while true
    direction_1 = hall_begin
    if direction_1 == "look"
      look_hall
    elsif direction_1 == "north"
      onwards_study
    elsif direction_1 == "quit"
      break
    end
  end
end

while true
# start of the game
  first_choice
    while true
    # all choices you face whilst in the study
        direction_2 = onwards_study
        if direction_2 == "look"
          look_study
        elsif direction_2 == "south"
          back_to_hall
        elsif direction_2 == "look at desk"
          study_desk
        elsif direction_2 == "enter combination 2451"
          study_safe
          break
        elsif direction_2 == "quit"
          break
        end
    break
    end
end

Solution

  • As Chandan pointed out, having this many loops is unnecessary. I think what you are after can be achieved by having one main loop that gets the user input and then handles it.

    I don't want to make too complicated suggestions to begin with since you are just starting out, but I think keeping track of a "current_room" variable is helpful (which can later transition into coordinates on a 2D room array or something).

    Too give you a few examples, this is how something similar could be achieved.

    def describe_room(current_room)
      if current_room == "hall"
        puts "You are standing in the hall, either look around or go north"
      elsif current_room == "study"
        puts "You are in the study, you can either look around of move back south"
      end
    end
    
    def examine_room(current_room)
      if current_room == "hall"
        puts "You are standing in a hall with a marble floor. You see a door."
      elsif current_room == "study"
        puts "You are in a warm and cosy study. You see a safe. You see a desk."
      end
    end
    
    def move(current_room, direction)
      if current_room == "hall" and direction == "north"
        "study"
      elsif current_room == "study" and direction == "south"
        "hall"
      else
        puts "You cannot go that way"
        current_room
      end
    end
    
    def hall_commands(command)
      # No hall specific commands at this points
      puts "Unknown command"
    
      # Return "hall" since we are never moving anywhere else
      "hall"
    end
    
    def study_commands(command)
      if command == "look at desk"
        puts "You see a piece of paper that reads, The combination is 2451."
    
      elsif command == "enter combination 2451"
        puts "You see some diamonds in the safe, pick them up and make your escape"
        return nil # Use explicit return statement to avoid default return at the end of the method
    
      else
        puts "Unknown command"
      end
    
      # Return "study" as the default
      "study"
    end
    
    # Starting position
    current_room = "hall"
    
    while true
      break if current_room == nil
    
      # Start each loop by a brief description of the current room.
      describe_room(current_room)
    
      # Get the user input in the main loop
      command = gets.chomp
    
      # Check for global commands (i.e. movements, look, etc.) first
      # and then move on to check for room specific commands. 
      if command.in?(["north", "east", "south", "west"])
        current_room = move(current_room, command)
    
      elsif command == "look"
        examine_room(current_room)
    
      elsif command == "quit"
        break
    
      elsif current_room == "hall"
        current_room = hall_commands(command)
    
      elsif current_room == "study"
        current_room = study_commands(command)
      
      else
        puts "Unknown command"
      end
    end
    

    Basically I have simplified it into one loop as mentioned earlier, then split up the "global commands" that could be used regardless which room your are in, and the "room specific commands" that only apply in certain rooms.

    I hope this helps you getting into Ruby. When you feel more comfortable, I would recommend looking into case/when statements as an alternative to if/elsif/else statements and also Arrays to keep track of rooms and positions.