RCRPG/Wren

From Rosetta Code

Wren version of RCRPG.

Code

Translation of: Python
Library: Wren-str
Library: Wren-ioutil
import "random" for Random
import "./str" for Str
import "./ioutil" for Input

var Rand = Random.new()

var Directions = {
    "north": [ 0, -1,  0],
    "east" : [ 1,  0,  0],
    "south": [ 0,  1,  0],
    "west" : [-1,  0,  0],
    "up"   : [ 0,  0,  1],
    "down" : [ 0,  0, -1]
}

var Aliases = {
    "north": ["move", "north"],
    "south": ["move", "south"],
    "east" : ["move", "east" ],
    "west" : ["move", "west" ],
    "up"   : ["move", "up"   ],
    "down" : ["move", "down" ]
}

var RoomNames = {
    [0, 0, 0].toString: "the starting room",
    [1, 1, 5].toString: "the prize room"
}

class Room {
    construct new(items) {
        _items = items.toList
        _passages = {}
        for (key in Directions.keys) _passages[key] = false
    }

    items { _items }
    passages { _passages }

    describe(location) {
        var result = "You are at "
        var locStr = location.toString
        if (RoomNames.containsKey(locStr)) {
            result = result + RoomNames[locStr]
        } else {
            result = result + location.join(",")
        }
        if (!items.isEmpty) {
            result = result + "\nOn the ground you can see: %(items.join(", "))"
        }
        var exits = []
        for (me in _passages) if (me.value) exits.add(me.key)
        if (exits.isEmpty) exits.add("None")
        exits = exits.map { |e| Str.capitalize(e) }.join(", ")
        return result + "\nExits are: %(exits)"
    }

    take(target) {
        var results
        if (target == "all") {
            results = _items.toList
            _items.clear()
            System.print("You now have everything in the room.")
        } else if (_items.contains(target)) {
            _items.remove(target)
            results = [target]
            System.print("Taken.")
        } else {
            results = []
            System.print("Item not found.")
        }
        return results
    }
}

var GetNewCoord = Fn.new { |oldCoord, direction|
    return [oldCoord[0] + Directions[direction][0],
            oldCoord[1] + Directions[direction][1],
            oldCoord[2] + Directions[direction][2]]
}

var OppositeDir = Fn.new { |direction|
    return (direction == "north") ? "south" :
           (direction == "south") ? "north" :
           (direction == "west" ) ? "east"  :
           (direction == "east" ) ? "west"  :
           (direction == "up"   ) ? "down"  :
           (direction == "down" ) ? "up"    : Fiber.abort("No direction found: %(direction)")
}

var MakeRandomItems = Fn.new {
    var rn = Rand.int(4)
    return (rn == 0) ? [] :
           (rn == 1) ? ["sledge"] :
           (rn == 2) ? ["ladder"] : ["gold"]
}
           
class World {
    construct new() {
        _currentPos = [0, 0, 0]
        _rooms = { [0, 0, 0].toString: Room.new(["sledge"]) }
        _inv = []
        _equipped = ""
    }

    look() { _rooms[_currentPos.toString].describe(_currentPos) }

    move(direction) {
        if (direction == "up" && !_rooms[_currentPos.toString].items.contains("ladder")) {
            System.print("You'll need a ladder in this room to go up.")
            return
        }
        if (!Directions.containsKey(direction)) {
            System.print("That's not a direction.")
            return
        }
        if (_rooms[_currentPos.toString].passages[direction]) {
            _currentPos = GetNewCoord.call(_currentPos, direction)
        } else {
            System.print("Can't go that way.")
        }
    }

    alias(newAlias, command) {
        Aliases[newAlias] = command.toList
        System.print("Alias created.")
    }

    inventory() {
        if (!_inv.isEmpty) {
            System.print("Carrying: %(_inv.join(", "))")
        } else {
            System.print("You aren't carrying anything.")
        }
        if (_equipped != "") {
            System.print("Holding: %(_equipped)")
        }
    }

