From 89f2e3e5c59ce69850f6a61b543b305d30650a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Tue, 2 Jan 2018 17:11:15 +0100 Subject: [PATCH] befunge93_runner (FIN) --- www/data/css/styles.css | 11 +- www/data/css/styles_befungerunner.scss | 11 +- www/data/javascript/blogpost_bef93runner.js | 230 +++++++++++++++++++- www/fragments/befunge93_runner.php | 2 + www/fragments/blogview_euler_single.php | 18 +- 5 files changed, 243 insertions(+), 29 deletions(-) diff --git a/www/data/css/styles.css b/www/data/css/styles.css index 7c9c996..f94af1b 100644 --- a/www/data/css/styles.css +++ b/www/data/css/styles.css @@ -628,6 +628,9 @@ html, body { margin-left: auto; } .bce_code .bce_code_ctrl .ctrl_btn { user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; display: block; border: 1px solid #000; background: #444; @@ -677,7 +680,7 @@ html, body { flex-grow: 1; margin: 0 4px 4px 4px; border: 1px solid #888; - min-height: 200px; } + height: 200px; } .bce_code_out .bce_code_out_stack { font-family: Consolas, Monaco, "Courier New", Menlo, monospace; overflow-y: scroll; @@ -687,17 +690,17 @@ html, body { margin: 0 4px 4px 4px; width: 200px; border: 1px solid #888; - min-height: 200px; } + height: 200px; } @media (max-width: 767px) { .bce_code_out { flex-direction: column; } .bce_code_out .bce_code_out_text { flex-grow: 0; - min-height: 100px; } + height: 100px; } .bce_code_out .bce_code_out_stack { width: auto; - min-height: 150px; } } + height: 150px; } } .b93rnr_outpanel_hidden { visibility: collapse; display: none; } diff --git a/www/data/css/styles_befungerunner.scss b/www/data/css/styles_befungerunner.scss index daa4596..2a617eb 100644 --- a/www/data/css/styles_befungerunner.scss +++ b/www/data/css/styles_befungerunner.scss @@ -33,6 +33,9 @@ .ctrl_btn { user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; display: block; border: 1px solid #000; background: #444; @@ -83,7 +86,7 @@ flex-grow: 1; margin: 0 4px 4px 4px; border: 1px solid #888; - min-height: 200px; + height: 200px; } .bce_code_out_stack { @@ -95,15 +98,15 @@ margin: 0 4px 4px 4px; width: 200px; border: 1px solid #888; - min-height: 200px; + height: 200px; } } @media (max-width: 767px) { .bce_code_out { flex-direction: column; - .bce_code_out_text { flex-grow: 0; min-height: 100px;} - .bce_code_out_stack { width: auto; min-height: 150px;} + .bce_code_out_text { flex-grow: 0; height: 100px;} + .bce_code_out_stack { width: auto; height: 150px;} } } diff --git a/www/data/javascript/blogpost_bef93runner.js b/www/data/javascript/blogpost_bef93runner.js index a16aa7b..e769ca7 100644 --- a/www/data/javascript/blogpost_bef93runner.js +++ b/www/data/javascript/blogpost_bef93runner.js @@ -1,6 +1,13 @@ const BefState = Object.freeze ({ UNINIITIALIZED: {}, INITIAL: {}, RUNNING: {}, PAUSED: {} }); +Array.prototype.peek = function() { return this[this.length - 1]; }; +Array.prototype.revjoin = function(sep) { + let str=''; + for(let i=this.length-1; i >= 0;i--) {if (i t1); break; + case '>': this.delta = [+1,0]; break; + case '<': this.delta = [-1,0]; break; + case '^': this.delta = [0,-1]; break; + case 'v': this.delta = [0,+1]; break; + case '?': this.delta = [[+1,0],[-1,0],[0,+1],[0,-1]][Math.floor(Math.random()*4)]; break; + case '_': this.delta = [[-1,0],[+1,0]][ this.pop_b()?0:1 ]; break; + case '|': this.delta = [[0,-1],[0,+1]][ this.pop_b()?0:1 ]; break; + case '"': this.strmode = true; break; + case ':': this.push_i(this.peek_i()); break; + case '\\': t1 = this.pop_i(); t2 = this.pop_i(); this.push_i(t1); this.push_i(t2); break; + case '$': this.pop_i(); break; + case '.': this.output += this.pop_i() + ' '; break; + case ',': this.output += String.fromCharCode(this.pop_i()); break; + case '#': this.move(); break; + case 'p': t1 = this.pop_i(); t2 = this.pop_i(); t3 = this.pop_i(); this.gridset_i(t2, t1, t3); break; + case 'g': t1 = this.pop_i(); t2 = this.pop_i(); this.push_i(this.gridget_i(t2, t1)); break; + case '&': t1 = null; while (t1===null||t1===''||isNaN(parseInt(t1[0], 10))){t1=prompt("Input number",null);} this.push_i(parseInt(t1[0], 10)); break; + case '~': t1 = null; while (t1===null||t1===''){t1=prompt("Input character",null);} this.push_c(t1[0]); break; + case '@': this.delta = [0,0]; break; + case '0': this.push_i(0); break; + case '1': this.push_i(1); break; + case '2': this.push_i(2); break; + case '3': this.push_i(3); break; + case '4': this.push_i(4); break; + case '5': this.push_i(5); break; + case '6': this.push_i(6); break; + case '7': this.push_i(7); break; + case '8': this.push_i(8); break; + case '9': this.push_i(9); break; + default: window.log('BefRunner: Undefinied command: ' + chr.charCodeAt(0)); + } + } +}; + +BefObject.prototype.move = function() { + + this.position[0] += this.delta[0]; + this.position[1] += this.delta[1]; + + if (this.position[0] < 0) this.position[0] += this.width; + if (this.position[1] < 0) this.position[1] += this.height; + + if (this.position[0] >= this.width) this.position[0] -= this.width; + if (this.position[1] >= this.height) this.position[1] -= this.height; +}; + +BefObject.prototype.push_i = function(v) { this.stack.push(v); }; +BefObject.prototype.pop_i = function() { return this.stack.pop(); }; +BefObject.prototype.peek_i = function() { return this.stack.peek(); }; +BefObject.prototype.push_b = function(v) { this.stack.push(v?1:0); }; +BefObject.prototype.pop_b = function() { return this.stack.pop()!==0; }; +BefObject.prototype.peek_b = function() { return this.stack.peek()!==0; }; +BefObject.prototype.push_c = function(v) { this.stack.push(v.charCodeAt(0)); }; +BefObject.prototype.gridset_i = function(x,y,c) { if (x < 0 || y < 0 || x >= this.width || y >= this.height) return; this.code[y][x]=String.fromCharCode(c); }; +BefObject.prototype.gridget_i = function(x,y) { if (x < 0 || y < 0 || x >= this.width || y >= this.height) return 0; return this.code[y][x].charCodeAt(0); }; + BefObject.prototype.updateUI = function() { classListSet(this.btnStart, 'ctrl_btn_disabled', this.state === BefState.RUNNING || this.state === BefState.PAUSED); @@ -58,6 +211,50 @@ BefObject.prototype.updateUI = function() { classListSet(this.pnlBottom, 'b93rnr_outpanel_hidden', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL); }; +BefObject.prototype.updateDisplay = function() { + let str = ''; + for (let y=0; y < this.height; y++) { + for (let x=0; x < this.width; x++) { + let chr = this.code[y][x]; + let cc = chr.charCodeAt(0); + if (chr === '&') chr = '&'; + if (chr === '<') chr = '<'; + if (chr === '>') chr = '>'; + if (chr === ' ') chr = ' '; + if (cc===0) chr = '0'; + else if (cc>127 || cc<32) chr = '?'; + if (x === this.position[0] && y === this.position[1]) chr = '' + chr + ''; + str += chr; + } + str += '
'; + } + this.pnlCode.innerHTML = str; + + this.pnlOutput.innerHTML = htmlescape(this.output); + + this.pnlStack.innerHTML = this.stack.revjoin("
"); +}; + +BefObject.prototype.parseBef = function(str) { + const lines = str.replace('\r\n', '\n').split('\n').map(function(str){return str.replace(/\s+$/, '')}); + let max = 0; + for (let line of lines) max = Math.max(max, line.length); + + let result = []; + + for (let line of lines) + { + let row = []; + for(let i=0; i < max; i++) + { + row.push((i < line.length ? (line[i]) : ' ')); + } + result.push(row) + } + + return [result, max, result.length]; +}; + function classListSet(e, cls, active) { if (active) { if (e.classList.contains(cls)) return; @@ -68,6 +265,15 @@ function classListSet(e, cls, active) { } } +function htmlescape(str) { + str = str.replace(/&/g, "&"); + str = str.replace(//g, ">"); + str = str.replace(/ /g, " "); + str = str.replace(/\n/g, "
"); + return str; +} + window.onload = function () { let elements = document.getElementsByClassName("b93rnr_base"); @@ -76,8 +282,8 @@ window.onload = function () let befungeObject = new BefObject(elem); - befungeObject.btnStart.onclick = function () { if (befungeObject.btnStart.classList.contains('ctrl_btn_disabled')) return; befungeObject.Start(); }; - befungeObject.btnStop.onclick = function () { if (befungeObject.btnStop.classList.contains('ctrl_btn_disabled')) return; befungeObject.Stop(); }; - befungeObject.btnReset.onclick = function () { if (befungeObject.btnReset.classList.contains('ctrl_btn_disabled')) return; befungeObject.Reset(); }; + befungeObject.btnStart.onclick = function () { if (befungeObject.btnStart.classList.contains('ctrl_btn_disabled')) return; befungeObject.start(); }; + befungeObject.btnStop.onclick = function () { if (befungeObject.btnStop.classList.contains('ctrl_btn_disabled')) return; befungeObject.stop(); }; + befungeObject.btnReset.onclick = function () { if (befungeObject.btnReset.classList.contains('ctrl_btn_disabled')) return; befungeObject.reset(); }; } }; \ No newline at end of file diff --git a/www/fragments/befunge93_runner.php b/www/fragments/befunge93_runner.php index 1c05b79..33dc393 100644 --- a/www/fragments/befunge93_runner.php +++ b/www/fragments/befunge93_runner.php @@ -11,6 +11,8 @@ function fmtBef($str) { $str = join("\n", array_map(function($p){return rtrim($p);}, explode("\n", $str))); $str = str_replace(' ', ' ', $str); $str = nl2br($str); + $str = str_replace("\r", '', $str); + $str = str_replace("\n", '', $str); return $str; } diff --git a/www/fragments/blogview_euler_single.php b/www/fragments/blogview_euler_single.php index d9968c2..6ecda88 100644 --- a/www/fragments/blogview_euler_single.php +++ b/www/fragments/blogview_euler_single.php @@ -92,13 +92,13 @@ $max = ceil($max / 20) * 20; $break = false; for($i1=0;;$i1++) { - echo "
"; + echo "
\n"; for($i2=0;$i2<2;$i2++) { - echo "
"; + echo "
\n"; for($i3=0;$i3<2;$i3++) { - echo "
"; + echo "
\n"; for($i4=0;$i4<5;$i4++) { $ii = $i1*20 + $i2*10 + $i3*5 + $i4 + 1; @@ -107,19 +107,19 @@ $max = ceil($max / 20) * 20; $pii = str_pad($ii, 3, '0', STR_PAD_LEFT); if ($ii == $problem['number']) - echo "
" . $pii . "
"; + echo "
" . $pii . "
\n"; else if (key_exists($ii, $arr)) - echo "" . $pii . ""; + echo "" . $pii . "\n"; else - echo "
" . $pii . "
"; + echo "
" . $pii . "
\n"; } - echo "
"; + echo "
\n"; if ($break) break; } - echo "
"; + echo "
\n"; if ($break) break; } - echo "
"; + echo "
\n"; if ($break) break; } ?>