[ create a new paste ] login | about

Link: http://codepad.org/SflrKqbT    [ raw code | fork ]

D, pasted on Feb 5:
import std.stdio, std.typecons, std.random, std.string, std.conv,
       std.array, std.range, std.algorithm;

alias T3 = Tuple!(int, int, int);

immutable T3[string] directions;
string[][string] aliases;
string[T3] roomNames;

static this() {
    directions = ["north":T3(0,-1,0),
                  "east":T3(1,0,0),
                  "south":T3(0,1,0),
                  "west":T3(-1,0,0),
                  "up":T3(0,0,1),
                  "down":T3(0,0,-1)];

    aliases = ["north": ["move","north"],
               "south": ["move","south"],
               "east": ["move","east"],
               "west": ["move","west"],
               "up": ["move","up"],
               "down": ["move","down"]];

    roomNames = [T3(0,0,0):"the starting room",
                 T3(1,1,5):"the prize room"];
}

class Room {
    string[] items;
    bool[string] passages;

    this(string[] items=null) {
        this.passages = directions.byKey.zip(repeat(false))
                        .assocArray();
        this.items = items.dup;
    }

    string describe(T3 location) {
        auto result = "You are at ";
        if (location in roomNames)
            result ~= roomNames[location];
        else
            result ~= format("%d,%d,%d", location.tupleof);

        if (!this.items.empty)
            result ~= "\nOn the ground you can see: " ~
                      this.items.join(", ");
        result ~= "\nExits are: ";
        string[] exits = this.passages.byKey
                         .filter!(k => passages[k])()
                         .array();
        if (exits.empty) exits = ["None"];
        result ~= exits.map!capitalize().join(", ");
        return result;
    }

    string[] take(in string target) {
        string[] results;
        if (target == "all") {
            results = this.items.dup;
            this.items.length = 0;
            writeln("You now have everything in the room.");
        } else if (this.items.canFind(target)) {
            this.items = this.items.remove(target);
            results = [target];
            writeln("Taken.");
        } else
            writeln("Item not found.");
        return results;
    }
}

T3 get_new_coord(T3 oldCoord, string direction) pure nothrow {
    return T3(oldCoord[0] + directions[direction][0],
              oldCoord[1] + directions[direction][1],
              oldCoord[2] + directions[direction][2]);
}

string opposite_dir(string direction) pure nothrow {
    switch (direction) {
        case "north": return "south";
        case "south": return "north";
        case "west":  return "east";
        case "east":  return "west";
        case "up":    return "down";
        case "down":  return "up";
        default:
            throw new Error("No direction found: " ~ direction);
    }
}

string[] make_random_items() {
    return [[], ["sledge"], ["ladder"], ["gold"]][uniform(0, $)];
}

class World {
    T3 currentPos = T3(0,0,0);
    Room[T3] rooms;
    string[] inv;
    string equipped;

    this() {
        this.rooms = [T3(0,0,0): new Room(["sledge"])];
    }

    string look() {
        return this.rooms[this.currentPos].describe(this.currentPos);
    }

    void move(in string direction) {
        if (direction == "up" &&
            !canFind(this.rooms[this.currentPos].items, "ladder"))
            return writeln("You'll need a ladder in " ~
                           "this room to go up.");
        if (direction !in directions)
            return writeln("That's not a direction.");
        if (this.rooms[this.currentPos].passages[direction])
            currentPos = get_new_coord(this.currentPos, direction);
        else
            writeln("Can't go that way.");
    }

    void newalias(string newAlias, string[] command...) {
        aliases[newAlias] = command.dup;
        writeln("Alias created.");
    }

    void inventory() {
        if (this.inv.empty)
            writeln("You aren't carrying anything.");
        else
            writeln("Carrying: ", this.inv.join(", "));
        if (!this.equipped.empty)
            writeln("Holding: ", this.equipped);
    }

    void take(in string target) {
        this.inv ~= this.rooms[this.currentPos].take(target);
    }

    void drop(in string target) {
        if (target == "all") {
            this.rooms[this.currentPos].items ~= this.inv;
            this.inv.length = 0;
            writeln("Everything dropped.");
        } else if (this.inv.canFind(target)) {
            this.inv = this.inv.remove(target);
            this.rooms[this.currentPos].items ~= target;
            writeln("Dropped.");
        } else
            writeln("Could not find item in inventory.");
    }

    void equip(in string itemName) {
        if (this.inv.canFind(itemName)) {
            if (!this.equipped.empty)
                this.unequip();
            this.inv = this.inv.remove(itemName);
            this.equipped = itemName;
            writeln("Equipped ", itemName, ".");
        } else
            writeln("You aren't carrying that.");
    }

    void unequip() {
        if (this.equipped.empty)
            writeln("You aren't equipped with anything.");
        else {
            this.inv ~= this.equipped;
            writeln("Unequipped ", this.equipped, ".");
            this.equipped = null;
        }
    }

    void name(string[] newRoomNameTokens...) {
        roomNames[this.currentPos] = newRoomNameTokens.join(" ");
    }

    void dig(in string direction) {
        if (this.equipped != "sledge")
            return writeln("You don't have a digging tool equipped.");
        if (direction !in directions)
            return writeln("That's not a direction.");
        if (!this.rooms[this.currentPos].passages[direction]) {
            this.rooms[this.currentPos].passages[direction] = true;
            auto joinRoomPos = get_new_coord(this.currentPos, direction);
            if (joinRoomPos !in this.rooms)
                this.rooms[joinRoomPos] = new Room(make_random_items());
            this.rooms[joinRoomPos].passages[opposite_dir(direction)] = true;
            writeln("You've dug a tunnel.");
        } else
            writeln("Already a tunnel that way.");
    }
}

void main() {
    auto world = new World();
    writeln("Welcome to the dungeon!\nGrab the sledge && make your" ~
            " way to room 1,1,5 for a non-existant prize!");
    while (true) {
        writeln("\n", world.look());
        write("> ");
        auto tokens = readln().strip().toLower().split();
        if (tokens[0] == "quit")
            break;
        while (!tokens.empty) {
            if (tokens[0] in aliases && tokens[0] != aliases[tokens[0]][0]) {
                tokens[0] = aliases[tokens[0]];
                continue;
            }
/*
            try:
                getattr(world, tokens[0])(tokens[1 .. $])
            except AttributeError as ex:
                writeln("Command not found.")
            except TypeError as ex:
                writeln("Wrong number of args.")
*/
            break;
        }
    }
    writeln("Thanks for playing!");
}


Create a new paste based on this one


Comments: