Last active
July 19, 2018 19:35
-
-
Save Reconcyl/e2cbe9cc55a7cd075f2a1f00b0ae2cba to your computer and use it in GitHub Desktop.
Modilar SNISP stack snippet (https://codegolf.stackexchange.com/questions/168906/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<link href="main.css" rel="stylesheet" type="text/css"> | |
</head> | |
<body> | |
<b>Code:</b> | |
<br/> | |
<textarea id="code" width="300" height="300"></textarea> | |
<br/> | |
<button id="run-button" onclick="run()">Run</button> | |
<button id="stop-button" onclick="stop()" style="display: none;">Stop</button> | |
<br/> | |
<div id="execution-display"></div> | |
<script src="main.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#code { | |
font-family: monospace; | |
} | |
#execution-display { | |
font-family: monospace; | |
white-space: pre; | |
} | |
.highlight { | |
background-color: yellow; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let TICKS_PER_SECOND = 5; | |
let INTERVAL_MS = 1000 / TICKS_PER_SECOND; | |
let runButton = document.getElementById("run-button"); | |
let stopButton = document.getElementById("stop-button"); | |
let code = document.getElementById("code"); | |
let executionArea = document.getElementById("execution-display"); | |
let intervalId; | |
function htmlEscape(string) { | |
let node = document.createElement("span"); | |
node.innerText = string; | |
return node.innerHTML; | |
} | |
let snisp = { | |
x: null, | |
y: null, | |
direction: null, | |
callStack: null, | |
stopped: null, | |
playfield: null, | |
padRows: function() { | |
let maxLength = Math.max(...this.playfield.map(e => e.length)); | |
for (let i = 0; i < this.playfield.length; i++) { | |
this.playfield[i] = this.playfield[i].padEnd(maxLength, "."); | |
} | |
}, | |
initialize: function() { | |
this.x = 0; | |
this.y = 0; | |
this.direction = "right"; | |
this.callStack = []; | |
this.stopped = false; | |
this.playfield = code.value.split("\n"); | |
this.padRows(); | |
this.update(); | |
}, | |
getCurrentChar: function() { | |
let row = this.playfield[this.y]; | |
if (row == undefined) return; | |
return row[this.x]; | |
}, | |
backslashMirror: function() { | |
let table = { | |
"up": "left", | |
"right": "down", | |
"down": "right", | |
"left": "up", | |
}; | |
this.direction = table[this.direction]; | |
}, | |
slashMirror: function() { | |
let table = { | |
"up": "right", | |
"right": "up", | |
"down": "left", | |
"left": "down", | |
}; | |
this.direction = table[this.direction]; | |
}, | |
forward: function() { | |
switch (this.direction) { | |
case "up": | |
this.y -= 1; | |
break; | |
case "down": | |
this.y += 1; | |
break; | |
case "left": | |
this.x -= 1; | |
break; | |
case "right": | |
this.x += 1; | |
break; | |
default: | |
throw "direction is invalid"; | |
} | |
}, | |
pushState: function() { | |
this.callStack.push({ | |
x: this.x, | |
y: this.y, | |
direction: this.direction, | |
}); | |
}, | |
restoreState: function() { | |
let state = this.callStack.pop(); | |
if (state == undefined) { | |
this.stopped = true; | |
return; | |
} | |
this.x = state.x; | |
this.y = state.y; | |
this.direction = state.direction; | |
}, | |
tick: function() { | |
if (this.stopped) return; | |
let currentChar = this.getCurrentChar(); | |
if (currentChar == undefined) { | |
this.stopped = true; | |
return; | |
} | |
switch (currentChar) { | |
case "\\": | |
this.backslashMirror(); | |
break; | |
case "/": | |
this.slashMirror(); | |
break; | |
case "!": | |
this.forward(); | |
break; | |
case "@": | |
this.pushState(); | |
break; | |
case "#": | |
this.restoreState(); | |
this.forward(); | |
break; | |
default: | |
break; | |
} | |
this.forward(); | |
}, | |
generatePlayfieldHTML: function(stateX, stateY) { | |
let playfieldLines = []; | |
for (let y = 0; y < this.playfield.length; y++) { | |
let chars = []; | |
let row = this.playfield[y]; | |
for (let x = 0; x < row.length; x++) { | |
let c = htmlEscape(row[x]); | |
if (x == stateX && y == stateY) { | |
c = '<span class="highlight">' + c + '</span>'; | |
} | |
chars.push(c); | |
} | |
playfieldLines.push(chars.join("")); | |
} | |
return playfieldLines.join("<br>"); | |
}, | |
update: function() { | |
let playfields = []; | |
for (let i = 0; i < this.callStack.length; i++) { | |
let state = this.callStack[i]; | |
playfields.push(this.generatePlayfieldHTML(state.x, state.y)); | |
} | |
playfields.push(this.generatePlayfieldHTML(this.x, this.y)); | |
let playfieldHTML = playfields.join("<br><br>"); | |
executionArea.innerHTML = playfieldHTML; | |
}, | |
}; | |
function tick() { | |
snisp.tick(); | |
snisp.update(); | |
} | |
function run() { | |
runButton.style.display = "none"; | |
stopButton.style.display = ""; | |
code.style.display = "none"; | |
executionArea.style.display = ""; | |
snisp.initialize(); | |
intervalId = setInterval(tick, INTERVAL_MS); | |
} | |
function stop() { | |
runButton.style.display = ""; | |
stopButton.style.display = "none"; | |
code.style.display = ""; | |
executionArea.style.display = "none"; | |
clearInterval(intervalId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment