Tuesday, October 11, 2011

Calling a method in another method in Ruby

I've hit another turning point in my work with Ruby. I've slowly been getting more and more excited about coding, but this week marks the point that sitting down to code seems like something that's fun to do and not just something I kind of enjoy doing that I'm working on because I'm interested in a career change.

I had a really good day with the project I'm currently working on as part of Learn Ruby the Hard Way: a text-based adventure. It's a pretty simple concept, but so far I've got a working four room dungeon. And it's a game! Sure, it's a basic, text based game, not even as complicated as Zork, but it works! Do you know how awesome it feels to build something that works? REALLY AWESOME.

Today at work I was thinking of ways to expand it. How about adding a "help" command to give players some commands that will allow them to manipulate objects in the dungeon? How about a "look" command to remind players which room they're in and to point out important features of that room? How about a "quit" command to let players quit the game?

Done, done and done. Pretty easy: these were all just matters of defining methods and then calling them within the methods I've defined for the various rooms. For example, here's the "help" method I made:

def help()
  puts "Here's a list of handy commands to help you in your quest:"
  puts "Open: open doors, chests, your heart, etc."
  puts "Look: get a description of the room you're in."
  puts "Take: take an item and add it to your inventory."
  puts "Inventory: see what items you're carrying."
  puts "Quit: quit the game, as a coward would."

And then I wire it up in each of my room methods, so in the torch_room method, I use this code to allow a player to call up the Help menu:

if next_move == "help"
  prompt; next_move = gets.chomp

As I may have mentioned before, I don't have much coding experience with other languages, so I don't know how easy it is to add functionality, but it's really easy with Ruby, and that's part of what I love about it. I'm having a ton of fun with this little project, and while I did a similar project when I was working through Beginning Ruby, those were different times. It was a matter of simply copying code at that point and not understanding what I could do with Ruby and how to make it do what I want it to.

I'm not saying I've mastered Ruby (not by a long shot!) but I'm definitely getting better and it's getting more fun the more I learn. My goal is to keep working on this dungeon for a few more days, expanding the number of rooms, adding monsters and traps, coming up with an inventory system and so on before I move forward with Learn Ruby the Hard Way.

Monday, October 10, 2011

Scope issues with Ruby

I'm still working through Learn Ruby the Hard Way. The exercise I'm working on now has me building a text-adventure dungeon (similar to the one I made when I was going through Beginning Ruby) but this time around I've got a better idea of how to map the project out.

Basically I'm starting with a simple 4 room dungeon. Players will need to go to one room to get a key to unlock a door in the starting room. I understand how to build rooms and allow a player to navigate between them, but managing an inventory and allowing players to access different rooms once they have completed a specific action (such as finding a key to unlock the door) was confusing me.

After asking for some input on Stack Overflow, I think I've got a better handle on the problem now. I'd originally set door_open = false in the start_room method, then once a player had found the key in the chest_room method, I set door_open to true. However, I couldn't call this from the start_room, because it was a local variable. As far as start_room was concerned, door_open was still = false. Am I thinking about this the right way?

I'll simply make key into an instance variable, so it can be accessed by all methods, and edit the logic so while !@key_present, players can open the door. Easy enough! Just wish I could get to coding NOW instead of tonight.

Also, I've been using if/elsif statements, but the same user suggested case/when is cleaner and simpler. I haven't used case/when before, but from the snippet of code he posted, I think I agree. Your thoughts?