2

I understand how classes work and how to make them, but the 2nd extra credit of the exercice says to create a two-class version, in 2 different files.

I tried different things, but I can't figure out how to make it work...

I don't know if I'm not searching at the right places, but I can't find any help on that, nor find any solution...

If anyone could help me on that, it would be much appreciated :)

here is the exercice : http://ruby.learncodethehardway.org/book/ex42.html

What I have tried so far :

map.rb
class Map

with all the methods in here (death(), central_corridor(), etc.)

then

engine.rb
class Engine
require './map.rb'

  def initialize(start)
    @quips = [
      "You died. You kinda suck at this.",
      "Nice job, you died... jackass.",
      "Suck a luser."
    ]

    @start = start
    puts "in init @start = " + @start.inspect
  end

  def prompt()
    print "> "
  end

  def play()
    puts "@start => " + @start.inspect
    @next_room = @start

    while true
      puts "\n--------"
      room = method(@next_room)
      @next_room = room.call()
    end
  end

end

a_game = Engine.new(:central_corridor)
a_game.play()

So basically what I did is get the methods used for "actions" in the game (the rooms, death, etc.. and put them in a class Map in map.rb, and then called in engine.rb where i have my class Engine with the "general" methods/variables like prompt, play, start.

The error I get is

engine.rb:24:in `method': undefined method `central_corridor' for class `Engine'

I understand it means ruby tries to find a method "central_corridor" in the class engine, but it's in the class map in map.rb and I can't figure out what to do, either it's some variable modifications or just some things to add... :(

Jauny
  • 950
  • 1
  • 8
  • 19
  • 1
    Can you [edit] your post to include what you've tried and the error messages you get from your attempts? – sarnold Jun 21 '12 at 21:52
  • Don't `require` the map class *inside* the engine class, put that before the class declaration. But an `Engine` instance method (defined via `def` inside the `Engine` declaration) requires an instance of an `Engine` to execute. – Dave Newton Jun 21 '12 at 22:20
  • What do you mean by it requires an instance of an Engine to execute? The whole point of the exercise of having the 2 classes in 2 files is to use an instance of map while being in engine, I think... – Jauny Jun 21 '12 at 22:34

1 Answers1

2

The problem is that you don't have an instance of class Map, which is what you need to be able to call central_corridor. Add this into initialize:

@map=Map.new

And change room = method(@next_room) to room=@map.method(@next_room).


Although this isen't your question, I have a feeling that if Map never changes (you have methods for everything in the map), that you make all of the methods class methods and just use the class Map for your map. But by good design principles, you should probably make the map have a Hash of lambdas representing the areas. That way, you can have more than one map

Linuxios
  • 34,849
  • 13
  • 91
  • 116
  • Thanks a lot, the problem is solved ! But now i have another problem, which is the opposite :) /Users/Jonathan/Hardway/map.rb:20:in `central_corridor': undefined method `prompt' for # (NoMethodError) thanks a lot – Jauny Jun 21 '12 at 22:54
  • @Jauny: Glad to help. When you find an answer that solves your problem, you can click on the check under the vote count to accept the answer. – Linuxios Jun 21 '12 at 22:55
  • @Jauny: What are the return values of the `Map.central_corridor` method? Does it every return `:prompt`? – Linuxios Jun 22 '12 at 03:21
  • Don't worry, I put prompt into map.rb since it's where it is used, and it fixed it :) – Jauny Jun 22 '12 at 17:25