Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [Solution] Lisp Game #49

Reply
Thread Tools

[Solution] Lisp Game #49

 
 
Sean O'Halpin
Guest
Posts: n/a
 
      10-06-2005
I wasn't going to finish this but somehow I couldn't stop myself....

It's not tested & debugged but I had to post it before I spent way too
much time on it.

Now if I can integrate it with IFMapper...

---- CODE ---

#$DEBUG_GAME =3D true
def dbg(*args)
puts *args if $DEBUG_GAME
end

class Object
def in?(container)
container.include?(self)
end
end

module Attributes
def has(*names)
self.class_eval {
names.each do |name|
# with args =3D setter
# without =3D getter
define_method(name) {|*args|
if args.size > 0
instance_variable_set("@#{name}", *args)
else
instance_variable_get("@#{name}")
end
}
# also define traditional setter=3D
define_method("#{name}=3D") {|*args|
instance_variable_set("@#{name}", *args)
}
end
}
end

end

module Directions
def directions(*directions)
directions.each do |name|
self.class.class_eval {
define_method(name) {
go(name)
}
}
end
end
end

class GameObject
extend Attributes
has :identifier, :name, :description
def initialize(identifier, &block)
@identifier =3D identifier
instance_eval &block
end
end

class Thing < GameObject
has :location, ortable

def initialize(identifier, &block)
# put defaults before super - they will be overridden in block (if at a=
ll)
# e.g. light, dark, etc.
@portable =3D true
super
end

end

class Room < GameObject
has :exits
end

class Game
include Directions

attr_accessor :name, :rooms, :location, :things

def initialize(name, &block)
@name =3D name
@rooms =3D {}
@things =3D {}

# read game definition
instance_eval &block

end

def room(identifier, &block)
@rooms[symbol(identifier)] =3D Room.new(symbol(identifier), &block)
end

def thing(identifier, &block)
@things[symbol(identifier)] =3D Thing.new(symbol(identifier), &block)
end

def match_thing(*identifiers)
thing =3D nil
identifiers.each do |identifier|
if thing =3D @things[identifier]
break
end
end
thing
end

def symbol(s)
s.to_s.to_sym
end

def start(room_identifier)
@location =3D @rooms[room_identifier]
end

def display_list(things)
if things.size > 2
things[0..-2].join(", ") + " and " + things[-1]
else
things.join(" and ")
end
end

def describe_path(direction, path)
"a #{path} going #{direction}"
end

def describe_exits(location)
"There is " + display_list(location.exits.map {|direction, (path,
destination)|
describe_path(direction, path)
}) + "."
end

def describe_floor(location)
things =3D @things.select{|key, thing| thing.location =3D=3D location.i=
dentifier}
if things.size > 0
"You can also see " + display_list(things.map{|key, thing| "a
#{thing.name}"}) + "."
else
""
end
end

def main_loop
print "> "
while input =3D gets
input.chomp!
case input
when 'exit', 'quit'
break
when 'help'
puts "Sorry pal! You're on your own here "
else
begin
#puts "#{input}"
tokens =3D input.split
cmd =3D tokens[0]
rest =3D tokens[1..-1].map{|x| x.to_sym}.reject{|x| x.in?
[:the, :to, n, :in, :a, :with]}
instance_eval { send(cmd, *rest) }
rescue Exception =3D> e
dbg e.to_s
puts "Eh?"
end
end
print "> "
end
end

# commands taking symbols

def in_location(location_id, thing_id)
@things[thing_id].location =3D=3D location_id
end

def is_here(thing_id)
in_location(@location.identifier, thing_id)
end

def player_has(thing_id)
in_location(layer, thing_id)
end

def player_in(location_id)
@location.identifier =3D=3D location_id
end

def move_to(location_id, thing_id)
@things[thing_id].location =3D location_id
end

def move_here(thing_id)
move_to(@location.identifier, thing_id)
end

def destroy(thing_id)
move_to(:nowhere, thing_id)
end

def pick_up(thing_id)
move_to(layer, thing_id)
end

# verbs

def look
puts location.description
puts describe_exits(location)
puts describe_floor(location)
end

def go(direction)
dest =3D @location.exits[direction]
if dest
@location =3D @rooms[dest[1]]
look
else
puts "You can't move in that direction"
end
end
alias :walk :go

def inventory
carried =3D @things.select{|key, thing| player_has(thing.identifier)}
puts "You are carrying " +
if carried.size > 0
"a #{display_list(carried.map{|key, thing| thing.name})}"
else
"nothing"
end
end
alias :i :inventory

def get(*args)
if thing =3D match_thing(*args)
if is_here(thing.identifier)
if thing.portable
pick_up(thing.identifier)
puts "OK - you picked up the #{thing.name}"
else
puts "You try and you try but you just can't pick up the
#{thing.name}"
end
else
puts "You can't see a #{thing.name} here"
end
else
puts "Get what?"
end
end
alias :take :get

def drop(*args)
if thing =3D match_thing(*args)
if player_has(thing.identifier)
move_here(thing.identifier)
puts "OK - you dropped the #{thing.name}"
else
"You're not carrying a #{thing.name}"
end
else
puts "Drop what?"
end
end

def examine(*args)
if obj =3D match_thing(*args)
if is_here(obj.identifier)
puts "Looks like #{obj.description}"
else
puts "You can't see that here"
end
else
puts "Don't know what you're talking about"
end
end
alias :exam :examine

end

def game(name, &block)
puts "Welcome to #{name}\n\n"
g =3D Game.new(name, &block)
g.look
g.main_loop
end

# Game definition

game "Ruby Adventure" do

directions :east, :west, :north, :south, :upstairs, :downstairs
alias :up :upstairs
alias :down :downstairs

# rooms

room :living_room do
name 'Living Room'
description "You are in the living-room of a wizard's house. There
is a wizard snoring loudly on the couch."
exits :west =3D> [:door, :garden],
:upstairs =3D> [:stairway, :attic]
end

room :garden do
name 'Garden'
description "You are in a beautiful garden. There is a well in
front of you."
exits :east =3D> [:door, :living_room]
end

room :attic do
name "Attic"
description "You are in the attic of the wizard's house. There is
a giant welding torch in the corner."
exits :downstairs =3D> [:stairway, :living_room]
end

start :living_room

# things

thing :wizard do
name "wizard"
description "a typical wizard - pointy hat, wand, unkempt beard,
smelly feet"
location :living_room
portable false
end

thing :self do
name "Yourself"
description "your same ol' ugly self"
portable false
end

thing :bottle do
name 'whiskey bottle'
description 'a half-empty whiskey bottle'
location :living_room
end

thing :bucket do
name 'bucket'
description 'a rusty bucket'
location :living_room
end

thing :welded_bucket do
name "bucket"
description "a bucket with a chain welded to it"
location :nowhere
end

thing :filled_bucket do
name "bucket"
description "a bucket full of water with a chain welded to it"
location :nowhere
end

# chain
thing :chain do
name 'chain'
description 'a sturdy iron chain'
location :garden
end

thing :frog do
name 'frog'
description 'a wide-mouthed frog'
location :garden
end

# verbs

def splash(*args)
thing, *rest =3D *args
if thing =3D=3D :wizard and player_in(:living_room) and
player_has(:filled_bucket)
if player_has(:frog)
puts "The wizard awakens and sees that you stole his frog. He
is so upset he banishes you to the netherworlds - you lose! The end."
break
else
puts "The wizard awakens from his slumber and greets you
warmly. He hands you the magic low-carb donut - you win! The end."
break
end
elsif thing =3D=3D :bucket
puts "The bucket has nothing in it"
else
puts "With what?"
end
end

def attach(*args)
subject, object, *rest =3D *args
if [subject, object].in?([[:chain, :bucket], [:bucket, :chain]])
and player_in(:attic) and player_has(:bucket) and player_has(:chain)
destroy(:bucket)
destroy(:chain)
pick_up(:welded_bucket)
puts "The chain is now securely welded to the bucket."
else
puts "Interesting..."
end
end
alias :weld :attach

def fill(*args)
thing, *rest =3D *args
if thing =3D=3D :bucket and player_in(:garden) and player_has(:welded_b=
ucket)
destroy(:welded_bucket)
pick_up(:filled_bucket)
puts "You have filled the bucket with water"
elsif thing =3D=3D :bucket
if player_in(:garden)
puts "You can't reach the water in the well. You'll need
something to lower the bucket down"
elsif player_has(:bucket)
puts "Fill it with what?"
else
puts "You don't have the bucket!"
end
else
puts "Hmmmm...."
end
end
alias :dunk :fill

end

__END__
get bucket
go west
get chain
east
upstairs
weld chain to bucket
down
west
fill bucket
east
splash wizard

--- END CODE ---

Regards,

Sean


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Nice historical Musical - VERY RELAXING - about LISP history -fundamental ideas of LISP nanothermite911fbibustards C++ 0 06-16-2010 09:47 PM
Nice historical Musical - VERY RELAXING - about LISP history -fundamental ideas of LISP nanothermite911fbibustards Python 0 06-16-2010 09:47 PM
Calling Common Lisp Game Developers jobs@omacindustries.com Python 0 09-08-2008 04:55 PM
Calling Common Lisp Game Developers jobs@omacindustries.com Python 0 09-08-2008 04:51 PM
pat-match.lisp or extend-match.lisp in Python? ekzept Python 0 08-10-2007 06:08 PM



Advertisments