class Twisty::Engine

Main class within Twisty.

Attributes

commands[R]

(Hash[Command]) Hash of user typeable commands indexed by regular expression

inventory[R]

(Array[Symbol]) Keys of the Items the player is carrying

items[R]

(Hash{Symbol => Item}) All Items in the game regardless of if they have been placed anywhere

rooms[R]

(Hash{Symbol => Room}) All Rooms in the game regardless of if they can be reached

Public Class Methods

new() click to toggle source

Initialiser. As this class is a singleton use Engine.instance instead

# File lib/twisty/engine.rb, line 36
def initialize
        @items = {}
        @rooms = {}

        @current_room = nil
        @inventory = []

        @playing = nil

        @commands = {} #Filled in by lib/twisty.rb
end

Public Instance Methods

add_door(from, to, name) click to toggle source

Creates an exit from one Room to another

from

(Symbol) Key for the Room where the player is before using “walk”

to

(Symbol) Key for the Room where the player is after using “walk”

name

(String) Used to name the door. This can be a word such as “East” rather than the name of the destination. NOTE Must be one word

# File lib/twisty/engine.rb, line 123
def add_door(from, to, name)
        if @rooms.has_key?(from)
                if @rooms.has_key?(to)
                        @rooms[from].add_door(to, name)
                else
                        raise GameError.new "Invalid room name: #{to}"
                end
        else
                raise GameError.new "Invalid room name: #{from}"
        end

        return nil
end
current_doors() click to toggle source

(Hash{Symbol => String})

Exits of the Room the player is currently in

# File lib/twisty/engine.rb, line 202
def current_doors
        @rooms[@current_room].doors
end
current_items() click to toggle source

(Array[Symbol])

Keys of the Items present in the Room where the player is currently located

# File lib/twisty/engine.rb, line 211
def current_items
        @rooms[@current_room].items
end
current_room() click to toggle source

(Room)

The instance of Room that the player is currently in

# File lib/twisty/engine.rb, line 194
def current_room
        @rooms[@current_room]
end
current_room=(id) click to toggle source

Change the the room that the player is currently in to the one represented by the Symbol id. Unlike Engine.goto() This does not print any information or trigger events.

id

(Symbol) Key of the Room where the player will go to

# File lib/twisty/engine.rb, line 143
def current_room=(id)
        if @rooms.has_key? id
                @current_room = id
        else
                raise GameError.new "Room #{id} has not been defined"
        end

        return nil
end
define_command(pattern, help1, help2, &func) click to toggle source

Create a new command for the user to type. Not applicable for creating methods to develop the game with

pattern

(Regexp) Pattern that triggers the command to be run.

NOTE Must be unique and unambigious

help1

(String) An example of the command. E.g. “take item”

help2

(String) A short description of what the command does

&func

(Proc) Code executed when the player types the command in. NOTE Must take one argument of type Array[String] which contains what the player typed

# File lib/twisty/engine.rb, line 181
def define_command(pattern, help1, help2, &func)
        @commands[pattern] = Command.new(help1, help2, func)
        return nil
end
define_item(id, name, desc, options={}) click to toggle source

(Item)

Creates a new instance of Item in Engine.items indexed by id. Use this instead of Item.new().

id

(Symbol) Key within Engine.items

name

Name shown in “look” and used to “take” / “drop” the Item. NOTE This MUST be a single word.

desc

(String) Long description shown when the player uses “look at”

options

(Hash{Symbol => +Any}) Additional attributes of the Item

At present there are only two valid options that can be passed via options:

fixed

(Boolean) If set to true prevents “take” from working on the Item. Set to false by default

storage

(Integer) Indicates the number of other Items that this Item can contain. Set to 0 by default

# File lib/twisty/engine.rb, line 72
def define_item(id, name, desc, options={})
        options = {fixed: false, storage: 0}.merge(options)

        fixed = options[:fixed] || false
        storage = options[:storage] || 0

        if @items[id] == nil
                @items[id] = Twisty::Item.new(id, name, desc, fixed, storage)
        else
                raise GameError.new "Item #{id} has already been defined"
        end

        return @items[id]
end
define_room(id, name, desc) click to toggle source

(Room)

Creates a new instance of Room in Engine.rooms indexed by id. Use this instead of Room.new().

id

(Symbol) Key for the Room in Engine.rooms

name

String (preferably one word) shown in the prompt when the player is located in this Room

desc

(String) The long description of the player's current location

# File lib/twisty/engine.rb, line 97
def define_room(id, name, desc)
        room = Twisty::Room.new(id, name, desc)

        if @rooms[id] == nil
                @rooms[id] = room
        else
                raise GameError.new "Room #{id} has already been defined"
        end

        #First defined room is default starting point
        if @rooms.size == 1
                @current_room = id
        end

        return @rooms[id]
end
drop_item(name) click to toggle source

The “drop item” command. Probably best not to call directly

name

(String) The name, typed by the player, of the item to be

dropped

