Skip to content

Instantly share code, notes, and snippets.

@phase
Created December 5, 2015 20:06
Show Gist options
  • Save phase/75db61e40069e467d30c to your computer and use it in GitHub Desktop.
Save phase/75db61e40069e467d30c to your computer and use it in GitHub Desktop.
labyrinth.js golfed
/*jshint esnext: true */
//Note labyrinth X Y are swapped!
//Syntax highlighting?
//Wall = black
//Bigint library?
//Use: https://developers.google.com/web/updates/2014/05/Web-Animations-element.animate-is-now-in-Chrome-36
//Save option
//a => ASCII code (Explanation of the commands)
//Fix spider threads
var pointer; //pointer
var labyrinth; //(labyrinth)code
var main,aauxiliary; //(main, auxiliary)stacks, main.length-1=top
var direction; //N=0,E=1,S=2,W=3;
var inpLoc;
var sucide;
var step;
var debug;
//var p,l,m,a,d,il,su,st,de;
// pointer,labyrinth, main, auxiliary, direction, inpLoc, su
function mod(x, y) {
return ((x % y) + y) % y;
}
Array.prototype.top = function() {
if (this.length === 0) {
return 0;
}
return this[this.length - 1];
};
Array.prototype._pop = Array.prototype.pop;
Array.prototype.pop = function(x) {
var temp = this._pop();
return temp !== undefined ? temp : 0;
};
function reset() {
p = [0, 0];
labyrinth = lab.innerHTML.replace(/\[/g, " ").replace(/\]/g, " ").split("<br>");
var maxLength = 0;
for (var i = 0; i < labyrinth.length; i++) {
if (maxLength < labyrinth[i].length)
maxLength = labyrinth[i].length;
}
for (i = 0; i < labyrinth.length; i++) {
labyrinth[i] = (labyrinth[i] + " ".repeat(maxLength - labyrinth[i].length)).split("");
}
loop:
for (i = 0; i < labyrinth.length; i++) {
for (j = 0; j < labyrinth[i].length; j++) {
if (labyrinth[i][j] !== " ") {
p = [j, i];
break loop;
}
}
}
main = [];
auxiliary = [];
direction = 1;
sucide = false;
inpLoc = 0;
step = 1;
O.value = "";
}
function run() {
reset();
if (debug) {
spiderContainer.innerHTML = "";
debugButton.disabled = false;
lab.contentEditable = false;
}
//Start if
if (lab.innerHTML.replace(/\[/g, "").replace(/\]/g, "").replace(/<br>/, "") !== "") {
if (!debug) {
while (!sucide) {
updatePointer();
}
} else {
updatePointer();
}
} else {
stepButton.disabled = "disabled";
lab.contentEditable = "true";
}
}
function updatePointer() {
if (sucide) {
stepButton.disabled = "disabled";
lab.contentEditable = "true";
pointerOverlay.innerHTML = "";
return -1; //End
}
stepDiv.innerHTML = step;
step++;
execChar(labyrinth[p[1]][p[0]]);
if (dir() != -1) {
var currentDir = mod(direction, 4);
deb.value =
"Pointer: " + p +
"\nCommand: " + labyrinth[p[1]][p[0]] +
"\nMain [" + main + " | " + auxiliary.slice().reverse() + "] Auxiliary";
if (debug) {
pointerOverlay.innerHTML = "\n".repeat(p[1]) + " ".repeat(p[0]) + (currentDir === 0 ? "▲" : currentDir == 1 ? "►" : currentDir == 2 ? "▼" : currentDir == 3 ? "◄" : "X");
}
if (currentDir === 0) {
p[1] --;
} else if (currentDir == 1) {
p[0] ++;
} else if (currentDir == 2) {
p[1] ++;
} else if (currentDir == 3) {
p[0] --;
}
}
}
function updateGrid() {
lab.innerHTML = "";
labyrinth.forEach(s => lab.innerHTML += s.join("") + "\n");
}
function rotVert(rotWhich) {
var temp;
for (var i = 0; i < labyrinth.length; i++) {
if (i === 0) {
temp = labyrinth[0][rotWhich];
}
if (i == labyrinth.length - 1) {
labyrinth[i][rotWhich] = temp;
} else {
labyrinth[i][rotWhich] = labyrinth[i + 1][rotWhich];
}
if (labyrinth[i][rotWhich] === undefined) {
labyrinth[i].splice(rotWhich, 1);
}
}
}
function rotVert2(rotWhich) {
var temp;
for (var i = labyrinth.length - 1; i >= 0; i--) {
if (i == labyrinth.length - 1) {
temp = labyrinth[i][rotWhich];
}
if (i === 0) {
labyrinth[i][rotWhich] = temp;
} else {
labyrinth[i][rotWhich] = labyrinth[i - 1][rotWhich];
}
if (labyrinth[i][rotWhich] === undefined) {
labyrinth[i].splice(rotWhich, 1);
}
}
}
function lookAt(d) {
if (mod(d, 4) === 0) {
try {
return labyrinth[p[1] - 1][p[0]];
} catch (e) {
return " ";
}
} else if (mod(d, 4) == 1) {
try {
return labyrinth[p[1]][p[0] + 1];
} catch (e) {
return " ";
}
} else if (mod(d, 4) == 2) {
try {
return labyrinth[p[1] + 1][p[0]];
} catch (e) {
return " ";
}
} else if (mod(d, 4) == 3) {
try {
return labyrinth[p[1]][p[0] - 1];
} catch (e) {
return " ";
}
}
}
function isWall(d) {
if (lookAt(d) == " " || lookAt(d) === undefined) {
return true;
} else {
return false;
}
}
function dir() {
var dracula = 0;
if (!isWall(0)) {
dracula++;
}
if (!isWall(1)) {
dracula++;
}
if (!isWall(2)) {
dracula++;
}
if (!isWall(3)) {
dracula++;
}
if (dracula == 4) {
if (main.top() < 0) {
direction -= 1;
} else if (main.top() > 0) {
direction += 1;
}
} else if (dracula == 3) {
if (main.top() < 0) {
direction -= 1;
} else if (main.top() > 0) {
direction += 1;
}
if (isWall(direction)) {
direction += 2;
}
} else if (dracula == 2) {
if (isWall(direction + 2)) {
if (isWall(direction)) {
//Special case
if (main.top() < 0) {
direction -= 1;
} else if (main.top() > 0) {
direction += 1;
} else {
direction += Math.random() < 0.5 ? -1 : 1;
}
} else {
//Keep moving..
}
} else {
for (var i = 0; i <= 3; i++) {
if (!isWall(i) && i != mod((direction + 2), 4)) {
direction = i;
break;
}
}
}
} else if (dracula == 1) {
if (!isWall(0)) {
direction = 0;
} else
if (!isWall(1)) {
direction = 1;
} else
if (!isWall(2)) {
direction = 2;
} else
if (!isWall(3)) {
direction = 3;
}
} else {
return -1;
}
}
function execChar(char) {
var a;
var b;
if (/\d/.exec(char)) {
main.push(main.pop() * 10 + (+char));
} else switch (char) {
case '!':
O.value += main.pop();
break;
case '"': //Nothing...
break;
case '#':
main.push(main.length);
break;
case '$':
main.push(main.pop() ^ main.pop());
break;
case '%':
a = main.pop();
b = main.pop();
main.push(mod(b, a));
break;
case '&':
main.push(main.pop() & main.pop());
break;
case "'":
//Debug-Unimplemented
break;
case '(':
main.push(main.pop() - 1);
break;
case ')':
main.push(main.pop() + 1);
break;
case '*':
main.push(main.pop() * main.pop());
break;
case '+':
main.push(main.pop() + main.pop());
break;
case ',':
a = I.value.charCodeAt(inpLoc);
if (Number.isNaN(a)) {
main.push(-1);
} else {
main.push(a);
inpLoc++;
}
break;
case '-':
a = main.pop();
b = main.pop();
main.push(b - a);
break;
case '.':
O.value += String.fromCharCode(mod(main.pop(), 256));
break;
case '/':
a = main.pop();
b = main.pop();
if (a === 0) {
sucide = true;
throw "Stop that";
}
main.push(Math.floor(b / a));
break;
case ':':
main.push(main.top());
break;
case ';':
main.pop();
break;
case '<':
//MOVE IP
b = main.pop();
a = mod(p[1] + b, labyrinth.length);
labyrinth[a].push(labyrinth[a].shift());
updateGrid();
if (b === 0) {
p[0] = mod(p[0] - 1, labyrinth[a].length);
}
break;
case '=':
a = main.pop();
b = auxiliary.pop();
main.push(b);
auxiliary.push(a);
break;
case '>':
//MOVE IP
b = main.pop();
a = mod(p[1] + b, labyrinth.length);
labyrinth[a].unshift(labyrinth[a].pop());
updateGrid();
if (b === 0) {
p[0] = mod(p[0] + 1, labyrinth[a].length);
}
break;
case '?':
try {
a = I.value.substr(inpLoc);
b = (+(/[\+-]?\d+/.exec(a)[0]));
main.push(b);
inpLoc += a.search(/[\+-]?\d+/) + (b + "").length;
} catch (e) {
main.push(0);
inpLoc = I.value.length;
}
break;
case '@':
sucide = true;
break;
case '\\':
O.value += "\n";
break;
case '^':
b = main.pop();
a = mod(p[0] + b, labyrinth[p[1]].length);
rotVert(a);
updateGrid();
if (b === 0) {
p[1] = mod(p[1] - 1, labyrinth.length);
}
break;
case '_':
main.push(0);
break;
case '`':
main.push(-main.pop());
break;
case 'v':
b = main.pop();
a = mod(p[0] + b, labyrinth[p[1]].length);
rotVert2(a);
updateGrid();
if (b === 0) {
p[1] = mod(p[1] + 1, labyrinth.length);
}
break;
case '{':
main.push(auxiliary.pop());
break;
case '|':
main.push(main.pop() | main.pop());
break;
case '}':
auxiliary.push(main.pop());
break;
case '~':
main.push(~main.pop());
break;
}
}
//Spiders
function spider() {
if (document.cookie.split("youWereHere=")[1] === undefined) {
stepButton.disabled = false;
document.cookie = "youWereHere=yep";
debugButton.disabled = 'disabled';
var spiderImg = document.createElement('img');
spiderImg.src = "http://i.imgur.com/fsYfS9H.png"; //http://i.imgur.com/PRPmqMJ.gif
spiderImg.className = "spider";
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'line');
svg.setAttribute("stroke-width", 2);
var rn = Math.random() * 10 + 5;
for (var i = 0; i < rn; i++) {
var tempSpider = spiderImg.cloneNode(true);
var left = Math.min(Math.random() * innerWidth, innerWidth - 50);
var top = -Math.random() * 300;
tempSpider.style.left = left - 26 + "px";
tempSpider.style.top = top - 5 + "px";
var tempSvg = svg.cloneNode(true);
tempSvg.setAttribute("y1", top - innerHeight - 100);
tempSvg.setAttribute("y2", top);
tempSvg.setAttribute("x1", left);
tempSvg.setAttribute("x2", left);
spiderContainer.appendChild(tempSpider);
svgId.appendChild(tempSvg);
// Make sure the initial state is applied.
window.getComputedStyle(tempSpider).transform; // jshint ignore:line
window.getComputedStyle(tempSvg).transform; // jshint ignore:line
tempSpider.style.transform = "translateY(" + (innerHeight + 48 + top) + "px)";
tempSvg.style.transform = "translateY(" + (innerHeight + 48 + top) + "px)";
}
setTimeout(fallDown, 2500);
debug = true;
setTimeout(run, 4000);
} else {
debug = true;
stepButton.disabled = false;
run();
}
}
function fallDown() {
svgId.innerHTML = "";
var spiders = document.getElementsByClassName("spider");
for (var i = 0; i < spiders.length; i++) {
spiders[i].style.top = innerHeight + "px";
}
}
//Textarea auto-resize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment