icfp15/js/mine.min.js

1 line
7.8 KiB
JavaScript

var Mine=function(){var b=0,f=1,a=2,d=3;function e(g,h){return new Array(h+1).join(g)}function c(g){this.parse(g)}c.ALIVE=b;c.LOST=f;c.ABORTED=a;c.WON=d;c.prototype.parse=function(g){var o,k,h,n,j,m,p;this.orig_map=g;o=g.split(/\r\n?|\r?\n/);h=0;n=o.length;for(k=0;k<o.length;++k){if(0==o[k].length){n=k;o.splice(k,1);break}h=Math.max(h,o[k].length)}this.height=n;this.width=h;this.map=g=o.splice(0,n).reverse();this.lambdas=0;this.found_lambdas=0;this.moves=0;this.score=0;this.moves_below_water=0;this.water={level:0,flooding:0,proof:10};this.lift=this.robot=false;this.trampoline={sources:{},targets:{}};this.beard={growth:25,razors:0};g.splice(n,0,e("#",h));g.splice(0,0,e("#",h),e("#",h));n=n+3;h=h+2;for(k=0;k<n;++k){if(g[k].length<h-2){g[k]+=e(" ",h-g[k].length-2)}g[k]="#"+g[k]+"#";p=g[k]=g[k].split("");for(m=0;m<h;++m){switch(p[m]){case" ":case"*":case"#":case".":case"W":case"!":break;case"@":case"\\":this.lambdas++;break;case"L":if(this.lift!==false){throw"Only one lift is allowed"}this.lift={x:m,y:k};break;case"R":if(this.robot!==false){throw"Only one robot is allowed"}this.robot={x:m,y:k};break;default:if(p[m]>="A"&&p[m]<="I"){if(this.trampoline.sources[p[m]]){throw"Can have only one trampoline "+p[m]}this.trampoline.sources[p[m]]={x:m,y:k,target:false};this.trampoline.fromSources}else{if(p[m]>="1"&&p[m]<="9"){if(this.trampoline.targets[p[m]]){throw"Can have only one trampoline target "+p[m]}this.trampoline.targets[p[m]]={x:m,y:k,sources:[]}}else{throw"Invalid character in map: '"+p[m]+"'"+m}}break}}}if(this.robot===false){throw"Need a robot"}this.meta={};for(k=0;k<o.length;++k){if(0==o[k].length){continue}var l=o[k].split(/ +/);switch(l[0]){case"Water":this.water.level=parseInt(l[1]);break;case"Flooding":this.water.flooding=parseInt(l[1]);break;case"Waterproof":this.water.proof=parseInt(l[1]);break;case"Trampoline":if(l.length!==4||l[2]!=="targets"){throw"Invalid trampoline: '"+l.join(" ")+"'"}if(l[1].length!=1||l[1]<"A"||l[1]>"I"){throw"Invalid trampoline source '"+l[1]+"'"}if(l[3].length!=1||l[3]<"1"||l[3]>"9"){throw"Invalid trampoline target '"+l[3]+"'"}if(!this.trampoline.sources[l[1]]){throw"Trampoline "+l[1]+" not defined"}if(!this.trampoline.targets[l[3]]){throw"Trampoline target "+l[3]+" not defined"}if(this.trampoline.sources[l[1]].target){throw"Trampoline "+l[1]+" already has a target"}this.trampoline.sources[l[1]].target=l[3];this.trampoline.targets[l[3]].sources.push(l[1]);break;case"Growth":this.beard.growth=parseInt(l[1]);break;case"Razors":this.beard.razors=parseInt(l[1]);break;default:this.meta[l[0]]=l.splice(1).join(" ");break}}for(k in this.trampoline.sources){if(this.trampoline.sources.hasOwnProperty(k)){if(!this.trampoline.sources[k].target){throw"Trampoline "+k+" has no target"}}}for(k in this.trampoline.targets){if(this.trampoline.targets.hasOwnProperty(k)){if(0==this.trampoline.targets[k].sources.length){throw"Trampoline target "+k+" has no sources"}}}this.water_level=this.water.level;this.razors=this.beard.razors;this.state=b};c.prototype.get=function(g,h){if(g<0||h<0||g>=this.width||h>=this.height){return"#"}return this.map[h][g]};c.prototype.validMove=function(g){if(this.state!=b){return false}var i,h;g=g.toUpperCase();switch(g){case"L":case"R":i=(g=="L"?-1:1);h=this.map[this.robot.y][this.robot.x+i];switch(h){case"#":return false;case" ":case".":case"!":case"\\":return true;case"L":return false;case"O":return true;case"*":case"@":if(" "==this.map[this.robot.y][this.robot.x+2*i]){return true}default:if(this.trampoline.sources.hasOwnProperty(h)){return true}break}break;case"U":case"D":i=(g=="D"?-1:1);h=this.map[this.robot.y+i][this.robot.x];switch(h){case"#":return false;case" ":case".":case"!":case"\\":return true;case"L":return false;case"O":return true;case"*":return false;case"@":return false;default:if(this.trampoline.sources.hasOwnProperty(h)){return true}break}break;case"W":case"S":return this.razors>0;case"A":return true}return false};c.prototype.move=function(l){if(this.state!=b){return false}var k,p,z,w;var g,r,q,o,m,u,h=this.map,v;l=l.toUpperCase();if(this.validMove(l)){switch(l.toUpperCase()){case"L":case"R":k=(l=="L"?-1:1);h[this.robot.y][this.robot.x]=" ";p=h[this.robot.y][this.robot.x+k];switch(p){case"*":case"@":h[this.robot.y][this.robot.x+2*k]=p;break;case"\\":this.lambdas--;this.found_lambdas++;break;case"!":this.razors++;break;case"O":this._foundLift();break;default:if(this.trampoline.sources.hasOwnProperty(p)){z=this.trampoline.sources[p];w=this.trampoline.targets[z.target];for(k=0;k<w.sources.length;++k){z=this.trampoline.sources[w.sources[k]];h[z.y][z.x]=" "}this.robot.x=w.x;this.robot.y=w.y;k=0}}this.robot.x+=k;h[this.robot.y][this.robot.x]="R";break;case"U":case"D":k=(l=="D"?-1:1);h[this.robot.y][this.robot.x]=" ";p=h[this.robot.y+k][this.robot.x];switch(p){case"\\":this.lambdas--;this.found_lambdas++;break;case"!":this.razors++;break;case"O":this._foundLift();break;default:if(this.trampoline.sources.hasOwnProperty(p)){z=this.trampoline.sources[p];w=this.trampoline.targets[z.target];for(k=0;k<w.sources.length;++k){z=this.trampoline.sources[w.sources[k]];h[z.y][z.x]=" "}this.robot.x=w.x;this.robot.y=w.y;k=0}}this.robot.y+=k;h[this.robot.y][this.robot.x]="R";break;case"S":--this.razors;for(var o=-1;o<=1;++o){for(var m=-1;m<=1;++m){if("W"==h[this.robot.y+o][this.robot.x+m]){h[this.robot.y+o][this.robot.x+m]=" "}}}break;case"A":this._abort();return}}this.moves++;if(0==this.lambdas){if(false!==this.lift){this.map[this.lift.y][this.lift.x]="O"}}g=[];v=false;if(this.beard.growth>0&&0==(this.moves%this.beard.growth)){v=true}for(q=0;q<h.length;++q){g[q]=this.map[q].slice()}for(q=2;q<2+this.height;++q){for(r=1;r<=this.width;++r){p=h[q][r];if("*"===p||"@"===p){u=h[q-1][r];if(" "===u){g[q-1][r]=p;if("@"===p&&" "!=h[q-2][r]){g[q-1][r]="\\"}g[q][r]=" ";if("R"===h[q-2][r]){this._crushed()}}else{if((u==="*"||u==="\\"||u==="@")&&" "===h[q-1][r+1]&&" "===h[q][r+1]){g[q-1][r+1]=p;if("@"===p&&" "!=h[q-2][r+1]){g[q-1][r+1]="\\"}g[q][r]=" ";if("R"==h[q-2][r+1]){this._crushed()}}else{if((u==="*"||u==="@")&&" "===h[q-1][r-1]&&" "===h[q][r-1]){g[q-1][r-1]=p;if("@"===p&&" "!=h[q-2][r-1]){g[q-1][r-1]="\\"}g[q][r]=" ";if("R"==h[q-2][r-1]){this._crushed()}}}}}else{if(v&&"W"===p){for(o=-1;o<=1;++o){for(m=-1;m<=1;++m){if(" "===h[q+o][r+m]){g[q+o][r+m]="W"}}}}}}}this.map=g;if(this.robot.y<this.water_level+2){this.moves_below_water++;if(this.moves_below_water>this.water.proof){this._drown()}}else{this.moves_below_water=0}if(this.water.flooding>0&&0==(this.moves%this.water.flooding)){++this.water_level}switch(this.state){case f:this.score=25*this.found_lambdas-this.moves;break;case d:this.score=75*this.found_lambdas-this.moves;break;case b:case a:this.score=50*this.found_lambdas-this.moves;break}};c.prototype._drown=function(){if(this.state<f){this.state=f;this.reason="Drowned"}};c.prototype._crushed=function(){if(this.state<f){this.state=f;this.reason="Crushed by rock"}};c.prototype._foundLift=function(){if(this.state<d){this.state=d;this.reason="Found lift"}};c.prototype._abort=function(){if(this.state<a){this.state=a;this.reason="Aborted"}};c.prototype.toString=function(){return this.map.slice(2,-1).map(function(g){return g.slice(1,-1).join("")}).reverse().join("\n")};c.prototype.metaText=function(){var h,i=[],g=[];if(this.water.level!=0){g.push("Water "+this.water.level)}if(this.water.flooding!=0){g.push("Flooding "+this.water.flooding)}if(this.water.proof!=10){g.push("Waterproof "+this.water.proof)}for(h in this.trampoline.sources){if(this.trampoline.sources.hasOwnProperty(h)){i.push(h)}}i.sort();for(h=0;h<i.length;++h){g.push("Trampoline "+i[h]+" targets "+this.trampoline.sources[i[h]].target)}if(this.beard.growth!=25){g.push("Growth "+this.beard.growth)}if(this.beard.razors!=0){g.push("Razors "+this.beard.razors)}i=[];for(h in this.meta){if(this.meta.hasOwnProperty(h)){i.push(h)}}i.sort();for(h=0;h<i.length;++h){g.push(i[h]+" "+this.meta[i[h]])}return g.join("\n")};return c}();if(typeof exports!=="undefined"){exports.Mine=Mine};