# File lib/twisty/engine.rb, line 338
def drop_item(name)
        id = find_in_inventory(name)
        if @items[id].drop_event
                current_room.items << id
                @inventory.delete id
        end

        return nil
end
end_loop() click to toggle source

Ends the main loop of the game. Use this for win and loose conditions

# File lib/twisty/engine.rb, line 403
def end_loop
        @playing = false
        return nil
end
find_in_current_room(name) click to toggle source

(Symbol)

Returns Index of the Item of the same name in the current room

# File lib/twisty/engine.rb, line 227
def find_in_current_room(name)
        current_items.each do |id|
                if @items.has_key? id
                        if @items[id].name.downcase == name.downcase
                                return id
                        end
                else
                        raise GameError.new "Invalid Item #{id} in #{@current_room}"
                end
        end

        #Could not be found
        raise PlayError.new "I see no #{name}"
        return :nil #Never reached
end
find_in_inventory(name) click to toggle source

(Symbol)

Returns Index of the Item of the same name in the inventory

# File lib/twisty/engine.rb, line 247
def find_in_inventory(name)
        inventory.each do |id|
                if @items.has_key? id
                        if @items[id].name.downcase == name.downcase
                                return id
                        end
                else
                        raise GameError.new "Invalid Item #{id} in inventory"
                end
        end

        #Could not be found
        raise PlayError.new "You are not carrying that"
        return :nil
end
give(id) click to toggle source

Place an Item represented by the Symbol id. Unlike Engine.take_item_by_id() this does not remove the Item from any Room it may be in or trigger any events.

id

(Symbol) Key of the Item that will be added to the player's inventory

# File lib/twisty/engine.rb, line 160
def give(id)
        if @items.include? id
                @inventory << id
        else
                raise GameError.new "Invalid item: #{id}"
        end

        return nil
end
goto(to) click to toggle source

Called by the “walk door” command. Unlike current_room=(id) this triggers events and only moves the player if said events run successfully

id

(Symbol) Key in Engine.rooms of the Room that the player will be moved to

# File lib/twisty/engine.rb, line 355
def goto(to)
        if @rooms.has_key? to
                if current_room.exit_event and @rooms[to].enter_event
                        @current_room = to
                end
        else
                raise TwistyError.new "Room #{to} has not been defined"
        end

        return nil
end
parse(line) click to toggle source

Called by start_loop to process user inpu.

# File lib/twisty/engine.rb, line 410
def parse(line)
        #Strip double spaces and downcase
        tokens = line.downcase.split
        line = tokens.join(' ')

        if line == "" #Empty command
                return nil
        end

        @commands.each do |pattern, command|
                if line =~ pattern
                        command.exec(tokens)
                        return nil
                end
        end

        #Implicit error
        raise PlayError.new "I don't know how to #{line}"

        #Never reached
        return nil
end
put_item(item, container) click to toggle source

The “put item in item” command. Probably best not to call directly

item

(String) Name that the player has typed for an item to be added to a container

# File lib/twisty/engine.rb, line 317
def put_item(item, container)
        iId = find_in_inventory(item)
        cId = find_in_current_room(container)

        if @items[cId].storage == 0
                raise PlayError.new "It won't fit in there"
        end

        if @items[cId].put_content_event(iId) and @items[iId].drop_event
                @items[cId].add_item(iId)
                @inventory.delete iId
        end

        return nil
end
start_loop() click to toggle source

Starts the main loop of the game

NOTE This must be included once and only once at the end of the program

# File lib/twisty/engine.rb, line 376
def start_loop
        @playing = true

        current_room.look
        puts
        @commands[/^inventory$/].exec(["inventory"])
        puts

        while @playing == true
                printf "#{current_room.name} > "
                begin
                        line = gets
                        if line.class == NilClass
                                @playing = false
                                return nil
                        end
                        parse(line)
                rescue PlayError => e
                        puts e.message
                end
        end

        return nil
end
take_from(item, container) click to toggle source

The “take item from item” command. Probably best not to call directly

item

(String) Name that the player has typed for an item to be inventory

container

(String) Name of an Item that the player is looking to remove added to the another Item from

# File lib/twisty/engine.rb, line 291
def take_from(item, container)
        cId = find_in_current_room(container) #Container ID

        @items[cId].contents.each do |iId|
                if @items.has_key? iId
                        if @items[iId].name.downcase == item.downcase
                                if @items[cId].take_content_event(iId) and @items[iId].take_event
                                        @items[cId].del_item iId
                                        @inventory << iId

                                        return nil
                                end
                        end
                else
                        raise GameError.new "Invalid Item in container #{cId}"
                end
        end

        return nil
end
take_item(name) click to toggle source

The “take item” command. Probably best not to call directly

name

(String) Name of an Item the player has typed in

# File lib/twisty/engine.rb, line 270
def take_item(name)
        id = find_in_current_room(name)
        if @items[id].fixed
                raise PlayError.new "You can not move that"
        else
                if @items[id].take_event
                        current_room.items.delete id
                        @inventory << id
                end

                return nil
        end
end