icfp15/js/mine.min.js

1 line
7.1 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.trampoline.targets={};for(k=0;k<n;++k){if(g[k].length<h){g[k]+=e(" ",h-g[k].length)}p=g[k]=g[k].split("");for(m=0;m<h;++m){switch(p[m]){case" ":case"*":case"#":case".":break;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]+"'"}}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=l[1];break;case"Flooding":this.water.flooding=l[1];break;case"Waterproof":this.water.proof=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;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.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);if(this.robot.x+i<0){return false}if(this.robot.x+i>=this.width){return false}h=this.map[this.robot.y][this.robot.x+i];switch(h){case"#":return false;case" ":case".":case"\\":return true;case"L":return false;case"O":return true;case"*":if(this.robot.x+2*i<0){return false}if(this.robot.x+2*i>=this.width){return false}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);if(this.robot.y+i<0){return false}if(this.robot.y+i>=this.height){return false}h=this.map[this.robot.y+i][this.robot.x];switch(h){case"#":return false;case" ":case".":case"\\":return true;case"L":return false;case"O":return true;case"*":return false;default:if(this.trampoline.sources.hasOwnProperty(h)){return true}break}break;case"W":case"A":return true}return false};c.prototype.move=function(i){if(this.state!=b){return false}var h,j,p,o;i=i.toUpperCase();if(this.validMove(i)){switch(i.toUpperCase()){case"L":case"R":h=(i=="L"?-1:1);this.map[this.robot.y][this.robot.x]=" ";j=this.map[this.robot.y][this.robot.x+h];switch(j){case"*":this.map[this.robot.y][this.robot.x+2*h]="*";break;case"\\":this.lambdas--;this.found_lambdas++;break;case"O":this._foundLift();break;default:if(this.trampoline.sources.hasOwnProperty(j)){p=this.trampoline.sources[j];o=this.trampoline.targets[p.target];for(h=0;h<o.sources.length;++h){p=this.trampoline.sources[o.sources[h]];this.map[p.y][p.x]=" "}this.robot.x=o.x;this.robot.y=o.y;h=0}}this.robot.x+=h;this.map[this.robot.y][this.robot.x]="R";break;case"U":case"D":h=(i=="D"?-1:1);this.map[this.robot.y][this.robot.x]=" ";j=this.map[this.robot.y+h][this.robot.x];switch(j){case"\\":this.lambdas--;this.found_lambdas++;break;case"O":this._foundLift();break;default:if(this.trampoline.sources.hasOwnProperty(j)){p=this.trampoline.sources[j];o=this.trampoline.targets[p.target];for(h=0;h<o.sources.length;++h){p=this.trampoline.sources[o.sources[h]];this.map[p.y][p.x]=" "}this.robot.x=o.x;this.robot.y=o.y;h=0}}this.robot.y+=h;this.map[this.robot.y][this.robot.x]="R";break;case"A":this._abort();return}}this.moves++;if(0==this.lambdas){if(false!==this.lift&&"L"==this.map[this.lift.y][this.lift.x]){this.map[this.lift.y][this.lift.x]="O"}}var g=[],l,k,m;for(k=0;k<this.height;++k){g[k]=this.map[k].slice()}for(k=0;k<this.height;++k){for(l=0;l<this.width;++l){if("*"==this.map[k][l]){m=this.get(l,k-1);if(" "==m){g[k-1][l]="*";g[k][l]=" ";if("R"==this.get(l,k-2)){this._crushed()}}else{if((m=="*"||m=="\\")&&" "==this.get(l+1,k-1)&&" "==this.map[k][l+1]){g[k-1][l+1]="*";g[k][l]=" ";if("R"==this.get(l+1,k-2)){this._crushed()}}else{if((m=="*")&&" "==this.get(l-1,k-1)&&" "==this.map[k][l-1]){g[k-1][l-1]="*";g[k][l]=" ";if("R"==this.get(l-1,k-2)){this._crushed()}}}}}}}this.map=g;if(this.robot.y<this.water_level){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.map(function(g){return g.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)}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};