summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Lasseter <Nat Lasseter nathan@bytemark.co.uk>2018-04-04 21:54:03 +0100
committerNat Lasseter <Nat Lasseter nathan@bytemark.co.uk>2018-04-04 21:54:03 +0100
commitc7f7a60a7f1175696b8239355dc7737532c1f1ce (patch)
treefe5759a74286560e0da63208fdb0424098fe810c
Initial commitHEADmaster
-rw-r--r--game.gamefile33
-rw-r--r--game.rb180
-rw-r--r--parse.rb74
-rw-r--r--proto/game.rb109
-rw-r--r--proto/rooms.json25
-rw-r--r--proto/stuff.json9
6 files changed, 430 insertions, 0 deletions
diff --git a/game.gamefile b/game.gamefile
new file mode 100644
index 0000000..33c9f22
--- /dev/null
+++ b/game.gamefile
@@ -0,0 +1,33 @@
+thing("apple") {
+ property "edible"
+ energy 2
+}
+
+thing("lamp") {
+ property "lightable"
+ energy 20
+}
+
+thing("butter") {
+ property "lightable", "edible"
+ energy 3
+}
+
+room("start") {
+ description "The starting room"
+ inventory "apple", "lamp"
+ north "another"
+ south "another"
+ east "start"
+ west "start"
+}
+
+room("another") {
+ description "Just another room"
+ property "dark"
+ inventory "apple", "apple"
+ east "start"
+ west "start"
+}
+
+# vim: set ft=ruby:
diff --git a/game.rb b/game.rb
new file mode 100644
index 0000000..0af3bcc
--- /dev/null
+++ b/game.rb
@@ -0,0 +1,180 @@
+exit 1 if ARGV.empty?
+
+$thingfactories = {}
+$roomfactories = {}
+$rooms = {}
+
+class ThingFactory
+ def initialize(name, block)
+ @name = name
+ @properties = []
+ @energy = 0
+ self.instance_eval(&block)
+ end
+
+ def property(*strs)
+ strs.each do |str|
+ @properties << str
+ end
+ end
+
+ def energy(num)
+ @energy = num
+ end
+
+ def create
+ return Thing.new(@name, @properties, @energy)
+ end
+
+ attr_reader :name
+end
+
+class Thing
+ def initialize(name, properties, energy)
+ @name = name
+ @properties = properties
+ @energy = energy
+ end
+
+ def has_property(str)
+ return @properties.include?(str)
+ end
+
+ def method_missing(name)
+ if name.to_s =~ /^is_(.*)\?$/ then
+ has_property($1)
+ end
+ end
+
+ attr_reader :name
+ attr_accessor :energy
+end
+
+class RoomFactory
+ def initialize(block)
+ @description = ""
+ @properties = []
+ @inventory = []
+ @north = nil
+ @south = nil
+ @east = nil
+ @west = nil
+ self.instance_eval(&block)
+ end
+
+ def description(description)
+ @description = description
+ end
+
+ def property(str)
+ @properties << str
+ end
+
+ def inventory(*strs)
+ strs.each do |str|
+ @inventory << str
+ end
+ end
+
+ def north(str)
+ @north = str
+ end
+
+ def south(str)
+ @south = str
+ end
+
+ def east(str)
+ @east = str
+ end
+
+ def west(str)
+ @west = str
+ end
+
+ def create
+ return Room.new(@description, @properties, @inventory, @north, @south, @east, @west)
+ end
+end
+
+class Room
+ def initialize(description, properties, inventory, north, south, east, west)
+ @description = description
+ @properties = properties
+ @inventory = inventory
+ @north = north
+ @south = south
+ @east = east
+ @west = west
+ end
+
+ def reify!(roomhash)
+ t = []
+ @inventory.each do |str|
+ t << $thingfactories[str].create
+ end
+ @inventory = t
+
+ @north = roomhash[@north] unless @north.nil?
+ @south = roomhash[@south] unless @south.nil?
+ @east = roomhash[@east ] unless @east.nil?
+ @west = roomhash[@west ] unless @west.nil?
+ end
+
+ def take(thing)
+ matches = @inventory.select do |thg|
+ thg.name == thing
+ end
+
+ return @inventory.delete(matches[0])
+ end
+
+ def put(thing)
+ @inventory << thing
+ end
+
+ def has_property(str)
+ return @properties.include?(str)
+ end
+
+ def method_missing(name)
+ if name.to_s =~ /^is_(.*)\?$/ then
+ has_property($1)
+ end
+ end
+
+ attr_reader :description, :inventory, :north, :south, :east, :west
+end
+
+
+
+def room(name, &block)
+ factory = RoomFactory.new(block)
+ $roomfactories[name] = factory
+end
+
+def thing(name, &block)
+ factory = ThingFactory.new(name, block)
+ $thingfactories[name] = factory
+end
+
+
+
+def createRooms
+ $roomfactories.each do |name, factory|
+ $rooms[name] = factory.create
+ end
+ $rooms.each do |_, room|
+ room.reify!($rooms)
+ end
+end
+
+load ARGV.shift.strip
+createRooms
+
+
+
+puts "ERROR 1" unless $rooms["start"].east == $rooms["start"]
+puts "ERROR 2" unless $rooms["another"].is_dark?
+puts "ERROR 3" unless $rooms["another"].take("lamp").nil?
+puts "ERROR 4" if $rooms["another"].take("apple").nil?
diff --git a/parse.rb b/parse.rb
new file mode 100644
index 0000000..f81d509
--- /dev/null
+++ b/parse.rb
@@ -0,0 +1,74 @@
+exit 1 if ARGV.empty?
+
+$things = []
+$rooms = []
+
+class ThingFactory
+ def self.create_thing(block)
+ ThingFactory.new(block).to_thing
+ end
+
+ def initialize(block)
+ @name = ""
+ @properties = []
+ @energy = 0
+ self.instance_eval(&block)
+ end
+
+ def name(str)
+ @name = str
+ end
+
+ def property(str, *strs)
+ @properties << str
+ @properties += strs
+ end
+
+ def energy(num)
+ @energy = num
+ end
+
+ def to_thing
+ return Thing.new(@name, @properties, @energy)
+ end
+end
+
+class Thing
+ def self.parse(block)
+ return ThingFactory.create_thing(block)
+ end
+
+ def initialize(name, properties, energy)
+ @name = name
+ @properties = properties
+ @energy = energy
+ end
+
+ def has_property(str)
+ return @properties.include?(str)
+ end
+
+ def method_missing(name)
+ if name.to_s =~ /^is_(.*)\?$/ then
+ has_property($1)
+ end
+ end
+
+ attr_reader :name
+ attr_accessor :energy
+end
+
+
+
+def room(&block)
+ #return Room.parse(block)
+end
+
+def thing(&block)
+ $things << Thing.parse(block)
+end
+
+
+
+
+load ARGV.shift.strip
diff --git a/proto/game.rb b/proto/game.rb
new file mode 100644
index 0000000..68f1198
--- /dev/null
+++ b/proto/game.rb
@@ -0,0 +1,109 @@
+require 'json'
+
+class Array
+ def second; return self[1]; end
+ def third; return self[2]; end
+ def rest; return self[1..-1]; end
+end
+
+$stuff = JSON.parse(File.read("stuff.json"))
+$rooms = JSON.parse(File.read("rooms.json"))
+$inventory = []
+$room = "start"
+$energy = 10
+$light = false
+
+def look
+ if $rooms[$room]["dark"] and !$light then
+ puts "It's too dark, you can't see anything."
+ else
+ puts $rooms[$room]["summary"]
+ things = $rooms[$room]["inventory"]
+ if things.length.zero? then
+ puts "You see nothing."
+ else
+ puts "You see:"
+ things.each do |thing|
+ puts "\t#{thing}"
+ end
+ end
+ end
+end
+
+def handle(line)
+ a = line.split
+ case a.first
+ when "look"
+ if a.second == "me" || a.second == "self" then
+ puts "A daring adventurer."
+ puts "HP: #{$energy}"
+ handle "inventory"
+ else
+ look
+ end
+ when "take", "get"
+ if $rooms[$room]["inventory"].include?(a.second) then
+ $inventory << a.second
+ $rooms[$room]["inventory"].delete(a.second)
+ puts "You take the #{a.second}."
+ else
+ puts "You can't see a(n) #{a.second}."
+ end
+ when "north", "south", "east", "west"
+ handle "go #{a.first}"
+ when "go"
+ $room = $rooms[$room][a.second]
+ look
+ when "inventory"
+ if $inventory.length.zero? then
+ puts "You have nothing."
+ else
+ puts "You have:"
+ $inventory.each do |thing|
+ puts "\t#{thing}"
+ end
+ end
+ when "light"
+ if $inventory.include?(a.second) then
+ if $stuff[a.second]["light"] then
+ puts "You light the #{a.second}."
+ $light = true
+ else
+ puts "You can't light that."
+ end
+ else
+ puts "You don't have a(n) #{a.second} to light."
+ end
+ when "snuff"
+ if $inventory.include?(a.second) then
+ if $stuff[a.second]["light"] then
+ puts "You snuff the #{a.second}."
+ $light = false
+ else
+ puts "You can't light that, let alone snuff it."
+ end
+ else
+ puts "You don't have a(n) #{a.second} to snuff."
+ end
+ when "eat"
+ if $inventory.include?(a.second) then
+ if $stuff[a.second]["edible"] then
+ $energy += $stuff[a.second]["energy"]
+ puts "A tasty #{a.second}"
+ $inventory.delete(a.second)
+ else
+ puts "You can't eat that."
+ end
+ else
+ puts "You don't have a(n) #{a.second} to eat."
+ end
+ end
+end
+
+look
+
+loop do
+ print ">: "
+ line = gets.strip.downcase
+ handle(line)
+end
diff --git a/proto/rooms.json b/proto/rooms.json
new file mode 100644
index 0000000..a6d0cd7
--- /dev/null
+++ b/proto/rooms.json
@@ -0,0 +1,25 @@
+{
+ "start": {
+ "summary": "A bland, starting room.",
+ "inventory": [
+ "apple",
+ "lamp"
+ ],
+ "north": "another",
+ "south": "another",
+ "east": "start",
+ "west": "start"
+ },
+ "another": {
+ "summary": "Another room.",
+ "dark": true,
+ "inventory": [
+ "apple",
+ "apple"
+ ],
+ "north": "start",
+ "south": "start",
+ "east": "another",
+ "west": "another"
+ }
+}
diff --git a/proto/stuff.json b/proto/stuff.json
new file mode 100644
index 0000000..e665b6f
--- /dev/null
+++ b/proto/stuff.json
@@ -0,0 +1,9 @@
+{
+ "apple": {
+ "edible": true,
+ "energy": 2
+ },
+ "lamp": {
+ "light": true
+ }
+}