Along the same lines, as I am unlikely to pursue this any further,
here is my half-baked doodle towards a game DSL
You can move about (using 'east', 'west', 'upstairs', etc.) but nothing els=
e.
Regards,
Sean
-- CODE --
module Attributes
def has(*names)
self.class_eval {
names.each do |name|
define_method(name) {|*args|
if args.size > 0
instance_variable_set("@#{name}", *args)
else
instance_variable_get("@#{name}")
end
}
end
}
end
end
module Directions
def directions(*directions)
directions.each do |name|
self.class.class_eval {
define_method(name) {
dest =3D @location.exits[name]
if dest
@location =3D @rooms[dest[1]]
look
else
puts "You can't move in that direction"
end
}
}
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
end
class Room < GameObject
has :exits
def initialize(identifier, &block)
# put defaults before super - they will be overridden in block (if at a=
ll)
super
end
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 symbol(s)
s.to_s.to_sym
end
def start(room_identifier)
@location =3D @rooms[room_identifier]
end
def describe_path(direction, path)
"There is a #{path} going #{direction}."
end
def describe_exits(location)
location.exits.map {|direction, (path, destination)|
describe_path(direction, path)
}
end
def describe_floor(location)
@things.select{|key, thing| thing.location =3D=3D
location.identifier}.map{|key, thing| "There is a #{thing.description}
here."}
end
def main_loop
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
instance_eval input
rescue Exception =3D> e
puts e.to_s
puts "Eh?"
end
end
end
end
# commands
def look
puts location.description
puts describe_exits(location)
puts describe_floor(location)
end
def quit
break
end
end
def game(name, &block)
g =3D Game.new(name, &block)
g.look
g.main_loop
end
# Game definition
game "Ruby Adventure" do
directions :east, :west, :north, :south, :up, :down, :upstairs, :downstai=
rs
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
thing :whiskey_bottle do
name 'whiskey bottle'
description 'half-empty whiskey bottle'
location :living_room
end
thing :bucket do
name 'bucket'
description 'rusty bucket'
location :living_room
end
thing :chain do
name 'chain'
description 'sturdy iron chain'
location :garden
end
thing :frog do
name 'frog'
description 'green frog'
location :garden
end
start :living_room
end
-- END --