Skip to content

Instantly share code, notes, and snippets.

@jaymcgavren
Created February 5, 2024 06:31
Show Gist options
  • Save jaymcgavren/ea1ec730c4744c2f993e1259adf52a82 to your computer and use it in GitHub Desktop.
Save jaymcgavren/ea1ec730c4744c2f993e1259adf52a82 to your computer and use it in GitHub Desktop.
A prototype for a MUD where a Door blocks attempts to pass through a Way.
class ListenerQueue
attr_reader :listeners
def initialize
@listeners = []
end
def register(listener)
@listeners << listener
end
def share_message(receiver, method_name, args, kwargs)
@listeners.each do |listener|
return false unless listener.allow?(receiver, method_name, args, kwargs)
end
true
end
end
class Door
attr_accessor :state
def allow?(receiver, method_name, args, kwargs)
return true if method_name != :pass
if state == :closed
puts "The door blocks your way!"
return false
end
true
end
end
module MethodBroadcaster
def broadcast_calls_to(*method_names)
proxy = Module.new
method_names.each do |method_name|
proxy.define_method(method_name) do |*args, **kwargs, &block|
return false unless listener_queue.share_message(self, method_name, args, kwargs)
super(*args, **kwargs, &block)
end
end
self.prepend proxy
end
end
class Thing
attr_accessor :name
attr_accessor :current_area
def initialize(name:, current_area:)
@name, @current_area = name, current_area
end
end
class Area
attr_accessor :description
attr_accessor :things
attr_accessor :exits
def initialize(description: nil, things: [], exits: [])
@description, @things, @exits = description, things, exits
end
end
class Way
extend MethodBroadcaster
attr_accessor :listener_queue
attr_accessor :destination
attr_accessor :direction
def initialize(destination:, direction:)
@destination, @direction = destination, direction
end
def pass(thing)
thing.current_area = destination
end
broadcast_calls_to :pass
end
hall = Area.new(description: "hall")
room = Area.new(description: "room")
way = Way.new(destination: room, direction: "north")
way.listener_queue = ListenerQueue.new
door = Door.new
door.state = :closed
way.listener_queue.register(door)
player = Thing.new(name: "player", current_area: hall)
puts "Currently in #{player.current_area.description}"
way.pass(player)
puts "Currently in #{player.current_area.description}"
door.state = :open
way.pass(player)
puts "Currently in #{player.current_area.description}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment