|
@@ -3,6 +3,7 @@ const util = require("util");
|
|
|
|
|
|
const Stack = require("./Stack");
|
|
|
const ComputerParameterMode = require("./ComputerParameterMode");
|
|
|
+const InputModes = require("./InputModes");
|
|
|
const { DeepClone } = require("./common");
|
|
|
|
|
|
module.exports = class Computer {
|
|
@@ -17,6 +18,7 @@ module.exports = class Computer {
|
|
|
* @param {number} options.tickRate The number of milliseconds between calls to Execute. Initializes to 0.
|
|
|
* @param {boolean} options.inputFromConsole When true, the computer will prompt for input on the console. If false, it will check for an linked computer and, if one exists, will wait for input from that computer.
|
|
|
* @param {boolean} options.outputToConsole When true, the computer will print the output of opcode 4 to the console. If false, it will check for an linked computer and, if one exists, pass the output to that computer.
|
|
|
+ * @param {number[]} options.inputModeMap Map calls to the INPUT opcode to user input or the input array
|
|
|
*/
|
|
|
constructor(stack, options = {}) {
|
|
|
this._initialMemory = DeepClone(stack);
|
|
@@ -53,6 +55,7 @@ module.exports = class Computer {
|
|
|
tickRate: options.tickRate ?? 0,
|
|
|
inputFromConsole: options.inputFromConsole ?? false,
|
|
|
outputToConsole: options.outputToConsole ?? false,
|
|
|
+ inputModeMap: options.inputModeMap ?? [],
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -263,21 +266,35 @@ module.exports = class Computer {
|
|
|
Operation_Input() {
|
|
|
const outputPosition = this.stack.Next().Get(ComputerParameterMode.IMMEDIATE_MODE);
|
|
|
|
|
|
+ /** A variable to store the input in before putting it on the stack */
|
|
|
let userInput;
|
|
|
+ /** The input mode to use to get the value */
|
|
|
+ let inputMode = this.options.inputModeMap.shift();
|
|
|
|
|
|
- if (this.runtimeInput !== null) {
|
|
|
- userInput = this.runtimeInput;
|
|
|
- this.runtimeInput = null;
|
|
|
+ // If no input mode was found, attempt to set on using the runtime options
|
|
|
+ if (inputMode === undefined) {
|
|
|
+ if (this.options.inputFromConsole) { inputMode = InputModes.INPUT_FROM_CONSOLE; }
|
|
|
+ else { inputMode = InputModes.INPUT_FROM_RUNTIME_STACK; }
|
|
|
}
|
|
|
- else if (this.options.inputFromConsole) {
|
|
|
- do {
|
|
|
- userInput = Number(prompt("Please enter a number: "));
|
|
|
- } while (Number.isNaN(userInput));
|
|
|
- }
|
|
|
- else {
|
|
|
- throw new Error("No input found");
|
|
|
+
|
|
|
+ // Get the input based on the input mode
|
|
|
+ switch (inputMode) {
|
|
|
+ case InputModes.INPUT_FROM_RUNTIME_STACK: {
|
|
|
+ userInput = this.runtimeInput;
|
|
|
+ this.runtimeInput = null;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case InputModes.INPUT_FROM_CONSOLE: {
|
|
|
+ do {
|
|
|
+ userInput = Number(prompt("Please enter a number: "));
|
|
|
+ } while (Number.isNaN(userInput));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ throw new Error("No input found");
|
|
|
}
|
|
|
|
|
|
+ // Put the input value onto the stack
|
|
|
this.stack.Put(outputPosition, userInput);
|
|
|
}
|
|
|
|