Reglike: A simple roguelike written in Regex!

2 min read Original article ↗
<!DOCTYPE html> <html> <head> <title>Reglike</title> <style> *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; height: 100%; background: #333; color: #bbb; font-family: sans-serif; } .game > .display { white-space: pre; font-family: monospace; font-size: 2rem; } .instructions { font-size: 1.2rem; padding: 0.5em; } </style> </head> <body> <div class="game"> <div class="display"></div> <form action="#" data-controls> <input type="text" name="action" /> <button type="submit">Submit</button> </form> </div> <div class="instructions"> Use the R, L, U, and D commands to move yourself (@) and attack monsters (1 and 2). </div> <script> "use strict"; var gameEl = document.querySelector(".game"); var display = document.querySelector(".display"); var controls = gameEl.querySelector("form[data-controls]"); var input = controls.querySelector("input[name=\"action\"]"); var BASE_BOARD = ` ████████████████ █.2..1112..██.1█ █.@.████2████2.█ █1.████1.2.1...█ ████████████████ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▌HP:3 │ LV:1▐ ▌XP: <▐ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ `.trim(); var state = { board: BASE_BOARD }; var code = [ [/@\.((?:.|\n)+)R$/gi, "\.@$1"], // move right [/\.@((?:.|\n)+)L$/gi, "@\.$1"], // move left [/\.((?:.|\n){16})@((?:.|\n)+)U$/gi, "@$1\.$2"], // move up [/@((?:.|\n){16})\.((?:.|\n)+)D$/gi, "\.$1@$2"], // move down [/@2((?:.|\n)+)R$/gi, "@1$1"], // attack right, 2 -> 1 [/@1((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)R$/gi, "\.@$1XP:$2|$3"], // kill monster R, add XP [/2@((?:.|\n)+)L$/gi, "1@$1"], // attack left, 2 -> 1 [/1@((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)L$/gi, "@\.$1XP:$2|$3"], // kill monster L, add XP [/2((?:.|\n){16})@((?:.|\n)+)U$/gi, "1$1@$2"], // attack up, 2 -> 1 [/1((?:.|\n){16})@((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)U$/gi, "@$1\.$2XP:$3|$4"], // kill monster U, add XP [/@((?:.|\n){16})2((?:.|\n)+)D$/gi, "@$11$2"], // attack down, 2 -> 1 [/@((?:.|\n){16})1((?:.|\n)+?)XP:(\|*) ((?:.|\n)+)D$/gi, "\.$1@$2XP:$3|$4"], // kill monster D, add XP [/LV:1((?:.|\n)+?)XP:\|{10}/, "LV:2$1XP: "], // level up (1 -> 2) [/LV:2((?:.|\n)+?)XP:\|{10}/, "LV:3$1XP: "], // level up (1 -> 2) [/[^\n]+$/, ""] // remove command from buffer ]; var colors = [ [/[▄▐▌▀│<]+|█/g, "#fff"], [/HP:(\d)/, "#0d0"], [/LV:(\d)/, "#77e"], [/@/, "#ddf"], ]; function harvest() { return state.board + "\n" + input.value; } function step() { var value = harvest(); code.forEach(function(pair) { value = value.replace(pair[0], pair[1]); }); state.board = value.trim(); show(); } function colorize(board) { colors.forEach(function(pair) { var a = pair[0]; var b = pair[1]; board = board.replace(a, `<span style="color: ${ b }">$&</span>`); }); return board; } function show() { display.innerHTML = colorize(state.board); input.value = ""; } controls.addEventListener("submit", function(e) { e.preventDefault(); step(); return false; }); show(); </script> </body> </html>