diff options
author | elioat <elioat@tilde.institute> | 2023-12-28 21:45:37 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2023-12-28 21:45:37 -0500 |
commit | b63f67c6596cb93da7db010b7fd390ff75f7e892 (patch) | |
tree | d1295b4fad260b7e1999ea262a06682a8399b492 | |
parent | 42ec1a26d1e2c671d0f64aaf14a5025910d95c9c (diff) | |
download | tour-b63f67c6596cb93da7db010b7fd390ff75f7e892.tar.gz |
*
-rw-r--r-- | js/story-interpreter/interpreter.js | 136 | ||||
-rw-r--r-- | js/story-interpreter/world.dsl | 32 |
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 |