jocly/dist/browser/games/checkers/english-draughts-model.js
2017-05-18 00:16:28 +02:00

1 line
13 KiB
JavaScript

exports.model=Model={Game:{},Board:{},Move:{}},function(){function t(t){if(o){var e=t%s;return(t-e)/s*s+s-e}var n=s*i-t-1,r=n%s;return n-r+s-r}var s,i,o=!1;Model.Game.checkersPosToString=t,Model.Game.InitGameInfo=function(){},Model.Game.BuildGraphCoord=function(){var t=(this.mOptions.width,this.mOptions.height,[]),s=[];this.g.Graph=t,this.g.Coord=s},Model.Game.InitGame=function(){var t=this.mOptions.width,e=this.mOptions.height;if(s=t,i=e,o=this.mOptions.invertNotation||!1,this.g.compulsoryCatch=!0,this.g.canStepBack=!0,this.g.mustMoveForward=!1,this.g.mustMoveForwardStrict=!1,this.g.lastRowFreeze=!1,this.g.lastRowCrown=!1,this.g.captureLongestLine=!1,this.g.noMove="lose",this.g.kingCaptureShort=!1,this.g.kingValue=5,this.g.lastRowFactor=0,this.g.canCaptureBackward=!0,this.g.captureInstantRemove=!1,this.g.longRangeKing=!0,this.g.drawKvsK=!0,this.g.drawKvs2K=!0,this.g.whiteStarts=!0,this.g.king180deg=!1,this.g.suicide=!1,this.mOptions.variant)for(var n in this.mOptions.variant)this.mOptions.variant.hasOwnProperty(n)&&(this.g[n]=this.mOptions.variant[n]);this.BuildGraphCoord(),this.zobrist=new JocGame.Zobrist({board:{type:"array",size:this.g.Graph.length,values:["1/0","1/1","-1/0","-1/1"]}})},Model.Game.DestroyGame=function(){},Model.Game.CheckersDirections=4,Model.Game.Checkers2WaysDirections=[0,1,1,0],Model.Game.CheckersEachDirection=function(t,s){for(var i=0;i<this.CheckersDirections;i++){var o=this.g.Graph[t][i];if(null!=o&&0==s(o,i))return}},Model.Move.Init=function(t){this.pos=[];for(var s=t.pos?Object.keys(t.pos).sort():[],i=0;i<s.length;i++)this.pos.push(t.pos[i]);this.capt=[];for(var o=t.capt?Object.keys(t.capt).sort():[],i=0;i<o.length;i++)this.capt.push(t.capt[i])},Model.Move.ToString=function(s){s=s||"natural";var i=this;switch(s){case"natural":return function(){for(var s=[t(i.pos[0]),t(i.pos[i.pos.length-1])],o="-",e=1;e<i.capt.length;e++)null!=i.capt[e]&&(o="x",i.capt.length>3&&s.push(t(i.capt[e])));return s.join(o)}();case"hub":return function(){var s="-",o=[t(i.pos[0]),t(i.pos[i.pos.length-1])];if(i.capt[1]){s="x";var e=i.capt.slice(1).map(function(s){return t(s)});e.sort(),o=o.concat(e)}return o.join(s)}();case"dxp":return function(){var s=[t(i.pos[0]),t(i.pos[i.pos.length-1])];if(i.capt[1]){s.push(i.capt.length-1);for(var o=[],e=1;e<i.capt.length;e++)o.push(t(i.capt[e]));o.sort(),s=s.concat(o)}else s.push(0);return s.map(function(t){return t<10?"0"+t:t}).join("")}();default:return"??"}},Model.Board.Init=function(t){this.zSign=0},Model.Board.InitialPosition=function(t){var s=t.mOptions.width,i=t.mOptions.height,o=t.mOptions.initial;this.board=[];for(var e=0;e<i;e++)for(var n=0;n<s;n++)this.board[e*s+n]=-1;this.pieces=[];var r=0;if(t.mInitial){this.pCount=[0,0],this.spCount=[0,0],this.kpCount=[0,0];for(var a=0;a<t.mInitial.pieces.length;a++){var h=t.mInitial.pieces[a];this.board[h.p]=a,this.pieces.push({s:h.s,p:h.p,l:-1,t:h.t,plp:h.p}),this.zSign=t.zobrist.update(this.zSign,"board",h.s+"/"+h.t,h.p);var p=-(h.s-1)/2;this.pCount[p]++,0==h.t?this.spCount[p]++:this.kpCount[p]++}}else{for(var a in o.a)if(o.a.hasOwnProperty(a)){var u=o.a[a],c=u[0]*s+u[1],h={s:JocGame.PLAYER_A,p:c,l:-1,t:0,plp:c};this.pieces.push(h),this.board[c]=r++,this.zSign=t.zobrist.update(this.zSign,"board","1/0",c)}for(var a in o.b)if(o.b.hasOwnProperty(a)){var u=o.b[a],c=u[0]*s+u[1],h={s:JocGame.PLAYER_B,p:c,l:-1,t:0,plp:c};this.pieces.push(h),this.board[c]=r++,this.zSign=t.zobrist.update(this.zSign,"board","-1/0",c)}this.pCount=[o.a.length,o.b.length],this.spCount=[o.a.length,o.b.length],this.kpCount=[o.a.length,o.b.length]}},Model.Board.GenerateMoves=function(t){try{this._GenerateMoves(t)}catch(t){}},Model.Board._GenerateMoves=function(t){function s(t){for(var s=0;s<e.pieces.length;s++){var i=e.pieces[s];i&&i.s==e.mWho&&t(s,i.p)}}function i(s,o,n,r,a){for(;;){var h=[],p=[],u=[];if(t.CheckersEachDirection(s,function(i,c){var l;0==t.g.canCaptureBackward&&(l=t.g.Coord[s][0]);var g=t.Checkers2WaysDirections[c];if(a){if(t.g.longRangeKing)for(;e.board[i]==-1||t.g.king180deg&&null!=i&&n.indexOf(i)>=0;)i=t.g.Graph[i][c];if(null!=i&&e.board[i]>=0&&e.pieces[e.board[i]].s==-e.mWho){var v=i;if(i=t.g.Graph[i][c],t.g.kingCaptureShort){if(e.board[i]==-1||i==o[0]){for(var d=!0,f=0;f<r.length;f++)if(t.g.king180deg){if(n[f]==v){d=!1;break}}else if(t.g.captureInstantRemove&&n[f]==v||0==t.g.captureInstantRemove&&n[f]==v&&r[f]==g){d=!1;break}d&&(h.push(i),p.push(v),u.push(g)),i=t.g.Graph[i][c]}}else for(;e.board[i]==-1||i==o[0]||null!==i&&t.g.captureInstantRemove&&n.indexOf(i)>=0;){for(var d=!0,f=0;f<r.length;f++)if(t.g.captureInstantRemove&&n[f]==v||0==t.g.captureInstantRemove&&n[f]==v&&r[f]==g){d=!1;break}d&&(h.push(i),p.push(v),u.push(g)),i=t.g.Graph[i][c]}}}else if(e.board[i]>=0&&e.pieces[e.board[i]].s==-e.mWho){var m,C;if(0==t.g.canCaptureBackward&&(m=t.g.Coord[i][0],C=!1,(e.mWho==JocGame.PLAYER_A&&m>=l||e.mWho==JocGame.PLAYER_B&&m<=l)&&(C=!0)),t.g.canCaptureBackward||1==C){var b=t.g.Graph[i][c];if(null!=b&&(e.board[b]==-1||b==o[0]||null!==b&&t.g.captureInstantRemove&&n.indexOf(b)>=0)){for(var d=!0,f=0;f<r.length;f++)if(t.g.captureInstantRemove&&n[f]==i||0==t.g.captureInstantRemove&&n[f]==i&&r[f]==g){d=!1;break}d&&(h.push(b),p.push(i),u.push(g))}}}return!0}),0==h.length){o.length>1&&e.mMoves.push({pos:o,capt:n});break}if(!t.g.compulsoryCatch&&o.length>1){for(var c=[],l=0;l<o.length;l++)c.push(o[l]);for(var g=[],l=0;l<n.length;l++)g.push(n[l]);e.mMoves.push({pos:c,capt:g})}if(1!=h.length){for(var l=0;l<h.length;l++){for(var c=[],v=0;v<o.length;v++)c.push(o[v]);c.push(h[l]);for(var g=[],v=0;v<n.length;v++)g.push(n[v]);g.push(p[l]);for(var d=[],v=0;v<r.length;v++)d.push(r[v]);d.push(u[l]),i(h[l],c,g,d,a)}break}s=h[0],o.push(s),n.push(p[0]),r.push(u[0])}}var o=t.mOptions.height,e=this;if(this.mMoves=[],s(function(t,s){0==e.pieces[t].t?i(s,[s],[null],[null],!1):1==e.pieces[t].t&&i(s,[s],[null],[null],!0)}),0!=t.g.compulsoryCatch&&0!=this.mMoves.length||s(function(s,i){var n;0==e.pieces[s].t?((t.g.mustMoveForward||t.g.mustMoveForwardStrict||t.lastRowFreeze)&&(n=t.g.Coord[i][0]),t.CheckersEachDirection(i,function(r,a){var h,p,u;return t.g.mustMoveForwardStrict?(h=t.g.Coord[r][0],p=!1,(e.mWho==JocGame.PLAYER_A&&h>n||e.mWho==JocGame.PLAYER_B&&h<n)&&(p=!0)):t.g.mustMoveForward&&(h=t.g.Coord[r][0],p=!0,(e.mWho==JocGame.PLAYER_A&&h<n||e.mWho==JocGame.PLAYER_B&&h>n)&&(p=!1)),t.g.lastRowFreeze&&(u=!1,(e.mWho==JocGame.PLAYER_A&&n==o-1||e.mWho==JocGame.PLAYER_B&&0==n)&&(u=!0)),e.board[r]!=-1||!t.g.canStepBack&&r==e.pieces[s].l||(0!=t.g.mustMoveForward||0!=t.g.mustMoveForwardStrict)&&1!=p||0!=t.g.lastRowFreeze&&0!=u||e.mMoves.push({pos:[i,r],capt:[null,null]}),!0})):1==e.pieces[s].t&&t.CheckersEachDirection(i,function(s,o){if(t.g.longRangeKing)for(;e.board[s]==-1;)e.mMoves.push({pos:[i,s],capt:[null,null]}),s=t.g.Graph[s][o];else e.board[s]==-1&&(e.mMoves.push({pos:[i,s],capt:[null,null]}),s=t.g.Graph[s][o]);return!0})}),0==this.mMoves.length)switch(t.g.noMove){case"count":this.mFinished=!0,this.pCount[0]<this.pCount[1]?this.mWinner=JocGame.PLAYER_B:this.pCount[1]<this.pCount[0]?this.mWinner=JocGame.PLAYER_A:this.mWinner=JocGame.DRAW;break;case"lose":this.mFinished=!0,this.mWinner=-this.mWho;break;case"win":this.mFinished=!0,this.mWinner=this.mWho;break;default:this.mFinished=!0,this.mWinner=JocGame.DRAW}if(t.g.captureLongestLine){for(var n=this.mMoves,r=[],a=0,h=0;h<n.length;h++){var p=n[h];p.pos.length==a?r.push(p):p.pos.length>a&&(r=[p],a=p.pos.length)}this.mMoves=r}},Model.Board.Evaluate=function(t,s,i){if(t.mOptions.preventRepeat&&t.GetRepeatOccurence(this)>2)return this.mFinished=!0,void(this.mWinner=JocGame.DRAW);if(t.g.drawKvsK&&0==this.spCount[0]&&0==this.spCount[1]&&1==this.kpCount[0]&&1==this.kpCount[1])return this.mFinished=!0,void(this.mWinner=JocGame.DRAW);if(t.g.drawKvs2K&&0==this.spCount[0]&&0==this.spCount[1]&&this.kpCount[0]+this.kpCount[1]==3&&(1==this.kpCount[0]||2==this.kpCount[0]))return this.mFinished=!0,void(this.mWinner=JocGame.DRAW);if(0==this.pCount[1])return this.mFinished=!0,void(this.mWinner=t.g.suicide?JocGame.PLAYER_B:JocGame.PLAYER_A);if(0==this.pCount[0])return this.mFinished=!0,void(this.mWinner=t.g.suicide?JocGame.PLAYER_A:JocGame.PLAYER_B);if(this.mEvaluation=10*(this.spCount[0]-this.spCount[1])+10*(this.kpCount[0]-this.kpCount[1])*t.g.kingValue+this.pCount[0]/this.pCount[1]-this.pCount[1]/this.pCount[0],0!=t.g.lastRowFactor){for(var o=t.mOptions.height,e=0,n=0,r=0;r<this.pieces.length;r++){var a=this.pieces[r];a&&0==a.t&&(this.mWho==JocGame.PLAYER_A?e+=t.g.Coord[a.p][0]:n+=o-1-t.g.Coord[a.p][0])}this.mEvaluation+=(e-n)*t.g.lastRowFactor,t.g.suicide&&(this.mEvaluation=-this.mEvaluation)}},Model.Board.CopyFrom=function(t){this.board=[];for(var s=0;s<t.board.length;s++)this.board[s]=t.board[s];this.pieces=[];for(var s=0;s<t.pieces.length;s++){var i=t.pieces[s];this.pieces[s]=null==i?null:{s:i.s,p:i.p,l:i.l,t:i.t,plp:i.plp}}this.pCount=[t.pCount[0],t.pCount[1]],this.spCount=[t.spCount[0],t.spCount[1]],this.kpCount=[t.kpCount[0],t.kpCount[1]],this.mWho=t.mWho,this.zSign=t.zSign},Model.Board.ApplyMove=function(t,s){var i=(t.mOptions.width,t.mOptions.height),o=s.pos[0],e=this.board[o],n=this.pieces[e],r=n.s;n.l=o;var a={};this.zSign=t.zobrist.update(this.zSign,"board",n.s+"/"+n.t,n.p);for(var h=1;h<s.pos.length;h++){var p=s.pos[h];this.board[n.p]=-1,n.p=p,this.board[p]=e;var u=s.capt[h];null!=u&&(this.board[u]>=0&&(a[this.board[u]]=!0),this.board[u]=-1),o=p}this.zSign=t.zobrist.update(this.zSign,"board",n.s+"/"+n.t,p);var c=s.capt[s.capt.length-1];n.plp=c||s.pos[s.pos.length-2];for(var l in a)if(a.hasOwnProperty(l)){var g=this.pieces[l],v=(1-g.s)/2;switch(this.pCount[v]--,g.t){case 0:this.spCount[v]--;break;case 1:this.kpCount[v]--}this.zSign=t.zobrist.update(this.zSign,"board",g.s+"/"+g.t,g.p),this.pieces[l]=null}if(t.g.lastRowCrown&&0==this.pieces[e].t){var d=t.g.Coord[s.pos[s.pos.length-1]][0];if(r==JocGame.PLAYER_A&&d==i-1||r==JocGame.PLAYER_B&&0==d){var g=this.pieces[e];g.t=1;var f=(1-r)/2;this.spCount[f]--,this.kpCount[f]++,this.zSign=t.zobrist.update(this.zSign,"board",g.s+"/0",g.p),this.zSign=t.zobrist.update(this.zSign,"board",g.s+"/1",g.p)}}},Model.Board.IsValidMove=function(t,s){return!0},Model.Board.GetSignature=function(){return this.zSign},Model.Game.Import=function(t,s){function i(t,s,i){i=n-i;var o=i%r;i=i-o+r-o-1,e.push({s:t,p:i,l:-1,t:s,plp:i})}var o=1,e=[],n=this.mOptions.width*this.mOptions.height,r=this.mOptions.width;if("pjn"==t){var a=s.split(":");o="W"==a[0]?1:-1;for(var h=1;h<a.length;h++)if(0!=a[h].length)for(var p="W"==a[h].substr(0,1)?1:-1,u=a[h].substr(1).split(","),c=0;c<u.length;c++){var l=u[c],g=0;"K"==l.substr(0,1)&&(g=1,l=l.substr(1));var v=/^([0-9]+)-([0-9]+)$/.exec(l);if(v)for(var d=parseInt(v[1]);d<=parseInt(v[2]);d++)i(p,g,d);else i(p,g,parseInt(l))}return e.sort(function(t,s){return s.s-t.s}),{status:!0,initial:{pieces:e,turn:o}}}return{status:!1,error:"unsupported"}};var e=JocGame.prototype.GetBestMatchingMove;Model.Game.GetBestMatchingMove=function(t,s){var i=[],o=this;s.forEach(function(t){"function"==typeof t.ToString?i.push(t.ToString()):i.push(o.CreateMove(t).ToString())}),t=t.replace(/0([1-9])/g,"$1");var n=/^([0-9]+)[\-x]([0-9]+)([\-x][0-9]+)*$/.exec(t);if(n){var r=new RegExp("^"+n[1]+"[-x]"+n[2]+"([-x][0-9]+)*$"),a={};s.forEach(function(t,s){if(r.test(i[s])){var o=i[s],e=/^([0-9]+)x([0-9]+)x([0-9]+(x[0-9]+)*)/.exec(o);if(e){var n=e[3].split("x");n.sort(function(t,s){return parseInt(t)-parseInt(s)}),o=e[1]+"x"+e[2]+"x"+n.join("x")}a[o]=t}});var h=[];for(var p in a)a.hasOwnProperty(p)&&h.push(a[p]);h.length>0&&(s=h)}return e.call(this,t,s)},Model.Board.ExportBoardState=function(o,e){function n(t){for(var o=[],e=0;e<r.board.length;e++){var n=e%s,a=(e-n)/s,h=(i-a-1)*s+n,p=r.board[e];if(p<0)o[h]="e";else{var u=r.pieces[p],c=1==u.s?"w":t;1==u.t&&(c=c.toUpperCase()),o[h]=c}}return o.join("")}e=e||"natural";var r=this;switch(e){case"natural":case"fen":return function(){var s={},i=[];r.pieces.forEach(function(i){if(i&&null!=i.p){var o=1==i.s?"W":"B";void 0===s[o]&&(s[o]={});var e=1==i.t?"K":"";void 0===s[o][e]&&(s[o][e]={group:0==i.t,pos:[]}),s[o][e].pos.push(parseInt(t(i.p)))}});for(var o in s)if(s.hasOwnProperty(o)){var e=[];for(var n in s[o])if(s[o].hasOwnProperty(n)){var a=s[o][n];if(a.group){a.pos.sort(function(t,s){return parseInt(t)-parseInt(s)});var h=-2,p=-1,u=-1;a.pos.forEach(function(t){parseInt(t)==h+1?p=t:(p>=0?(e.push(n+u+"-"+p),p=-1):u>=0&&e.push(n+u),u=t),h=parseInt(t)}),p>=0?e.push(n+u+"-"+p):u>=0&&e.push(n+u)}else a.pos.forEach(function(t){e.push(n+t)})}i.push(o+e.join(","))}return i.join(":")}();case"dxp":return function(){return n("z")}();case"hub":return function(){return n("z")}();default:return JSON.stringify(this)}}}(),Model.Game.BuildGraphCoord=function(){for(var t=this.mOptions.width,s=this.mOptions.height,i=[],o=[],e=0;e<s;e++)for(var n=0;n<t;n++){var r=e*t+n;o[r]=[e,n],i[r]=[],e%2==0?(e<s-1?(i[r].push((e+1)*t+n),n>0?i[r].push((e+1)*t+n-1):i[r].push(null)):(i[r].push(null),i[r].push(null)),e>0?(i[r].push((e-1)*t+n),n>0?i[r].push((e-1)*t+n-1):i[r].push(null)):(i[r].push(null),i[r].push(null))):(e<s-1?(n<t-1?i[r].push((e+1)*t+n+1):i[r].push(null),i[r].push((e+1)*t+n)):(i[r].push(null),i[r].push(null)),e>0?(n<t-1?i[r].push((e-1)*t+n+1):i[r].push(null),i[r].push((e-1)*t+n)):(i[r].push(null),i[r].push(null)))}this.g.Graph=i,this.g.Coord=o};