about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-12-28 21:45:37 -0500
committerelioat <elioat@tilde.institute>2023-12-28 21:45:37 -0500
commitb63f67c6596cb93da7db010b7fd390ff75f7e892 (patch)
treed1295b4fad260b7e1999ea262a06682a8399b492
parent42ec1a26d1e2c671d0f64aaf14a5025910d95c9c (diff)
downloadtour-b63f67c6596cb93da7db010b7fd390ff75f7e892.tar.gz
*
-rw-r--r--js/story-interpreter/interpreter.js136
-rw-r--r--js/story-interpreter/world.dsl32
2 files changed, 168 insertions, 0 deletions
diff --git a/js/story-interpreter/interpreter.js b/js/story-interpreter/interpreter.js
new file mode 100644
index 0000000..be11f0e
--- /dev/null
+++ b/js/story-interpreter/interpreter.js
@@ -0,0 +1,136 @@
+const fs = require('fs');
+
+
+class Room {
+    constructor(name, description, items, animals, connections) {
+        this.name = name;
+        this.description = description;
+        this.items = items;
+        this.animals = animals;
+        this.connections = connections;
+    }
+}
+
+class Item {
+    constructor(name, description, action) {
+        this.name = name;
+        this.description = description;
+        this.action = action;
+    }
+}
+
+class Animal {
+    constructor(name, description, action) {
+        this.name = name;
+        this.description = description;
+        this.action = action;
+    }
+}
+
+class Interpreter {
+    constructor() {
+        this.rooms = {};
+        this.currentRoom = null;
+        this.history = [];
+    }
+
+    parseDSLFile(filePath) {
+        const dsl = fs.readFileSync(filePath, 'utf8');
+        this.parseDSL(dsl);
+    }
+
+    parseDSL(dsl) {
+        const lines = dsl.split('\n');
+        let currentRoom = null;
+        let currentItem = null;
+        let currentAnimal = null;
+
+        for (const line of lines) {
+            const trimmed = line.trim();
+
+            if (trimmed.startsWith('room')) {
+                const name = trimmed.split('"')[1];
+                currentRoom = new Room(name);
+                this.rooms[name] = currentRoom;
+            } else if (trimmed.startsWith('description')) {
+                const description = trimmed.split('"')[1];
+                if (currentItem) {
+                    currentItem.description = description;
+                } else if (currentAnimal) {
+                    currentAnimal.description = description;
+                } else {
+                    currentRoom.description = description;
+                }
+            } else if (trimmed.startsWith('item')) {
+                const name = trimmed.split('"')[1];
+                currentItem = new Item(name);
+                currentRoom.items[name] = currentItem;
+            } else if (trimmed.startsWith('animal')) {
+                const name = trimmed.split('"')[1];
+                currentAnimal = new Animal(name);
+                currentRoom.animals[name] = currentAnimal;
+            } else if (trimmed.startsWith('action')) {
+                const action = trimmed.split('"')[1];
+                if (currentItem) {
+                    currentItem.action = action;
+                } else {
+                    currentAnimal.action = action;
+                }
+            } else if (trimmed.startsWith('connection')) {
+                const direction = trimmed.split('"')[1];
+                const roomName = trimmed.split('"')[3];
+                currentRoom.connections[direction] = roomName;
+            } 
+        }
+    }
+
+    interpretCommand(command) {
+        const tokens = command.split(' ');
+        const action = tokens[0];
+        const object = tokens[1];
+
+        if (action === 'go') {
+            this.currentRoom = this.rooms[this.currentRoom.connections[object]];
+        } else if (action === 'take') {
+            if (this.currentRoom.items[object]) {
+                console.log(this.currentRoom.items[object].action);
+                this.inventory.push(this.currentRoom.items[object]);
+                delete this.currentRoom.items[object];
+            }
+        } else if (action === 'drop') {
+            if (this.inventory.includes(object)) {
+                this.currentRoom.items[object] = object;
+                this.inventory = this.inventory.filter(item => item !== object);
+                console.log(`You dropped the ${object}.`);
+            }
+        } else if (action === 'examine') {
+            if (this.currentRoom.items[object]) {
+                console.log(this.currentRoom.items[object].description);
+            } else if (this.inventory.includes(object)) {
+                console.log(object.description);
+            } else {
+                console.log(`There is no ${object} here to examine.`);
+            }
+        } else if (this.currentRoom.animals[object]) {
+            console.log(this.currentRoom.animals[object].action);
+        }
+
+        this.history.push(command);
+    }
+}
+
+// Create a new interpreter
+const interpreter = new Interpreter();
+
+// Parse the DSL file
+interpreter.parseDSLFile(process.argv[2]);
+
+// Start a command line interface
+const readline = require('readline').createInterface({
+    input: process.stdin,
+    output: process.stdout
+});
+
+readline.on('line', (line) => {
+    interpreter.interpretCommand(line);
+});
\ No newline at end of file
diff --git a/js/story-interpreter/world.dsl b/js/story-interpreter/world.dsl
new file mode 100644
index 0000000..3e75a7a
--- /dev/null
+++ b/js/story-interpreter/world.dsl
@@ -0,0 +1,32 @@
+room "Kitchen" {
+    description "A small, cozy kitchen. There's a smell of cookies baking."
+    
+    item "Cookie Jar" {
+        description "A ceramic jar filled with delicious cookies."
+        action "take" {
+            effect "You take a cookie from the jar."
+        }
+    }
+
+    animal "Cat" {
+        description "A small black cat is sitting on the counter."
+        action "talk" {
+            effect "The cat meows at you."
+        }
+    }
+
+    connection "north" to "Living Room"
+}
+
+room "Living Room" {
+    description "A large living room with a comfortable couch and a TV."
+    
+    item "Remote Control" {
+        description "A remote control for the TV."
+        action "use" {
+            effect "You turn on the TV. The news is on."
+        }
+    }
+
+    connection "south" to "Kitchen"
+}
\ No newline at end of file