Code Explanation
I made three event emitters that fire off one after the other. They receive input from the console and manipulate data in several ways.
const eventEmitter = require('events');
const firEmitter = new eventEmitter();
const secEmitter = new eventEmitter();
const thiEmitter = new eventEmitter();
const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);
// global variables
let fight = false;
let run = false;
let joke = false;
let cubed = null;
These are variable declarations so I can use them globally across the entire script file. First, I called in the event module to create three separate event emitters. It also sets up readline which will allow me to accept user input from the console. The global variables are used to store states across different events so I can track user choices and store a calculated value.
// first emitter: cube number processing
firEmitter.on('event', (root) => {
if (isNaN(root)) {
console.log('Please enter a valid number.');
} else {
let cubeRaw = root * root * root;
cubed = cubeRaw.toFixed(2);
console.log(`${root} cubed is ${cubed}.`)
secEmitter.emit('event');
}
});
This makes an event listener that processes a number argument when the 'event' event is fired. First there's validation to see if the argument 'root' is a valid number, if not then it prints an error message. Else, it cubes the number, formats it to two decimals places, stores it in a global variable called cubed, and prints the result. Finally, it triggers the next event for the secEmitter.
// second emitter: story choices
secEmitter.on('event', () => {
console.log('A funny looking goblin man jumps out of the bushes! He has a big hammer.');
rl.question('Will you: 1. Fight! 2. Run! 3. Tell a joke! ', (ans) => {
// user input processing
if (ans === '1' || ans === '1. Fight!' || ans === 'Fight' || ans === 'fight') {
fight = true; // state change
console.log(`You chose Fight.`);
console.log(`You bonk him on the head! The goblin squeaks and runs away crying. You monster!`);
thiEmitter.emit('event');
} else if (ans === '2' || ans === '2. Run!' || ans === 'Run' || ans === 'run') {
run = true; // state change
console.log(`You chose Run.`);
console.log(`You hear distant goblin screeching as you run away. It seems like he wanted to tell you something.`);
thiEmitter.emit('event');
} else if (ans === '3' || ans === '3. Tell a joke!' || ans === 'Tell a joke' || ans === 'tell a joke') {
joke = true; // state change
console.log(`You chose to tell a joke.`);
console.log(`The goblin drops his hammer and laughs so hard he falls over. He gives you a bunch of gold!`);
thiEmitter.emit('event');
} else {
console.log(`${ans} is not a valid choice. Please choose one of the options.`);
}
rl.close();
})
This is the second event. It prints a goblin encounter then asks a question through readline to grab user input from the console. Based on what the user types, it checks possibilites through the if/else statements then prints a story outcome depending on each choice. Finally, it triggers the next event and closes the readline with rl.close().
// third emitter: results
thiEmitter.on('event', () => {
let random = Math.floor(Math.random() * Math.PI * cubed);
if (fight === true) {
console.log(`You dealt ${random} points of damage.`);
} else if (run === true) {
console.log(`You ran ${random} miles!`);
} else if (joke === true) {
console.log(`He gave you ${random} gold pieces.`);
} else {
console.log(`Error.`);
}
});
This is the third event. It calculates a random number times Pi times cubed which creates a different variable each time it runs. Then it check which action the user chose, fight, run, or joke using booleans. Depending on the choice, it prints a different message showing dynamic results. If none are true, it prints an error message to help debug.
// start program
firEmitter.emit('event', 67);
This starts our entire event chain by emitting the 'event' event in 'firEmitter' and also passing 67 as the root argument.