[QUIZ] Lisp Game (#49)

R

Ruby Quiz

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

There's been quite a bit of discussion lately about how much Ruby is and isn't
like Lisp. While I've known of Lisp for some time now, I have never really
taken the time to play with it until just recently. I started with this great
tutorial:

http://www.lisperati.com/casting.html

Of course, just reading it didn't tell me all about the differences between Ruby
and Lisp, so I decided to translate it to Ruby. That taught me a lot, so I
thought I would share.

This week's Ruby Quiz is to translate the game built in the above tutorial into
the equivalent Ruby.

The tutorial is very interactive, so you should probably target irb as your
platform. (I did.) Don't worry about the prose here, we're just translating
the code from the tutorial.

I would say there are probably two extremes for how this can be done. You can
basically choose a direct command-for-command translation or decide to keep the
premise but translate the code to typical Ruby constructs. I think there's
merit to both approaches. I took the direct translation route for instance, and
I had to do a fair bit of thinking when I hit the section on Lisp's macros. On
the flip side, I think it would be great too wrap all the data in Ruby's objects
and use the tutorial to show off concepts like Ruby's open class system. So aim
for whatever approach interests you.
 
J

Joe Van Dyk

Holy crap, this looks cool. Very interested in seeing what comes out of it=
 
J

James Edward Gray II

Holy crap, this looks cool. Very interested in seeing what comes
out of it.

Thanks. It's a James Original Ideas(tm) and we all know those can be
a little rocky. ;)

Seriously, I hope people will give it a try. It's a beginning Lisp
tutorial, so you don't need to know it going in. It didn't take me
much longer to do than it did to read the tutorial itself. Besides
all that, it's downright fun code to play with.

Interesting Fact: My translation was used at a .rb group meeting
last night to expose Ruby neophytes to the language and I hear it
went well.

James Edward Gray II
 
G

Gregory Brown

James said:
Interesting Fact: My translation was used at a .rb group meeting
last night to expose Ruby neophytes to the language and I hear it
went well.

It went EXCELLENT!

There is nothing quite like seeing a room full of people's eyes light
up and say... ooh this would be so much uglier in Java / VB / C / Etc.

Even our python guy was like, some of the stuff James did would be hard
to do as elegantly and python. So... eat that, snake charmers!

Anyway, it was a great example and next week's meeting goal will be
porting the tutorial to something object oriented in nature.

Anyway, thanks to James and I certainly encourage anyone to try this
out, because my group loved it!
 
G

Gregory Brown

James said:
Interesting Fact: My translation was used at a .rb group meeting
last night to expose Ruby neophytes to the language and I hear it
went well.

It went EXCELLENT!

There is nothing quite like seeing a room full of people's eyes light
up and say... ooh this would be so much uglier in Java / VB / C / Etc.

Even our python guy was like, some of the stuff James did would be hard
to do as elegantly in python. So... eat that, snake charmers!

Anyway, it was a great example and next week's meeting goal will be
porting the tutorial to something object oriented in nature.

Anyway, thanks to James and I certainly encourage anyone to try this
out, because my group loved it!
 
G

Gregory Brown

Here is my solution, which is basically Jame's solution, but split into
a few files.

You can optionally turn on and off the method_missing trick by choosing
to require or not require "interactive"

adventure.rb (general game functions / direct translation with a couple
extra aliases):

http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/adventure.rb

interactive.rb (method missing trick)

http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/interactive.rb

game.rb (The wizard game)
http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/game.rb

I take no credit for Jame's code, just figured I'd share this for those
of you who wanted to play with what james made without cutting up the
Lisp / Perl file.
 
G

Gregory Brown

Here is my solution, which is basically Jame's solution, but split into
a few files.

You can optionally turn on and off the method_missing trick by choosing
to require or not require "interactive"

adventure.rb (general game functions / direct translation with a couple
extra aliases):

http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/adventure.rb

interactive.rb (method missing trick)

http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/interactive.rb

game.rb (The wizard game)
http://stonecode.org/organizations/unh.rb/code/meetings/2005.09.29/game.rb

I take no credit for Jame's code, just figured I'd share this for those
of you who wanted to play with what james made without cutting up the
Lisp / Ruby file.
 
S

soxinbox