    take(target) {
        _inv = _inv + _rooms[_currentPos.toString].take(target)
    }

    drop(target) {
        if (target == "all") {
            _rooms[_currentpos.toString].items.addAll(_inv)
            _inv.clear()
            System.print("Everything dropped.")
        } else if (_inv.contains("target")) {
            _inv.remove(target)
            _rooms[_currentPos.toString].items.add(target)
            System.print("Dropped.")
        } else {
            System.print("Could not find item in inventory.")
        }
    }

    equip(itemName) {
        if (_inv.contains(itemName)) {
            if (_equipped != "") unequip()
            _inv.remove(itemName)
            _equipped = itemName
            System.print("Equipped %(itemName).")
        } else {
            System.print("You aren't carrying that.")
        }
    }

    unequip() {
        if (_equipped == "") {
            System.print("You aren't equipped with anything.")
        } else {
            _inv.add(_equipped)
            System.print("Unequipped %(_equipped).")
            _equipped = ""
        }
    }

    name(newRoomNameTokens) {
        RoomNames[_currentPos.toString] = newRoomNameTokens.join(" ")
    }

    dig(direction) {
        if (_equipped != "sledge") {
            System.print("You don't have a digging tool equipped.")
            return
        }
        if (!Directions.containsKey(direction)) {
            System.print("That's not a direction.")
            return
        }
        if (!_rooms[_currentPos.toString].passages[direction]) {
            _rooms[_currentPos.toString].passages[direction] = true
            var joinRoomPos = GetNewCoord.call(_currentPos, direction)
            if (!_rooms.containsKey(joinRoomPos.toString)) {
                _rooms[joinRoomPos.toString] = Room.new(MakeRandomItems.call())
            }
            _rooms[joinRoomPos.toString].passages[OppositeDir.call(direction)] = true
            System.print("You've dug a tunnel.")
        } else {
            System.print("Already a tunnel that way.")
        }
    }
}

var world = World.new()
System.print("Welcome to the dungeon!\nGrab the sledge and make your way to room 1,1,5 for a non-existent prize!")

while (true) {
    System.print("\n" + world.look())
    var tokens = Str.lower(Input.text("> ")).trim().split(" ")
    var t = tokens[0]
    if (t == "quit") break
    if (!tokens.isEmpty) {
        if (Aliases.containsKey(t) && t != Aliases[t][0]) {
            tokens = Aliases[t] + tokens[1..-1]
        }
        t = tokens[0]
        var tc = tokens.count
        if (t == "look") {
            if (tc != 1) {
                System.print("'look' takes no arguments.")
            } else world.look()

        } else if (t == "move") {
            if (tc != 2) {
                System.print("'move' takes a single argument.")
            } else world.move(tokens[1])

        } else if (t == "alias") {
            if (tc < 3) {
                System.print("'alias' takes at least two arguments.")
            } else world.alias(tokens[1], tokens[2..-1])

        } else if (t == "inventory") {
            if (tc != 1) {
                System.print("'inventory' takes no arguments.")
            } else world.inventory()

        } else if (t == "take") {
            if (tc != 2) {
                System.print("'take' takes a single argument.")
            } else world.take(tokens[1])

        } else if (t == "drop") {
            if (tc != 2) {
                System.print("'drop' takes a single argument.")
            } else world.drop(tokens[1])

        } else if (t == "equip") {
            if (tc != 2) {
                System.print("'equip' takes a single argument.")
            } else world.equip(tokens[1])

        } else if (t == "unequip") {
            if (tc != 1) {
                System.print("'unequip' takes no arguments.")
            } else world.unequip()

        } else if (t == "name") {
            if (tc < 2) {
                System.print("'name' takes at least one argument.")
            } else world.name(tokens[1..-1])

        } else if (t == "dig") {
            if (tc != 2) {
                System.print("'dig' takes a single argument.")
            } else world.dig(tokens[1])

        } else {
            System.print("Command not found.")
        }
    }
}
System.print("Thanks for playing!")