kirupa
December 11, 2019, 5:55pm
1
If you’ve ever played some old-school/classic video games published by the game company Konami, you may have entered (or heard of) the following sequence of button presses:
This is a companion discussion topic for the original entry at https://www.kirupa.com/html5/konami_code.htm
kirupa
December 13, 2019, 5:43pm
2
Below is my attempt at solving this, which I explain the ins and outs of in the article:
let keys = {
37: "left",
38: "up",
39: "right",
40: "down",
65: "a",
66: "b"
};
let konamiCode = ["up", "up", "down", "down", "left", "right", "left", "right", "b", "a"];
let keyCount = 0;
let timerID;
document.addEventListener("keydown", checkCode, false);
function checkCode(e) {
let keyPressed = keys[e.keyCode];
if (keyPressed === konamiCode[keyCount]) {
keyCount++;
// clear timer
window.clearTimeout(timerID);
// start timer with a 1 second delay before resetting state
timerID = window.setTimeout(resetKeyState, 1000);
// check if we are still on the right path
if (keyCount === konamiCode.length) {
cheatCodeActivated();
resetKeyState();
}
} else {
resetKeyState();
}
}
function cheatCodeActivated() {
alert("Cheat code activated!");
}
function resetKeyState() {
console.log("Resetting state!");
window.clearTimeout(timerID);
keyCount = 0;
}
Here’s a nice convoluted example
class Deferred {
constructor () {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
}
}
function* iterateEvents (type) {
let nextEvent = new Deferred()
const onEvent = event => {
nextEvent.resolve(event)
nextEvent = new Deferred()
}
document.addEventListener(type, onEvent)
try {
while (true) {
yield nextEvent.promise
}
} finally {
document.removeEventListener(type, onEvent)
}
}
class Buffer {
static from (array) {
const buffer = new Buffer(array.length)
return buffer.push(...array)
}
constructor (length) {
this.length = length
this.data = Array(length).fill(undefined)
}
push (...values) {
this.data.push(...values)
this.data = this.data.slice(-this.length)
return this
}
values () {
return this.data.slice().values()
}
equals (buffer) {
return this.data.every((value, index) => value === buffer.data[index])
}
}
async function matchKeyboardSequence (sequence, timeoutTime, callback) {
let pressed
const clearPressed = () => pressed = new Buffer(sequence.length)
clearPressed()
let timeoutId
const resetTimeout = () => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
clearPressed()
resetTimeout()
}, timeoutTime)
}
resetTimeout()
for await (event of iterateEvents('keydown')) {
resetTimeout()
if (pressed.push(event.keyCode).equals(sequence)) {
clearPressed()
callback()
}
}
}
const konami = Buffer.from([38, 38, 40, 40, 37, 39, 37, 39, 66, 65])
matchKeyboardSequence(konami, 1000, () => alert('Cheat code activated!'))
1 Like