blogview_bfjoust
This commit is contained in:
parent
bb28fd3b6d
commit
3dcdd872c4
@ -94,7 +94,7 @@ body {
|
|||||||
#headerdiv .tabrow .tab_github {
|
#headerdiv .tabrow .tab_github {
|
||||||
background-color: #4078c0;
|
background-color: #4078c0;
|
||||||
border-left: 1px solid #111;
|
border-left: 1px solid #111;
|
||||||
border-right: 1px solid #111;
|
border-right: none;
|
||||||
color: black; }
|
color: black; }
|
||||||
#headerdiv .tabrow .tab_github:hover {
|
#headerdiv .tabrow .tab_github:hover {
|
||||||
background-color: #c9510c;
|
background-color: #c9510c;
|
||||||
@ -220,7 +220,7 @@ html, body {
|
|||||||
padding: 8px; }
|
padding: 8px; }
|
||||||
|
|
||||||
.bc_markdown code {
|
.bc_markdown code {
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
@ -344,4 +344,81 @@ html, body {
|
|||||||
.euler_pnl_cell_notexist {
|
.euler_pnl_cell_notexist {
|
||||||
background: #CCCCCC; }
|
background: #CCCCCC; }
|
||||||
|
|
||||||
|
.bfjoust_runner_owner {
|
||||||
|
border: 1px solid #888;
|
||||||
|
background: #F8F8F8;
|
||||||
|
padding: 6px; }
|
||||||
|
.bfjoust_runner_owner .hsplit {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap; }
|
||||||
|
.bfjoust_runner_owner .hsplit_1 {
|
||||||
|
flex: 1;
|
||||||
|
margin: 4px; }
|
||||||
|
.bfjoust_runner_owner .hsplit_2 {
|
||||||
|
flex: 1;
|
||||||
|
margin: 4px; }
|
||||||
|
.bfjoust_runner_owner textarea {
|
||||||
|
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
|
||||||
|
display: block; }
|
||||||
|
.bfjoust_runner_owner .source {
|
||||||
|
height: 350px; }
|
||||||
|
.bfjoust_runner_owner .sink {
|
||||||
|
height: 100px; }
|
||||||
|
.bfjoust_runner_owner .bottomelem {
|
||||||
|
height: 200px; }
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.bfjoust_runner_owner .hsplit {
|
||||||
|
display: block; }
|
||||||
|
.bfjoust_runner_owner .hsplit_1 {
|
||||||
|
display: block;
|
||||||
|
width: calc(100% - 8px); }
|
||||||
|
.bfjoust_runner_owner .hsplit_2 {
|
||||||
|
display: block;
|
||||||
|
width: calc(100% - 8px); }
|
||||||
|
.bfjoust_runner_owner textarea {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto; } }
|
||||||
|
.bfjoust_runner_owner #commandpanel {
|
||||||
|
text-align: center;
|
||||||
|
background-color: lightgray;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
display: table;
|
||||||
|
width: calc(100% - 8px);
|
||||||
|
margin: 4px;
|
||||||
|
padding: 5px 0; }
|
||||||
|
.bfjoust_runner_owner #commandpanel a {
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #000;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
text-decoration: none; }
|
||||||
|
.bfjoust_runner_owner #commandpanel a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #666; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_run {
|
||||||
|
background-color: #080; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_run:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #666; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_stop {
|
||||||
|
background-color: #F00; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_stop:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #666; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_arena {
|
||||||
|
background-color: #F80; }
|
||||||
|
.bfjoust_runner_owner #commandpanel #a_arena:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #666; }
|
||||||
|
.bfjoust_runner_owner #run_size {
|
||||||
|
width: 40px; }
|
||||||
|
.bfjoust_runner_owner #run_speed {
|
||||||
|
width: 70px; }
|
||||||
|
.bfjoust_runner_owner #board {
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #CCC; }
|
||||||
|
|
||||||
/*# sourceMappingURL=styles.css.map */
|
/*# sourceMappingURL=styles.css.map */
|
||||||
|
@ -7,3 +7,4 @@
|
|||||||
@import 'styles_blogview';
|
@import 'styles_blogview';
|
||||||
|
|
||||||
@import 'styles_eulerpanel';
|
@import 'styles_eulerpanel';
|
||||||
|
@import 'styles_bfjoustrunner';
|
84
www/data/css/styles_bfjoustrunner.scss
Normal file
84
www/data/css/styles_bfjoustrunner.scss
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
@import 'styles_config';
|
||||||
|
|
||||||
|
.bfjoust_runner_owner {
|
||||||
|
|
||||||
|
border: 1px solid #888;
|
||||||
|
background: #F8F8F8;
|
||||||
|
padding: 6px;
|
||||||
|
|
||||||
|
.hsplit {
|
||||||
|
display:flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hsplit_1 { flex: 1; margin: 4px; }
|
||||||
|
.hsplit_2 { flex: 1; margin: 4px; }
|
||||||
|
|
||||||
|
textarea { font-family: $FONT_CODE; display:block; }
|
||||||
|
|
||||||
|
.source { height: 350px; }
|
||||||
|
.sink { height: 100px; }
|
||||||
|
.bottomelem { height: 200px; }
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.hsplit { display:block; }
|
||||||
|
.hsplit_1 { display:block; width: calc(100% - 8px); }
|
||||||
|
.hsplit_2 { display:block; width: calc(100% - 8px); }
|
||||||
|
textarea { margin-left: auto; margin-right: auto; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#commandpanel {
|
||||||
|
text-align: center;
|
||||||
|
background-color: lightgray;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
|
||||||
|
display: table;
|
||||||
|
width: calc(100% - 8px);;
|
||||||
|
|
||||||
|
margin: 4px;
|
||||||
|
padding: 5px 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #000;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
&:hover { text-decoration: none; background-color: #666; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#a_run {
|
||||||
|
background-color: #080;
|
||||||
|
&:hover { text-decoration: none; background-color: #666; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#a_stop {
|
||||||
|
background-color: #F00;
|
||||||
|
&:hover { text-decoration: none; background-color: #666; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#a_arena {
|
||||||
|
background-color: #F80;
|
||||||
|
&:hover { text-decoration: none; background-color: #666; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#run_size {
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#run_speed {
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#board {
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
border:1px solid #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bc_markdown code {
|
.bc_markdown code {
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
font-family: $FONT_CODE;
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
@ -42,7 +42,7 @@
|
|||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
background-color: #F8F8F8;
|
background-color: $COL_BACKGROUND_3;
|
||||||
color: black;
|
color: black;
|
||||||
border: 1px solid rgba(0,0,0,.15);
|
border: 1px solid rgba(0,0,0,.15);
|
||||||
-webkit-border-radius: 2px;
|
-webkit-border-radius: 2px;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
$COL_BACKGROUND: #EEE;
|
$COL_BACKGROUND: #EEE;
|
||||||
$COL_BACKGROUND_2: #E0E0E0;
|
$COL_BACKGROUND_2: #E0E0E0;
|
||||||
$COL_TEXT_NORMAL: #CCC;
|
$COL_BACKGROUND_3: #F8F8F8;
|
||||||
$COL_TEXT_DARK: #333;
|
$COL_TEXT_NORMAL: #CCC;
|
||||||
$COL_TRANSPARENT: #FFFFFF00;
|
$COL_TEXT_DARK: #333;
|
||||||
|
$COL_TRANSPARENT: #FFFFFF00;
|
||||||
|
|
||||||
$FONT_HEADER: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
$FONT_HEADER: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
$FONT_CODE: Consolas, Monaco, "Courier New", Menlo, monospace;
|
@ -57,7 +57,7 @@
|
|||||||
.tab_github {
|
.tab_github {
|
||||||
background-color: #4078c0;
|
background-color: #4078c0;
|
||||||
border-left: 1px solid #111;
|
border-left: 1px solid #111;
|
||||||
border-right: 1px solid #111;
|
border-right: none;
|
||||||
color: black;
|
color: black;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
924
www/data/javascript/blogpost_BFJoustBot_script.js
Normal file
924
www/data/javascript/blogpost_BFJoustBot_script.js
Normal file
@ -0,0 +1,924 @@
|
|||||||
|
if (!window.console) {
|
||||||
|
window.console = {
|
||||||
|
log: function() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function inheritPrototype(childObject, parentObject) {
|
||||||
|
var copyOfParent = Object.create(parentObject.prototype);
|
||||||
|
copyOfParent.constructor = childObject;
|
||||||
|
childObject.prototype = copyOfParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchWinnerToChar(w) {
|
||||||
|
switch (w) {
|
||||||
|
case MatchWinner.ABORT:
|
||||||
|
return '#';
|
||||||
|
case MatchWinner.PLAYER_1:
|
||||||
|
return '1';
|
||||||
|
case MatchWinner.DRAW:
|
||||||
|
return 'X';
|
||||||
|
case MatchWinner.PLAYER_2:
|
||||||
|
return '2';
|
||||||
|
case MatchWinner.UNDEFINIED:
|
||||||
|
return '?';
|
||||||
|
default:
|
||||||
|
throw "non-enum value in MatchWinnerToChar(" + w + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.contains = function(obj) {
|
||||||
|
var i = this.length;
|
||||||
|
while (i--) {
|
||||||
|
if (this[i] === obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.last = function() {
|
||||||
|
return this[this.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.peek = function() {
|
||||||
|
return this[this.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.reps = function( num ) {
|
||||||
|
return new Array( num + 1 ).join( this );
|
||||||
|
};
|
||||||
|
|
||||||
|
var RepetitionState = {
|
||||||
|
OPEN: 10,
|
||||||
|
CLOSED: 11,
|
||||||
|
AWAITING_NUMBER: 12,
|
||||||
|
FINISHED: 13
|
||||||
|
};
|
||||||
|
var RepetitionMode = {
|
||||||
|
UNDEFINIED: 10,
|
||||||
|
ITERATIVE: 11,
|
||||||
|
RECURSIVE: 12
|
||||||
|
};
|
||||||
|
var MatchWinner = {
|
||||||
|
UNDEFINIED: 0,
|
||||||
|
PLAYER_1: 10,
|
||||||
|
DRAW: 15,
|
||||||
|
PLAYER_2: 20,
|
||||||
|
ABORT: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
var BF_CHARS = ['+', '-', '<', '>', '[', ']', '.'];
|
||||||
|
var PP_CHARS = ['(', ')', '*', '{', '}', '%', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
|
var NM_CHARS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
|
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFPart() {}
|
||||||
|
|
||||||
|
BFPart.prototype.constructor = BFPart;
|
||||||
|
BFPart.prototype.append = function(part) {
|
||||||
|
throw "abstract";
|
||||||
|
};
|
||||||
|
BFPart.prototype.toProgram = function() {
|
||||||
|
throw "abstract";
|
||||||
|
};
|
||||||
|
BFPart.prototype.finish = function() {
|
||||||
|
throw "abstract";
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFCommand(c) {
|
||||||
|
this.cmd = c;
|
||||||
|
|
||||||
|
BFPart.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inheritPrototype(BFCommand, BFPart);
|
||||||
|
|
||||||
|
BFCommand.prototype.constructor = BFCommand;
|
||||||
|
BFCommand.prototype.append = function(part) {
|
||||||
|
throw "Invalid Appendix";
|
||||||
|
};
|
||||||
|
|
||||||
|
BFCommand.prototype.toProgram = function() {
|
||||||
|
return this.cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
BFCommand.prototype.finish = function() {
|
||||||
|
// void
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFConcat() {
|
||||||
|
this.list = []
|
||||||
|
|
||||||
|
BFPart.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inheritPrototype(BFConcat, BFPart);
|
||||||
|
|
||||||
|
BFConcat.prototype.constructor = BFConcat;
|
||||||
|
|
||||||
|
BFConcat.prototype.append = function(part) {
|
||||||
|
if (this.list.length > 0)
|
||||||
|
this.list.last().finish();
|
||||||
|
|
||||||
|
this.list.push(part);
|
||||||
|
};
|
||||||
|
|
||||||
|
BFConcat.prototype.toProgram = function() {
|
||||||
|
return this.list.map(function(x) {
|
||||||
|
return x.toProgram();
|
||||||
|
}).join("");
|
||||||
|
};
|
||||||
|
|
||||||
|
BFConcat.prototype.finish = function() {
|
||||||
|
if (this.list.length > 0)
|
||||||
|
this.list.last().finish();
|
||||||
|
};
|
||||||
|
|
||||||
|
BFConcat.prototype.splitAroundCenter = function() {
|
||||||
|
var left = new BFConcat();
|
||||||
|
var center = null;
|
||||||
|
var right = new BFConcat();
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
for (; i < this.list.length; i++) {
|
||||||
|
if (this.list[i] instanceof BFCenterLiteral) {
|
||||||
|
center = this.list[i];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
left.append(this.list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (; i < this.list.length; i++) {
|
||||||
|
if (this.list[i] instanceof BFCenterLiteral) {
|
||||||
|
throw "Two much {} in Repetition found";
|
||||||
|
} else {
|
||||||
|
right.append(this.list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (center === null)
|
||||||
|
throw "No {} in Repetition found";
|
||||||
|
|
||||||
|
return [left, center, right];
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFCenterLiteral() {
|
||||||
|
BFConcat.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inheritPrototype(BFCenterLiteral, BFConcat);
|
||||||
|
|
||||||
|
BFCenterLiteral.prototype.constructor = BFCenterLiteral;
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFRepetition() {
|
||||||
|
this.state = RepetitionState.OPEN;
|
||||||
|
this.mode = RepetitionMode.UNDEFINIED;
|
||||||
|
this.parts = new BFConcat();
|
||||||
|
this.count = 0;
|
||||||
|
|
||||||
|
BFPart.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inheritPrototype(BFRepetition, BFPart);
|
||||||
|
|
||||||
|
BFRepetition.prototype.constructor = BFCommand;
|
||||||
|
BFRepetition.prototype.append = function(part) {
|
||||||
|
this.parts.append(part);
|
||||||
|
};
|
||||||
|
|
||||||
|
BFRepetition.prototype.toProgram = function() {
|
||||||
|
if (this.mode == RepetitionMode.ITERATIVE) {
|
||||||
|
return new Array(this.count + 1).join(this.parts.toProgram());
|
||||||
|
} else if (this.mode == RepetitionMode.RECURSIVE) {
|
||||||
|
var split = this.parts.splitAroundCenter();
|
||||||
|
|
||||||
|
var left = new Array(this.count + 1).join(split[0].toProgram());
|
||||||
|
var center = split[1].toProgram();
|
||||||
|
var right = new Array(this.count + 1).join(split[2].toProgram());
|
||||||
|
|
||||||
|
return left + center + right;
|
||||||
|
} else {
|
||||||
|
throw "RepMode not definied";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BFRepetition.prototype.close = function() {
|
||||||
|
if (this.state == RepetitionState.CLOSED) return;
|
||||||
|
|
||||||
|
if (this.state != RepetitionState.OPEN)
|
||||||
|
throw ("state != OPEN, state == " + this.state);
|
||||||
|
|
||||||
|
this.state = RepetitionState.CLOSED;
|
||||||
|
};
|
||||||
|
|
||||||
|
BFRepetition.prototype.startNumberWaiting = function(md) {
|
||||||
|
this.mode = md;
|
||||||
|
|
||||||
|
if (this.state == RepetitionState.AWAITING_NUMBER) return;
|
||||||
|
|
||||||
|
if (this.state != RepetitionState.CLOSED)
|
||||||
|
throw ("state != CLOSED, state == " + this.state);
|
||||||
|
|
||||||
|
this.state = RepetitionState.AWAITING_NUMBER;
|
||||||
|
};
|
||||||
|
|
||||||
|
BFRepetition.prototype.finish = function() {
|
||||||
|
if (this.state == RepetitionState.FINISHED) return;
|
||||||
|
|
||||||
|
if (this.state != RepetitionState.AWAITING_NUMBER)
|
||||||
|
throw ("state != AWAITING_NUMBER, state == " + this.state);
|
||||||
|
|
||||||
|
this.state = RepetitionState.FINISHED;
|
||||||
|
};
|
||||||
|
|
||||||
|
BFRepetition.prototype.addNumber = function(p) {
|
||||||
|
this.count *= 10;
|
||||||
|
this.count += p;
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFProg (_code) {
|
||||||
|
this.code_position = 0;
|
||||||
|
this.board_position = 0;
|
||||||
|
this.inverted = false; // + <-> -
|
||||||
|
this.active = true;
|
||||||
|
this.code = _code;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.constructor = BFProg;
|
||||||
|
|
||||||
|
BFProg.prototype.step = function(match, invertboard) {
|
||||||
|
//console.log(this.code_position + " #> " + this.getCommand() + " (" + match.get(this.board_position, invertboard) + ")");
|
||||||
|
switch(this.getCommand()) {
|
||||||
|
case '+':
|
||||||
|
match.inc(this.board_position, invertboard);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
match.dec(this.board_position, invertboard);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '<':
|
||||||
|
this.board_position--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '>':
|
||||||
|
this.board_position++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
if (match.get(this.board_position, invertboard) == 0) {
|
||||||
|
this.skip_forward();
|
||||||
|
this.code_position--; // reverse effect of next move
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
this.skip_backward();
|
||||||
|
this.code_position--; // reverse effect of next move
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw "Unknown Char in prog: " + this.code.charAt(this.position);
|
||||||
|
}
|
||||||
|
this.move();
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.move = function() {
|
||||||
|
if (this.code_position < this.code.length - 1)
|
||||||
|
this.code_position++;
|
||||||
|
else {
|
||||||
|
if (this.active) console.log("END OF CODE REACHED");
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.skip_forward = function() {
|
||||||
|
var depth = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
var chr = this.code.charAt(this.code_position);
|
||||||
|
if (chr == '[')
|
||||||
|
depth++
|
||||||
|
else if (chr == ']')
|
||||||
|
depth--;
|
||||||
|
|
||||||
|
this.code_position++;
|
||||||
|
|
||||||
|
|
||||||
|
} while (depth > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.skip_backward = function() {
|
||||||
|
var depth = -1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
this.code_position--;
|
||||||
|
|
||||||
|
var chr = this.code.charAt(this.code_position);
|
||||||
|
if (chr == '[')
|
||||||
|
depth++
|
||||||
|
else if (chr == ']')
|
||||||
|
depth--;
|
||||||
|
|
||||||
|
|
||||||
|
} while (depth < 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.getCommand = function() {
|
||||||
|
if (this.active) {
|
||||||
|
switch(this.code.charAt(this.code_position)) {
|
||||||
|
case '+': return this.inverted ? '-' : '+';
|
||||||
|
case '-': return this.inverted ? '+' : '-';
|
||||||
|
case '<': return '<';
|
||||||
|
case '>': return '>';
|
||||||
|
case '.': return '.';
|
||||||
|
case '[': return '[';
|
||||||
|
case ']': return ']';
|
||||||
|
default: throw "Unknown Char in prog: " + this.code.charAt(this.code_position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.isFlowCommand = function() {
|
||||||
|
if (this.active) {
|
||||||
|
switch(this.code.charAt(this.code_position)) {
|
||||||
|
case '+': return false;
|
||||||
|
case '-': return false;
|
||||||
|
case '<': return true;
|
||||||
|
case '>': return true;
|
||||||
|
case '.': return false;
|
||||||
|
case '[': return true;
|
||||||
|
case ']': return true;
|
||||||
|
default: throw "Unknown Char in prog: " + this.code.charAt(this.code_position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.getBoardPos = function(invertboard, size) {
|
||||||
|
if (invertboard)
|
||||||
|
return (size - 1) - this.board_position;
|
||||||
|
else
|
||||||
|
return this.board_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFProg.prototype.isOOB = function(size) {
|
||||||
|
return this.board_position < 0 || this.board_position >= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function BFMatch (_size, _prog1, _prog2) {
|
||||||
|
this.size = _size;
|
||||||
|
this.prog1 = _prog1;
|
||||||
|
this.prog2 = _prog2;
|
||||||
|
|
||||||
|
this.flagZeroed1 = 0;
|
||||||
|
this.flagZeroed2 = 0;
|
||||||
|
this.roundCount = 0;
|
||||||
|
this.winner = MatchWinner.UNDEFINIED;
|
||||||
|
this._intervalID = -1
|
||||||
|
|
||||||
|
this.map = new Array(_size);
|
||||||
|
for(var i = 0; i < _size; i++) this.map[i] = 0;
|
||||||
|
this.map[0] = 128;
|
||||||
|
this.map[this.map.length - 1] = 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.constructor = BFMatch;
|
||||||
|
|
||||||
|
BFMatch.prototype.calc = function() {
|
||||||
|
for(;;) {
|
||||||
|
this.roundCount++;
|
||||||
|
|
||||||
|
if (this.prog2.isFlowCommand()) { // Flow-cmd first -> reverse order
|
||||||
|
this.prog2.step(this, true);
|
||||||
|
this.prog1.step(this, false);
|
||||||
|
} else {
|
||||||
|
this.prog1.step(this, false);
|
||||||
|
this.prog2.step(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stepFlag();
|
||||||
|
this.stepWinner();
|
||||||
|
|
||||||
|
if (this.winner != MatchWinner.UNDEFINIED)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.winner;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.start = function(canvas, width, height, speed) {
|
||||||
|
this.param_canvas = canvas;
|
||||||
|
this.param_width = width;
|
||||||
|
this.param_height = height;
|
||||||
|
|
||||||
|
this._intervalID = setInterval(this.tick.bind(this), speed);
|
||||||
|
};
|
||||||
|
|
||||||
|
BFMatch.prototype.stop = function(winner) {
|
||||||
|
if (winner == MatchWinner.UNDEFINIED)
|
||||||
|
throw ("can't stop on undef");
|
||||||
|
|
||||||
|
if (this._intervalID != -1) {
|
||||||
|
clearInterval(this._intervalID);
|
||||||
|
this._intervalID = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Match stopped winner: " + winner);
|
||||||
|
|
||||||
|
switch (winner) {
|
||||||
|
case MatchWinner.PLAYER_1:
|
||||||
|
this.winner = MatchWinner.PLAYER_1;
|
||||||
|
break;
|
||||||
|
case MatchWinner.DRAW:
|
||||||
|
this.winner = MatchWinner.DRAW;
|
||||||
|
break;
|
||||||
|
case MatchWinner.PLAYER_2:
|
||||||
|
this.winner = MatchWinner.PLAYER_2;
|
||||||
|
break;
|
||||||
|
case MatchWinner.ABORT:
|
||||||
|
this.winner = MatchWinner.ABORT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw ( "no-enum value in stop()" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BFMatch.prototype.tick = function() {
|
||||||
|
this.step();
|
||||||
|
this.draw(this.param_canvas, this.param_width, this.param_height);
|
||||||
|
};
|
||||||
|
|
||||||
|
BFMatch.prototype.step = function() {
|
||||||
|
this.roundCount++;
|
||||||
|
|
||||||
|
if (this.prog2.isFlowCommand()) { // Flow-cmd first -> reverse order
|
||||||
|
this.prog2.step(this, true);
|
||||||
|
this.prog1.step(this, false);
|
||||||
|
} else {
|
||||||
|
this.prog1.step(this, false);
|
||||||
|
this.prog2.step(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stepFlag();
|
||||||
|
this.stepWinner();
|
||||||
|
|
||||||
|
if (this.winner == MatchWinner.PLAYER_1)
|
||||||
|
alert('Player 1 (left) won');
|
||||||
|
else if (this.winner == MatchWinner.PLAYER_2)
|
||||||
|
alert('Player 2 (right) won');
|
||||||
|
else if (this.winner == MatchWinner.DRAW)
|
||||||
|
alert('Draw');
|
||||||
|
};
|
||||||
|
|
||||||
|
BFMatch.prototype.stepFlag = function() {
|
||||||
|
if (this.map[0] == 0)
|
||||||
|
this.flagZeroed1++;
|
||||||
|
else
|
||||||
|
this.flagZeroed1 = 0;
|
||||||
|
|
||||||
|
if (this.map[this.size - 1] == 0)
|
||||||
|
this.flagZeroed2++;
|
||||||
|
else
|
||||||
|
this.flagZeroed2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.getFlagWeight = function(fg) {
|
||||||
|
if (fg == MatchWinner.PLAYER_1) {
|
||||||
|
return Math.abs(this.map[0]);
|
||||||
|
} else if (fg == MatchWinner.PLAYER_2) {
|
||||||
|
return Math.abs(this.map[this.size - 1]);
|
||||||
|
} else {
|
||||||
|
throw "Unknown player: " + fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.stepWinner = function() {
|
||||||
|
if (this.roundCount > 100000 && this.getFlagWeight(MatchWinner.PLAYER_1) == this.getFlagWeight(MatchWinner.PLAYER_2))
|
||||||
|
this.stop(MatchWinner.DRAW);
|
||||||
|
|
||||||
|
if ((this.prog1.isOOB(this.size) || this.flagZeroed1 >= 2) && (this.prog2.isOOB(this.size) || this.flagZeroed2 >= 2))
|
||||||
|
this.stop(MatchWinner.DRAW);
|
||||||
|
|
||||||
|
if (this.prog1.isOOB(this.size) || this.flagZeroed1 >= 2)
|
||||||
|
this.stop(MatchWinner.PLAYER_2);
|
||||||
|
|
||||||
|
if (this.prog2.isOOB(this.size) || this.flagZeroed2 >= 2)
|
||||||
|
this.stop(MatchWinner.PLAYER_1);
|
||||||
|
|
||||||
|
if (this.roundCount > 100000 && this.getFlagWeight(MatchWinner.PLAYER_1) > this.getFlagWeight(MatchWinner.PLAYER_2))
|
||||||
|
this.stop(MatchWinner.PLAYER_1);
|
||||||
|
|
||||||
|
if (this.roundCount > 100000 && this.getFlagWeight(MatchWinner.PLAYER_1) < this.getFlagWeight(MatchWinner.PLAYER_2))
|
||||||
|
this.stop(MatchWinner.PLAYER_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.inc = function(idx, invertboard) {
|
||||||
|
if (invertboard) idx = (this.size - 1) - idx;
|
||||||
|
|
||||||
|
this.map[idx]++;
|
||||||
|
this.map[idx] = (this.map[idx] + 127 + 256) % 256 - 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.dec = function(idx, invertboard) {
|
||||||
|
if (invertboard) idx = (this.size - 1) - idx;
|
||||||
|
|
||||||
|
this.map[idx]--;
|
||||||
|
this.map[idx] = (this.map[idx] + 127 + 256) % 256 - 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.get = function(idx, invertboard) {
|
||||||
|
if (invertboard) idx = (this.size - 1) - idx;
|
||||||
|
|
||||||
|
return this.map[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
BFMatch.prototype.draw = function(canvas, width, height) {
|
||||||
|
var BORDER = 4;
|
||||||
|
var PADDING = 2;
|
||||||
|
|
||||||
|
var cell_width = (((width - 2*BORDER) + PADDING) / this.size) - PADDING;
|
||||||
|
var cell_height = cell_width * 3/4;
|
||||||
|
var max_height = (height - 2*BORDER - cell_height) / 2;
|
||||||
|
|
||||||
|
cell_width = Math.floor(cell_width);
|
||||||
|
cell_height = Math.floor(cell_height);
|
||||||
|
max_height = Math.floor(max_height);
|
||||||
|
|
||||||
|
canvas.lineWidth = 1;
|
||||||
|
|
||||||
|
|
||||||
|
canvas.fillStyle="#FFFFFF";
|
||||||
|
canvas.fillRect(0, 0, width, height);
|
||||||
|
canvas.fillStyle="#000000";
|
||||||
|
|
||||||
|
for (var i = 0; i < this.size; i++) {
|
||||||
|
var cell_value = this.map[i];
|
||||||
|
|
||||||
|
var x = Math.floor(BORDER + i*(cell_width + PADDING)) + 0.5;
|
||||||
|
var y = Math.floor(height/2 - cell_height/2) + 0.5;
|
||||||
|
|
||||||
|
canvas.fillStyle="#F3F3F3";
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.rect(x, y, cell_width, cell_height);
|
||||||
|
canvas.closePath();
|
||||||
|
canvas.fill();
|
||||||
|
canvas.stroke();
|
||||||
|
|
||||||
|
if (this.prog1.getBoardPos(false, this.size) == i) {
|
||||||
|
canvas.fillStyle="#F00";
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.moveTo(x, y);
|
||||||
|
canvas.lineTo(x + cell_height/2, y + cell_height/2);
|
||||||
|
canvas.lineTo(x, y + cell_height);
|
||||||
|
canvas.lineTo(x, y);
|
||||||
|
canvas.closePath();
|
||||||
|
canvas.fill();
|
||||||
|
canvas.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.prog2.getBoardPos(true, this.size) == i) {
|
||||||
|
canvas.fillStyle="#00F";
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.moveTo(x + cell_width, y);
|
||||||
|
canvas.lineTo(x + cell_width - cell_height/2, y + cell_height/2);
|
||||||
|
canvas.lineTo(x + cell_width, y + cell_height);
|
||||||
|
canvas.lineTo(x + cell_width, y);
|
||||||
|
canvas.closePath();
|
||||||
|
canvas.fill();
|
||||||
|
canvas.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
canvas.fillStyle="#F00";
|
||||||
|
else if (i == this.size - 1)
|
||||||
|
canvas.fillStyle="#00F";
|
||||||
|
else
|
||||||
|
canvas.fillStyle="#484D51";
|
||||||
|
if (cell_value < 0) {
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.rect(x,
|
||||||
|
y + cell_height,
|
||||||
|
cell_width,
|
||||||
|
-Math.floor(max_height * cell_value/128));
|
||||||
|
canvas.closePath();
|
||||||
|
canvas.fill();
|
||||||
|
canvas.stroke();
|
||||||
|
} else if (cell_value > 0) {
|
||||||
|
canvas.beginPath();
|
||||||
|
canvas.rect(x,
|
||||||
|
y,
|
||||||
|
cell_width,
|
||||||
|
-Math.ceil(max_height * cell_value/128));
|
||||||
|
canvas.closePath();
|
||||||
|
canvas.fill();
|
||||||
|
canvas.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
//######################################################
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function expand(input) {
|
||||||
|
var root = new BFConcat();
|
||||||
|
var stack = [];
|
||||||
|
stack.push(root);
|
||||||
|
var linep = 1;
|
||||||
|
var charp = 1;
|
||||||
|
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
var c = input.charAt(i);
|
||||||
|
var next = ((i + 1) == input.length) ? (' ') : (input.charAt(i + 1));
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
linep++;
|
||||||
|
charp = 0;
|
||||||
|
}
|
||||||
|
charp++;
|
||||||
|
|
||||||
|
if (BF_CHARS.contains(c)) {
|
||||||
|
stack.peek().append(new BFCommand(c));
|
||||||
|
} else if (c == '(') {
|
||||||
|
var rep = new BFRepetition();
|
||||||
|
stack.peek().append(rep);
|
||||||
|
stack.push(rep);
|
||||||
|
} else if (c == ')' && stack.peek() instanceof BFRepetition && stack.peek().state == RepetitionState.OPEN) {
|
||||||
|
stack.peek().close();
|
||||||
|
|
||||||
|
if (next != '*' && next != '%') {
|
||||||
|
stack.peek().startNumberWaiting(RepetitionMode.ITERATIVE);
|
||||||
|
stack.peek().addNumber(1);
|
||||||
|
stack.peek().finish();
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
|
} else if (c == '{' && stack.peek() instanceof BFRepetition) {
|
||||||
|
var rep = new BFCenterLiteral();
|
||||||
|
stack.peek().append(rep);
|
||||||
|
stack.push(rep);
|
||||||
|
} else if (c == '}' && stack.peek() instanceof BFCenterLiteral) {
|
||||||
|
stack.pop();
|
||||||
|
} else if (c == '*' && stack.peek() instanceof BFRepetition) {
|
||||||
|
var rep = stack.peek();
|
||||||
|
|
||||||
|
rep.startNumberWaiting(RepetitionMode.ITERATIVE);
|
||||||
|
} else if (c == '%' && stack.peek() instanceof BFRepetition) {
|
||||||
|
var rep = stack.peek();
|
||||||
|
|
||||||
|
rep.startNumberWaiting(RepetitionMode.RECURSIVE);
|
||||||
|
} else if (NM_CHARS.contains(c) && stack.peek() instanceof BFRepetition && stack.peek().state == RepetitionState.AWAITING_NUMBER) {
|
||||||
|
var rep = stack.peek();
|
||||||
|
|
||||||
|
rep.addNumber(c - '0');
|
||||||
|
|
||||||
|
if (!NM_CHARS.contains(next))
|
||||||
|
stack.pop();
|
||||||
|
} else {
|
||||||
|
console.log("Ignore Char: '" + c + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (stack.peek() !== root)
|
||||||
|
throw ("Stack not unwinded" + stack);
|
||||||
|
|
||||||
|
return root.toProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
function getCollapseCount(code, width) {
|
||||||
|
var count = 0;
|
||||||
|
var piece = code.substr(0, width);
|
||||||
|
|
||||||
|
for(var pos = 0; pos <= code.length; pos += width) {
|
||||||
|
if (code.substr(pos, width) == piece)
|
||||||
|
count++;
|
||||||
|
else
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSquareBracketHill(code) {
|
||||||
|
var height = 0;
|
||||||
|
|
||||||
|
for(var p = 0; p < code.length; p++) {
|
||||||
|
if (code.charAt(p) == '[') height++;
|
||||||
|
else if (code.charAt(p) == ']') height--;
|
||||||
|
|
||||||
|
if (height < 0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return height == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function collapse(code) {
|
||||||
|
if (code.length == 0) return code;
|
||||||
|
|
||||||
|
var maxImprovement = 0;
|
||||||
|
var maxImpWidth = -1;
|
||||||
|
var maxImpRep = -1;
|
||||||
|
|
||||||
|
for(var i = 1; i < (code.length/2 + 1); i++) {
|
||||||
|
var width = i;
|
||||||
|
|
||||||
|
if (! isSquareBracketHill(code.substr(0, width))) continue;
|
||||||
|
|
||||||
|
var rep = getCollapseCount(code, width);
|
||||||
|
|
||||||
|
if (width * rep > width + 4 && (width * rep - (width + 4)) > maxImprovement) {
|
||||||
|
maxImprovement = (width * rep - (width + 4));
|
||||||
|
maxImpWidth = width;
|
||||||
|
maxImpRep = rep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxImpWidth > 0)
|
||||||
|
return "(" + collapse(code.substr(0, maxImpWidth)) + ")*" + maxImpRep + collapse(code.substr(maxImpRep * maxImpWidth, code.length));
|
||||||
|
else
|
||||||
|
return code.substr(0, 1) + collapse(code.substr(1, code.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################################################
|
||||||
|
|
||||||
|
document.getElementById("a_expand").onclick = onExpandClicked;
|
||||||
|
document.getElementById("a_collapse").onclick = onCollapseClicked;
|
||||||
|
document.getElementById("a_run").onclick = onRunClicked;
|
||||||
|
document.getElementById("a_stop").onclick = onStopClicked;
|
||||||
|
document.getElementById("a_arena").onclick = onArenaClicked;
|
||||||
|
|
||||||
|
function onExpandClicked() {
|
||||||
|
var source1 = document.getElementById("source_1");
|
||||||
|
var sink1 = document.getElementById("sink_1");
|
||||||
|
var source2 = document.getElementById("source_2");
|
||||||
|
var sink2 = document.getElementById("sink_2");
|
||||||
|
|
||||||
|
sink1.value = expand(source1.value);
|
||||||
|
sink2.value = expand(source2.value);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCollapseClicked() {
|
||||||
|
{
|
||||||
|
var source = document.getElementById("source_1");
|
||||||
|
var sink = document.getElementById("sink_1");
|
||||||
|
sink.value = collapse(expand(source.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var source = document.getElementById("source_2");
|
||||||
|
var sink = document.getElementById("sink_2");
|
||||||
|
sink.value = collapse(expand(source.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = null;
|
||||||
|
|
||||||
|
function onRunClicked() {
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
match.stop(MatchWinner.ABORT);
|
||||||
|
match = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var param_size = parseInt( document.getElementById("run_size").value );
|
||||||
|
var param_speed = parseInt( document.getElementById("run_speed").value );
|
||||||
|
var source1 = document.getElementById("source_1");
|
||||||
|
var code1 = expand(source1.value);
|
||||||
|
var source2 = document.getElementById("source_2");
|
||||||
|
var code2 = expand(source2.value);
|
||||||
|
var brd = document.getElementById("board");
|
||||||
|
var ctx = brd.getContext("2d");
|
||||||
|
|
||||||
|
brd.setAttribute('width', brd.offsetWidth);
|
||||||
|
brd.setAttribute('height', brd.offsetHeight);
|
||||||
|
|
||||||
|
match = new BFMatch(param_size, new BFProg(code1), new BFProg(code2));
|
||||||
|
|
||||||
|
document.getElementById("sink_1").value = code1;
|
||||||
|
document.getElementById("sink_2").value = code2;
|
||||||
|
|
||||||
|
match.start(ctx, brd.width, brd.height, param_speed);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStopClicked() {
|
||||||
|
|
||||||
|
if (match == null) return false;
|
||||||
|
|
||||||
|
document.getElementById("sink_1").value = '';
|
||||||
|
document.getElementById("sink_2").value = '';
|
||||||
|
|
||||||
|
var canvas = document.getElementById("board").getContext("2d");
|
||||||
|
canvas.fillStyle="#FFFFFF";
|
||||||
|
canvas.fillRect(0, 0, document.getElementById("board").width, document.getElementById("board").height)
|
||||||
|
|
||||||
|
match.stop(MatchWinner.ABORT);
|
||||||
|
match = null;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onArenaClicked() {
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
match.stop(MatchWinner.ABORT);
|
||||||
|
match = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var source1 = document.getElementById("source_1");
|
||||||
|
var code1 = expand(source1.value);
|
||||||
|
var source2 = document.getElementById("source_2");
|
||||||
|
var code2 = expand(source2.value);
|
||||||
|
|
||||||
|
var result = new Array(31);
|
||||||
|
for (var i = 0; i < 31; i++) result[i] = new Array(2);
|
||||||
|
var result_p1 = 0;
|
||||||
|
var result_draw = 0;
|
||||||
|
var result_p2 = 0;
|
||||||
|
|
||||||
|
for (var msize = 10; msize <= 30 ; msize++) {
|
||||||
|
var p1 = new BFProg(code1);
|
||||||
|
var p2 = new BFProg(code2);
|
||||||
|
|
||||||
|
match = new BFMatch(msize, p1, p2);
|
||||||
|
|
||||||
|
result[msize][0] = match.calc();
|
||||||
|
|
||||||
|
if (result[msize][0] == MatchWinner.PLAYER_1) result_p1++;
|
||||||
|
if (result[msize][0] == MatchWinner.DRAW) result_draw++;
|
||||||
|
if (result[msize][0] == MatchWinner.PLAYER_2) result_p2++;
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
|
||||||
|
var p1 = new BFProg(code1);
|
||||||
|
var p2 = new BFProg(code2);
|
||||||
|
p2.inverted = true;
|
||||||
|
|
||||||
|
var match = new BFMatch(msize, p1, p2);
|
||||||
|
|
||||||
|
result[msize][1] = match.calc();
|
||||||
|
|
||||||
|
if (result[msize][1] == MatchWinner.PLAYER_1) result_p1++;
|
||||||
|
if (result[msize][1] == MatchWinner.DRAW) result_draw++;
|
||||||
|
if (result[msize][1] == MatchWinner.PLAYER_2) result_p2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var log = "";
|
||||||
|
|
||||||
|
log += "Wins Player 1 (left) :" + result_p1 + '\n';
|
||||||
|
log += "Draws :" + result_draw + '\n';
|
||||||
|
log += "Wins Player 2 (left) :" + result_p2 + '\n';
|
||||||
|
log += "" + '\n';
|
||||||
|
|
||||||
|
log += " ".reps(9) + "|";
|
||||||
|
for (var i = 10; i <= 30; i++) log += ' ' + i;
|
||||||
|
log += '\n';
|
||||||
|
|
||||||
|
log += "-".reps(9) + "|" + "-".reps(3 * 21) + '\n';
|
||||||
|
|
||||||
|
log += "Normal | ";
|
||||||
|
for (var i = 10; i <= 30; i++) log += matchWinnerToChar(result[i][0]) + " ";
|
||||||
|
log += "\n";
|
||||||
|
|
||||||
|
log += "Inverted | ";
|
||||||
|
for (var i = 10; i <= 30; i++) log += matchWinnerToChar(result[i][1]) + " ";
|
||||||
|
log += "\n";
|
||||||
|
|
||||||
|
document.getElementById("log").value = log;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
47
www/fragments/bfjoust_runner.php
Normal file
47
www/fragments/bfjoust_runner.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
require_once (__DIR__ . '/../internals/base.php');
|
||||||
|
|
||||||
|
global $PARAM_CODE_LEFT;
|
||||||
|
global $PARAM_CODE_RIGHT;
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="bfjoust_runner_owner" >
|
||||||
|
<div class="hsplit">
|
||||||
|
<textarea class="hsplit_1 source" id="source_1"><?php echo htmlspecialchars($PARAM_CODE_LEFT); ?></textarea>
|
||||||
|
<textarea class="hsplit_2 source" id="source_2"><?php echo htmlspecialchars($PARAM_CODE_RIGHT); ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="commandpanel">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<a href="#" id="a_expand">expand</a>
|
||||||
|
|
|
||||||
|
<a href="#" id="a_collapse">collapse</a>
|
||||||
|
|
|
||||||
|
<a href="#" id="a_run">run</a>
|
||||||
|
(size:
|
||||||
|
<input type="number" id="run_size" min="10" max="30" value="30" width="30">
|
||||||
|
speed:
|
||||||
|
<input type="number" id="run_speed" min="0" max="10000" value="10">
|
||||||
|
)
|
||||||
|
|
|
||||||
|
<a href="#" id="a_stop">stop</a>
|
||||||
|
|
|
||||||
|
<a href="#" id="a_arena">arena</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hsplit">
|
||||||
|
<textarea class="hsplit_1 sink" id="sink_1"></textarea>
|
||||||
|
<textarea class="hsplit_2 sink" id="sink_2"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hsplit">
|
||||||
|
<canvas class="hsplit_1 bottomelem" id="board"></canvas>
|
||||||
|
<textarea class="hsplit_2 bottomelem" id="log" wrap="off"> </textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/data/javascript/blogpost_BFJoustBot_script.js"></script>
|
34
www/fragments/blogview_bfjoust.php
Normal file
34
www/fragments/blogview_bfjoust.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
require_once (__DIR__ . '/../internals/base.php');
|
||||||
|
require_once (__DIR__ . '/../internals/blog.php');
|
||||||
|
require_once (__DIR__ . '/../extern/Parsedown.php');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="blogcontent bc_markdown">
|
||||||
|
|
||||||
|
<div class="bc_header">
|
||||||
|
<?php echo $post['date']; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bc_data">
|
||||||
|
<?php
|
||||||
|
$code_own = file_get_contents(__DIR__ . '/../statics/blog/bfjoust_MultiVAC.bfjoust');
|
||||||
|
$code_opp = file_get_contents(__DIR__ . '/../statics/blog/bfjoust_Patashu_lazy.bfjoust');
|
||||||
|
|
||||||
|
$pd = new Parsedown();
|
||||||
|
$dat = file_get_contents( __DIR__ . '/../statics/blog/bfjoust.md');
|
||||||
|
$dat = str_replace("{{CODE}}", $code_own, $dat);
|
||||||
|
|
||||||
|
echo $pd->text($dat);
|
||||||
|
|
||||||
|
|
||||||
|
global $PARAM_CODE_LEFT;
|
||||||
|
global $PARAM_CODE_RIGHT;
|
||||||
|
|
||||||
|
$PARAM_CODE_LEFT = $code_own;
|
||||||
|
$PARAM_CODE_RIGHT = $code_opp;
|
||||||
|
include (__DIR__ . '/../fragments/bfjoust_runner.php');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
@ -22,7 +22,7 @@ class Blog
|
|||||||
[ 'id' => 1, 'date' => '2014-07-10', 'visible' => true, 'title' => 'Project Euler with Befunge', 'fragment' => '', 'type' => 'euler', 'cat' => 'blog' ],
|
[ 'id' => 1, 'date' => '2014-07-10', 'visible' => true, 'title' => 'Project Euler with Befunge', 'fragment' => '', 'type' => 'euler', 'cat' => 'blog' ],
|
||||||
[ 'id' => 3, 'date' => '2014-07-15', 'visible' => true, 'title' => '.Net format specifier Cheat Sheet', 'fragment' => 'net_format_spec.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
[ 'id' => 3, 'date' => '2014-07-15', 'visible' => true, 'title' => '.Net format specifier Cheat Sheet', 'fragment' => 'net_format_spec.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
||||||
[ 'id' => 19, 'date' => '2014-08-04', 'visible' => true, 'title' => 'I am Number Four', 'fragment' => 'v4.md', 'type' => 'markdown', 'cat' => 'log' ],
|
[ 'id' => 19, 'date' => '2014-08-04', 'visible' => true, 'title' => 'I am Number Four', 'fragment' => 'v4.md', 'type' => 'markdown', 'cat' => 'log' ],
|
||||||
[ 'id' => 7, 'date' => '2014-09-28', 'visible' => true, 'title' => 'My BFJoust arena and battle-bot', 'fragment' => 'bfjoust.php', 'type' => 'php', 'cat' => 'blog' ],
|
[ 'id' => 7, 'date' => '2014-09-28', 'visible' => true, 'title' => 'My BFJoust arena and battle-bot', 'fragment' => '', 'type' => 'bfjoust', 'cat' => 'blog' ],
|
||||||
[ 'id' => 8, 'date' => '2014-11-05', 'visible' => true, 'title' => 'Rapla Enhancement Script', 'fragment' => 'rapla_css.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
[ 'id' => 8, 'date' => '2014-11-05', 'visible' => true, 'title' => 'Rapla Enhancement Script', 'fragment' => 'rapla_css.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
||||||
[ 'id' => 20, 'date' => '2015-01-09', 'visible' => true, 'title' => 'More Befunge with Project Euler', 'fragment' => 'more_euler.md', 'type' => 'markdown', 'cat' => 'log' ],
|
[ 'id' => 20, 'date' => '2015-01-09', 'visible' => true, 'title' => 'More Befunge with Project Euler', 'fragment' => 'more_euler.md', 'type' => 'markdown', 'cat' => 'log' ],
|
||||||
[ 'id' => 9, 'date' => '2016-10-22', 'visible' => true, 'title' => 'A complete sudoku solver in Befunge-93', 'fragment' => 'sudoku_befunge.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
[ 'id' => 9, 'date' => '2016-10-22', 'visible' => true, 'title' => 'A complete sudoku solver in Befunge-93', 'fragment' => 'sudoku_befunge.md', 'type' => 'markdown', 'cat' => 'blog' ],
|
||||||
|
@ -42,9 +42,9 @@ if ($post === NULL) httpError(404, 'blogpost not found');
|
|||||||
|
|
||||||
include (__DIR__ . '/../fragments/blogview_markdown.php');
|
include (__DIR__ . '/../fragments/blogview_markdown.php');
|
||||||
|
|
||||||
} elseif ($post['type'] === 'php') {
|
} elseif ($post['type'] === 'bfjoust') {
|
||||||
|
|
||||||
include (__DIR__ . '/../fragments/blogview_php.php');
|
include (__DIR__ . '/../fragments/blogview_bfjoust.php');
|
||||||
|
|
||||||
} elseif ($post['type'] === 'euler') {
|
} elseif ($post['type'] === 'euler') {
|
||||||
|
|
||||||
|
44
www/statics/blog/bfjoust_MultiVAC.bfjoust
Normal file
44
www/statics/blog/bfjoust_MultiVAC.bfjoust
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
> # Build 9 big decoys
|
||||||
|
(-)*4>(+)*4> # A few small ones
|
||||||
|
(>)*6
|
||||||
|
|
||||||
|
(<(-)*80<(+)*80)*3 # And more big ones
|
||||||
|
<(+)*76 # For Confusion :/
|
||||||
|
<(-)*76
|
||||||
|
|
||||||
|
<(-)*28 # Just for you, Wall E
|
||||||
|
|
||||||
|
(>)*10
|
||||||
|
|
||||||
|
( # Walk forwards and clear everything
|
||||||
|
([+ # clear pos decoys
|
||||||
|
{
|
||||||
|
(-)*16
|
||||||
|
(-[ # clear neg decoys
|
||||||
|
{
|
||||||
|
(-)*112 # Big decoy / flag clearen: 128~16=112
|
||||||
|
[+]
|
||||||
|
}
|
||||||
|
])%16
|
||||||
|
}
|
||||||
|
])%16
|
||||||
|
[-] # Counter DecoyBot ~_~
|
||||||
|
(+)*2 # Leave a small trail behind
|
||||||
|
>
|
||||||
|
|
||||||
|
([- # The same thing with reversed polarity
|
||||||
|
{
|
||||||
|
(+)*16
|
||||||
|
(+[
|
||||||
|
{
|
||||||
|
(+)*112
|
||||||
|
[-]
|
||||||
|
}
|
||||||
|
])%16
|
||||||
|
}
|
||||||
|
])%16
|
||||||
|
[+]
|
||||||
|
(-)*2
|
||||||
|
>
|
||||||
|
|
||||||
|
)*11
|
3
www/statics/blog/bfjoust_Patashu_lazy.bfjoust
Normal file
3
www/statics/blog/bfjoust_Patashu_lazy.bfjoust
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#Patashu_lazy from #esoteric hill
|
||||||
|
|
||||||
|
>(+)*5>(-)*5>(+)*5>(-)*5>(-)*5>(+)*5>(+)*5>(-)*5(>(-.)*128)*21[-]((-)*2048(+)*2048.)*2
|
Loading…
Reference in New Issue
Block a user