I think the fun of these games ( especially when they first came out ) was
that it didn't seem like you were interacting with a computer. Thus some of
the fun is ruined when you have to type 'bucket-of-water' instead of 'bucket
of water'. The limited 'world' of this game also seemed contrived to fit the
program rather than having the program fit the 'world'.
I decided to go pure Ruby instead of writing Ruby methods to handle the LISP
formulas. I didn't think the original LISP was very readable, and so any
Ruby interpretation of it would be equally obfuscated.
So here is a short version with no ( that's right! zero ) added classes.
Just a big multi dimensional array to hold the data and a few methods to
implement the game.
Neat features include natural language handling: Try typing 'weld the bucket
to the chain' or 'dunk the drunken wizard with a bucket of water'. Also has
more detailed error messages that are particular to the verb. This adds
realism to the game, and is hard to get when all the verb methods are joined
into one generic method like in the LISP program. This generalization of
methods is almost always a good programming technique, but it takes away
from the realism in this particular type of game, so I avoided it. I also
gave each player a pet rock for added enjoyment.

#the wizard of 3 rooms
$map = [ ["living room","you are in the living-room of a wizard\'s house.
there is a wizard snoring loudly on the couch.",
["bottle of Jack Daniels","bucket"],
[["west","door","garden"],["upstairs","stairway","attic"]]],
["garden","you are in a beautiful garden. there is a well in front
of you.",
["chain","frog"],
[["east","door","living room"]]],
["attic","you are in the attic of the abandoned house. there is a
giant welding torch in the corner.",
[],
[["downstairs","stairway","living room"]]] ]
$location = "living room"
$knapsack = ["pet rock"]
$Commands = %w{look inventory get walk weld fill dunk }

def look(command)
myroom = $map.assoc($location)
print "#{myroom[1]}\n"
myroom[2].each{|item| print "There is a #{item} on the floor\n"}
myroom[3].each{|route|
print "There is a #{route[1]} going #{route[0]} from here\n"
}
end
def inventory(command)
if $knapsack.length == 0
print "you have nothing in your knapsack\n"
else
$knapsack.each{|item| print "you have a #{item} in your knapsack\n"}
end
end
def get(command)
if command.length < 2
print "get what?\n"
else
command.shift
object = command.join(" ")
if $map.assoc($location)[2].include?(object)
$knapsack << object
$map.assoc($location)[2].delete(object)
print "you now have a #{object}\n"
else
print "you can't get #{object}\n"
end
end
end
def walk(command)
if command.length <2
print "pacing..\n"
elsif (route = $map.assoc($location)[3].assoc(command[1])) == nil
print "you can't go #{command[1]} from #{$location}\n"
else
$location = route[2]
look(["look"])
end
end
def go(command)
walk(command)
end
def weld(command)
if not command.include?("chain") or not command.include?("bucket")
print "I don't understand!, Weld what to what?\n"
elsif $location != "attic"
print"There is no welder here\n"
elsif $knapsack.include?("chain") and $knapsack.include?("bucket")
$knapsack.delete("bucket")
$knapsack.delete("chain")
$knapsack << "bucket on a chain"
else
print"You need a bucket and a chain to do that\n"
end
end
def fill(command)
if $location != "garden"
print"There is no water here\n"
elsif not command.include?("bucket")
print "I don't understand!, What do you want to fill?\n"
elsif $knapsack.include?("bucket")
print "The water is to far down to reach with the bucket\n"
elsif $knapsack.include?("bucket on chain")
$knapsack.delete("bucket on chain")
$knapsack << "bucket of water on chain"
print"You now have a bucket of water on a chain\n"
elsif $knapsack.include?("bucket of water on chain")
print"The bucket is already full\n"
else
print"You have nothing to fill\n"
end
end
def dunk(command)
if not $knapsack.include?("bucket of water on chain")
print"you have no water\n"
elsif not command.include?("wizard")
print "splash\n"
elsif $location != "living room"
print "There is no wizard here\n"
elsif $knapsack.include?("frog")
print"The wizard is awoken. He sees you have stolen his frog. He
banishes you to Siberia\n"
print"You Lose\n"
abort
else
print"The wizard is awoken. He gives you the low carb donut (Yum!)
and you live happily ever after\n"
print"You Win\n"
abort
end
end

STDOUT.flush
command = ["look"]

while command[0] != "end"
if $Commands.include?(command[0])
eval command[0] + "(command)"
else
print "Huh?\n"
end
print "?"
STDOUT.flush
input = gets
command = input.split(" ")
puts command
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top