UNPKG

ktane-solver

Version:
582 lines (325 loc) 13.5 kB
# ktane-solver A JavaScript library to solve the vanilla bomb modules from [Keep Talking and Nobody Explodes](https://keeptalkinggame.com/). ## 📥 Installing `npm i ktane-solver` ## 📖 Terms - **Bomb** - the device which holds an amount of modules. - **Modules** - a device which contains a single, solvable puzzle which needs to be solved by the Defuser. - **Needy Modules** - a device which contains a single, unsolvable puzzle which needs to be regularly tended to by the Defuser. - **Stage** - a section or part of a module, indicated by a green LED on the right side of the module. - **Defuser** - the person that has sole access to the bomb. - **Expert(s)** - the person/people that has/have sole access to the Bomb Defusal Manual. - **"bomb check"** - the process of gathering information about the bomb. - **"display number" or "display letter"** - the big number/letter at the top of some modules. ## 💣 The Bomb object Some modules require information about the bomb in order to solve. - `digit: int` - the last digit of the serial code. - `vowel: boolean` - if the serial code contains a vowel. - `car: boolean` - if the bomb has a CAR lit indicator. - `frk: boolean` - if the bomb has a FRK lit indicator. - `pport: boolean` - if the bomb has a parallel port. - `batteries: int` - the amount of batteries on the bomb. **Methods** - `add_strike()` - Add a strike to the bomb. - `reset_strikes()` - Reset the bomb's strike count. - `reset_memory()` - Reset the Memory module. This is called automatically after solving the Memory module. - `reset_sequence()` - Reset the Sequence module. This is called automatically after solving the Sequence module. **Example** ```js let bomb = new Bomb(2, true, false, true, true, 1) ``` This creates a bomb instance that has: - A serial code with a vowel, and an even number as the last digit - For example: `AWXYZ2` - No CAR lit indicator - A FRK lit indicator - A parallel port - 1 battery --- ## 🧩: Modules More information about the modules, as well as how to solve them, can be found at the [Bomb Defusal Manual](https://www.bombmanual.com/). ### ✂️ Wires **Input** - `wires: Array<String>` - a String array with each wire colour. - Possible colours: `red`, `blue`, `yellow`, `black`, `white` - `bomb: Object` - an instance of the bomb object. **Output** - `int` - The index of the wire that should be cut based on the array passed, starting from 0. **Throws** - If the amount of wires is incorrect. **Example** ```javascript import Bomb from "ktane-solver/bomb" import Wires from "ktane-solver/wires" let bomb = new Bomb(2, true, false, false, true, 1) Wires.solve(["red", "blue", "blue"], bomb) >> 2 ``` --- ### 🔴 Button **Input for part 1** - `button: String` - a String describing the button's colour and text, in that order. - Possible colours: `red`, `blue`, `yellow`, `black`, `white` - Possible texts: `abort`, `detonate`, `hold`, `press` - `bomb: Object` - an instance of the bomb object. **Output for part 1** - `String` - What the Defuser should with the button after pressing it. - `"HOLD"` - the button should be pressed and held. - `"RELEASE"` - the button should be pressed and immediately released. **Throws** - If either `colour` or `text` are undefined. **Input for part 2** - `strip: String` - a String describing the colour of the strip. - Possible colours: `red`, `blue`, `yellow`, `white` **Output for part 2** - `String` When the button should be released. - `"1"` - the button should be released when the countdown timer has a 1 in any position. - `"4"` - the button should be released when the countdown timer has a 4 in any position. - `"5"` - the button should be released when the countdown timer has a 5 in any position. **Examples** *Part 1 example* ```javascript import Bomb from "ktane-solver/bomb" import Wires from "ktane-solver/button" let bomb = new Bomb(2, true, false, false, true, 1) Button.solvePartOne("red detonate", bomb) >> "HOLD" ``` *Part 2 example* ```js import Bomb from "ktane-solver/bomb" import Wires from "ktane-solver/button" let bomb = new Bomb(2, true, false, false, true, 1) Button.solvePartTwo("blue") >> 4 ``` --- ### 🔑 Keypad **Input** - `symbols: Array<String>` - a String array with each symbol description - A list of [each symbol, and their name, can be found here](./resources/README.md). **Output** - `Array<String>` - The order at which the symbols should be pressed. **Throws** - If exactly 4 symbols aren't passed. - If any symbol(s) aren't recognised. - If a solution for the given symbols isn't found. **Example** ```javascript import Keypad from "ktane-solver/keypad" Keypad.solve(["kitty", "curly h", "at", "reverse c"]) >> ["at", "kitty", "curly h", "reverse c"] ``` --- ### 💬 Simon Says **Input** - `colours: Array<String>` - a String array with each colour. - Possible colours: `red`, `blue`, `yellow`, `green` - `bomb: Object` - an instance of the bomb object. **Output** - `Array<String>` - The colours that the Defuser should press, in order. **Example** ```js import Bomb from "ktane-solver/bomb" import SimonSays from "ktane-solver/simonsays" let bomb = new Bomb(2, true, false, false, true, 1) SimonSays.solve(["red", "red", "blue"], bomb) >> [ "blue", "blue", "red" ] ``` --- ### 🗒️ Who's On First **Input** - `word: String` - the display word. **Output for part 1** - `String` - The position of the word on the module, that should be the input for part 2. - Possible positions: `TL` (top left), `TR` (top right), `ML` (middle left), `MR` (middle right), `BL` (bottom left), `BR` (bottom right) **Throws** - If a word is unrecognised. **Input for part 2** - `word: String` - the word, based on the position output from part 1. **Output for part 2** - `String` - A list of possible words, in order. The first word that both appears on the list, and on the module, should be pressed by the Defuser. **Throws** - If a word is unrecognised. **Examples** *Part 1 example* ```js import WhosOnFirst from "ktane-solver/whosonfirst" WhosOnFirst.solvePartOne("says") >> "BR" ``` *Part 2 example* ```js import WhosOnFirst from "ktane-solver/whosonfirst" WhosOnFirst.solvePartTwo("right") >> "YES, NOTHING, READY, PRESS, NO, WAIT, WHAT, RIGHT" ``` --- ### 🧠 Memory **Input** - `numbers: Array<int>` - an int array of the module's numbers, starting with the display number, and numbers below, in order from left-to-right. - `bomb: Object` - an instance of the bomb object. **Output** - `int` - The label of the button that the Defuser should press. **Throws** - If the passed array has more than 5 elements. - If the passed array contains a number that isn't 1, 2, 3, or 4. **Notes** - This module requires knowledge of previous stages, which is held in the bomb object. Make sure to pass the same bomb object in for each stage. - This module will automatically call `reset_memory()` after the module is solved. You can call this method prematurely if required. **Example** ```js import Bomb from "ktane-solver/bomb" import Memory from "ktane-solver/memory" let bomb = new Bomb(2, true, false, false, true, 1) Memory.solve([4,1,3,4,2], bomb) Memory.solve([3,3,1,2,4], bomb) Memory.solve([4,3,1,2,4], bomb) Memory.solve([2,2,4,1,3], bomb) Memory.solve([2,2,4,1,3], bomb) >> 2 >> 3 >> 4 >> 2 >> 3 ``` --- ### 💡 Morse Code **Input** - `morse: Array<String>` - a String array of Morse Code characters. **Output** - `Array<String>` - A list of the possible words, given the input; - `String` - OR the frequency that should be selected. **Throws** - If the translated word doesn't match to a frequency. **Example** ```js import Morse from "ktane-solver/morse" Morse.solve(["dot dot dot", "dot dot dot dot", "dot", "dot dash dot dot", "dot dash dot dot"]) >> 3.505 ``` --- ### 🐍 Complicated Wires **Input** - `wires: Array<String>` - a String array describing the wire colour(s), if there's a star, and if the light is on. - Possible colours, up to 2 at once: `red`, `white`, `blue` - `bomb: Object` an instance of the bomb object. **Output** - `Array<boolean>` - A list of Booleans describing if each wire should be cut. - `true` - cut the wire. - `false` - don't cut the wire. **Throws** - If a colour is unrecognised. **Notes** - If there's no star, you don't need to include "star" in the wire description. - If the light isn't on, you don't need to include "light" in the wire description. - The order of each wire description doesn't matter. i.e. `light red star`, `red star light`, and `star light red` are all equivalent and valid inputs. - The order of each wire colour doesn't matter. i.e. `red blue` and `blue red` are the both equivalent and valid inputs. **Example** ```js import Bomb from "ktane-solver/bomb" import Complicated from "ktane-solver/complicated" let bomb = new Bomb(2, true, false, false, true, 1) Complicated.solve(["white star", "red star", "red star", "blue star", "light blue star", "light red white star"], bomb) >> [ true, true, true, false, true, false ] ``` --- ### 🌽 Maze **Input** - `ind: Array<int>` - an int array of the position of either green indicator. - `start: Array<int>` - an int array of the position of the white light. - `end: Array<int>` - an int array of the position of the red triangle. **Output** - `Array<String>` - A list of directions that the Defuser should input into the module. - Possible directions: `UP`, `DOWN`, `LEFT`, `RIGHT` **Throws** - If the green indicator is unrecognised. **Notes** - Each position counts from 1. - The position follows the following notation: across first, then down. - Only one green indicator is required to identify the correct maze. - This solution uses a modified version of [this maze-solving algorithm](https://stackoverflow.com/a/52146134/12865020). Thank you trincot. **Example** ```js import Maze from "ktane-solver/maze" Maze.solve([3, 5], [6, 4], [1, 5]) >> ['DOWN', 'LEFT', 'UP', 'UP', 'RIGHT', 'UP', 'UP', 'LEFT', 'DOWN', 'LEFT', 'DOWN', 'DOWN', 'DOWN', 'DOWN', 'LEFT', 'LEFT', 'LEFT', 'UP' ] ``` *Based on this maze configuration:* ![](/resources/mazeexample.png) --- ### 🌈 Wire Sequence **Input** - `wires: Array<String>` - a String array describing the wire colour, and the letter it routes to. - Possible colours: `red`, `black`, `blue` - Possible letters: `A`, `B`, `C` - `bomb: Object` an instance of the bomb object. **Output** - `Array<boolean>` - A list of Booleans describing if each wire should be cut. - `true` - cut the wire. - `false` - don't cut the wire. **Throws** - If a colour is unrecognised. - If a letter is unrecognised. **Notes** - The number on the left side of the module is not required to solve. - This module requires knowledge of previous stages, which is held in the bomb object. Make sure to pass the same bomb object in for each stage. - This module will automatically call `reset_sequence()` after the module is solved. You can call this method prematurely if required. **Example** ```js import Bomb from "ktane-solver/bomb" import Sequence from "ktane-solver/sequence" let bomb = new Bomb(2, true, false, false, true, 1) Sequence.solve(["black a", "black b"], bomb) Sequence.solve(["red c", "red a", "red c"], bomb) Sequence.solve(["red a"], bomb) Sequence.solve(["blue b", "red a", "blue b"], bomb) >> [ true, false ] >> [ true, false, false ] >> [ true ] >> [ true, false, false ] ``` --- ### ⌨️ Password **Input** - `columns: Array<String>` - a String array describing each letter in each column. **Output** - `Array<String>` - A list of the possible passwords **Throws** - If the passed array isn't exactly 5 elements long (pad your input with empty strings, if needs be). **Notes** - Partial inputs (empty strings) are accepted. - Check if the returned array's length is 1 to determine the password. **Examples** ```js import Password from "ktane-solver/password" Password.solve(["kqtfhy", "hwjfus", "rinybk", "ynukj", "ipkxvc"]) >> ["THINK"] ``` ```js import Password from "ktane-solver/password" Password.solve(["tghus", "", "", "", "tnehr"]) >> [ "GREAT", "HOUSE", "THEIR", "THERE", "THESE", "THREE" ] ``` --- ## 🍞 Needy Modules Only one module, Knob, requires any logic. Venting Gas, and Capacitor Discharge can be handled by the Defuser. ### 🎛️ Knob **Input** - `lights: String` - the condition of each light. - `1` - the light is on. - `0` - the light is off. **Output** - `String` - The direction that the knob should be pointed. **Throws** - If a light sequence is unrecognised. **Notes** - Only the left-hand side of the lights are required to solve this module. - The order should be left-to-right, top-to-bottom. **Example** ```js import Knob from "ktane-solver/knob" Knob.solve("101111") >> RIGHT ```