jocly
Version:
Board games 3D/2D UI and AI web library
1 lines • 13.4 kB
JavaScript
exports.model=Model={Game:{},Board:{},Move:{}},Model.Game.HexInitRCPosAndLayout=function(){for(var t=this.mOptions.maxLines,i=[],e=[],s=0,o=0;o<this.mOptions.maxLines;o++){i[o]=[],e[o]=[];for(var r=0;r<this.mOptions.maxCols;r++)i[o][r]=this.mOptions.boardLayout[t-1-o][r],"."!=i[o][r]?(e[o][r]=s,s++):e[o][r]=-1}this.g.rcPositions=e,this.g.Layout=i,this.g.nbPos=s},Model.Game.HexRcPos=function(t,i){return this.g.rcPositions[t][i]},Model.Game.HexIsCell=function(t,i){return!(t<0||t>=this.mOptions.maxLines||i<0||i>=this.mOptions.maxCols)&&"."!=this.g.Layout[t][i]},Model.Game.HexInitGame=function(){this.HexInitRCPosAndLayout(),this.g.orientation=this.mOptions.orientation,this.g.maxNbCellsPerMove=this.mOptions.maxNbCellsPerMove,this.g.margin=this.mOptions.margin;for(var t=[],i=[],e=0;e<this.mOptions.maxLines;e++)for(var s=0;s<this.mOptions.maxCols;s++)if(this.HexIsCell(e,s)){var o=this.HexRcPos(e,s);if(i[o]=[e,s],t[o]=[],"onASide"==this.g.orientation)for(var r=0;r<6;r++)switch(r){case 0:this.HexIsCell(e+1,s+1)?t[o].push(this.HexRcPos(e+1,s+1)):t[o].push(null);break;case 1:this.HexIsCell(e+2,s)?t[o].push(this.HexRcPos(e+2,s)):t[o].push(null);break;case 2:this.HexIsCell(e+1,s-1)?t[o].push(this.HexRcPos(e+1,s-1)):t[o].push(null);break;case 3:this.HexIsCell(e-1,s-1)?t[o].push(this.HexRcPos(e-1,s-1)):t[o].push(null);break;case 4:this.HexIsCell(e-2,s)?t[o].push(this.HexRcPos(e-2,s)):t[o].push(null);break;case 5:this.HexIsCell(e-1,s+1)?t[o].push(this.HexRcPos(e-1,s+1)):t[o].push(null)}else for(var r=0;r<6;r++)switch(r){case 0:this.HexIsCell(e,s+2)?t[o].push(this.HexRcPos(e,s+2)):t[o].push(null);break;case 1:this.HexIsCell(e+1,s+1)?t[o].push(this.HexRcPos(e+1,s+1)):t[o].push(null);break;case 2:this.HexIsCell(e+1,s-1)?t[o].push(this.HexRcPos(e+1,s-1)):t[o].push(null);break;case 3:this.HexIsCell(e,s-2)?t[o].push(this.HexRcPos(e,s-2)):t[o].push(null);break;case 4:this.HexIsCell(e-1,s-1)?t[o].push(this.HexRcPos(e-1,s-1)):t[o].push(null);break;case 5:this.HexIsCell(e-1,s+1)?t[o].push(this.HexRcPos(e-1,s+1)):t[o].push(null)}}this.g.Graph=t,this.g.Coord=i},Model.Game.DestroyGame=function(){},Model.Board.xtraInitBoard=function(t){},Model.Board.HexInit=function(t){var i=t.mOptions.maxCols,e=t.mOptions.maxLines;this.board=[];var s=-1;void 0!=t.mOptions.boardInitValue&&(s=t.mOptions.boardInitValue);for(var o=0;o<e;o++)for(var r=0;r<i;r++)this.board[t.HexRcPos(o,r)]=s;var a=t.mOptions.initial;this.pieces=[];var h=0,n=[{},{}];if(a)for(var c=0;c<e;c++)for(var o=e-1-c,r=0;r<i;r++){var p=t.HexRcPos(o,r);switch(a.a[c][r]){case".":case"#":break;default:var l=a.a[c][r],m=n[0][l];void 0===m&&(n[0][l]=0),this.pieces.push({s:JocGame.PLAYER_A,pos:p,type:l,alive:!0,index:n[0][l]++}),this.board[p]=h++}switch(a.b[c][r]){case".":case"#":break;default:var l=a.b[c][r],m=n[1][l];void 0===m&&(n[1][l]=0),this.pieces.push({s:JocGame.PLAYER_B,pos:p,type:l,alive:!0,index:n[1][l]++}),this.board[p]=h++}}},Model.Game.InitGame=function(){this.HexInitGame(),this.g.GetStrengthByType=function(t){switch(t){case"C":return 5;case"c":return 3;case"p":return 2;default:return 0}},this.g.distAmiralToLastRowSubFactor={"-1":10,0:0,1:-10},this.g.distAmiralToLastRowFactor=3,this.g.pieceWeight={c:2,p:1,C:0,r:0},this.g.weightFactor=3,this.g.GainOtherAmiralDist=[0,15,4,2,1,.7,.6,.5,.4,.3,.2,.1,0],this.g.GainSelfAmiralDist=[0,5,4,2,1,.7,.6,.5,.4,.3,.2,.1,0],this.g.gainOtherAmiralDistSubFactor=1,this.g.gainSelfAmiralDistSubFactor=1,this.g.yohohoFactor=2,this.g.MoveCount=22;var t=this;this.g.Dist=function(i,e){if(i==e)return 0;if(e<i){var s=i;i=e,e=s}return t.g.DistArray[i][e-i-1]};var i=this.g.Graph.length;this.g.DistArray=[];for(var e=0;e<i-1;e++){for(var s=[],o=0;o<i-e;o++)s.push(-1);this.g.DistArray.push(s)}this.g.SetDist=function(i,e,s){if(i!=e){if(e<i){var o=i;i=e,e=o}t.g.DistArray[i][e-i-1]=s}};for(var r=0;r<i;r++)this.YohohoEachDirection(r,function(i){if(r<i){t.g.Dist(r,i)<0&&t.g.SetDist(r,i,1)}return!0});for(var r=0;r<i;r++)this.YohohoEachDirection(r,function(e){if(r<e)for(var s=0;s<i;s++){var o=t.g.Dist(s,r);if(o>=0){var a=t.g.Dist(s,e);(-1==a||o+1<a)&&t.g.SetDist(s,e,o+1)}}return!0})},Model.Move.Init=function(t){void 0!==t&&this.CopyFrom(t)},Model.Move.CopyFrom=function(t){if(this.t=t.t,"m"==t.t)this.m=[{f:t.m[0].f,t:t.m[0].t},{f:t.m[1].f,t:t.m[1].t}];else if("a"==t.t){this.af=[];for(var i=0;i<t.af.length;i++)this.af.push(t.af[i]);this.at=t.at}},Model.Move.ToString=function(){var t;return"m"==this.t?(t="M "+this.m[0].f+">"+this.m[0].t,void 0!==this.m[1].f&&(t+=" "+this.m[1].f+">"+this.m[1].t)):t="A "+this.af.join(",")+">"+this.at,t},Model.Board.InitialPosition=function(t){this.HexInit(t),this.first=!0,this.yohoho=!1,this.amirals={};for(var i=0;i<this.pieces.length;i++){var e=this.pieces[i];"C"==e.type&&(this.amirals[e.s]=i),e.s==JocGame.PLAYER_A?e.angle=0:e.angle=180}this.piecesWeight={"-1":8,1:8}},Model.Board.GenerateMoves=function(t){function i(t,i){if(t.index==i.index)return!1;for(var e=0;e<t.reqEmpty.length;e++){var s=t.reqEmpty[e];if(-1!=o.board[s])return!1}for(var e=0;e<i.reqEmpty.length;e++){var s=i.reqEmpty[e];if(s==t.t)return!1;if(-1!=o.board[s]&&s!=t.f)return!1}return t.t!=i.t}var e=!1,s=t.g.MoveCount;void 0!==t.mLevelInfo&&(void 0!==t.mLevelInfo.rowRaceLevel&&(e=t.mCurrentLevel>=0&&t.mCurrentLevel<=t.mLevelInfo.rowRaceLevel),void 0!==t.mLevelInfo.moveCount&&(s=t.mLevelInfo.moveCount));var o=this,r=this.pieces[this.amirals[this.mWho]].pos,a=this.pieces[this.amirals[-this.mWho]].pos,h=t.g.Coord[a][0],n=h-this.mWho,c={},p=[],l=[],m=this.pieces;e&&(m=[this.pieces[this.amirals[this.mWho]]]);for(var f=0;f<m.length;f++){var u=m[f];if(u.s==this.mWho&&u.alive)for(var v=this.YohohoReachablePositionsThrough(t,u.pos,u.type),g=0;g<v.length;g++){var d={f:u.pos,t:v[g].pos,index:f,reqEmpty:v[g].reqEmpty},b=0;if("C"==u.type){var y=t.g.Coord[u.pos],x=y[0],A=this.mWho==JocGame.PLAYER_A?8-x:x;y=t.g.Coord[d.t];var C=y[0],G=this.mWho==JocGame.PLAYER_A?8-C:C;0==G&&-1==this.board[d.t]&&l.push(d),b+=12,b+=t.g.distAmiralToLastRowSubFactor[G-A]}else"c"==u.type&&(b+=1);var M=t.g.Dist(d.t,r),R=t.g.Dist(d.t,a),E=t.g.GainSelfAmiralDist[M],D=t.g.GainOtherAmiralDist[R];2!=R||"c"!=u.type&&"p"!=u.type||t.YohohoEachDirection(d.t,function(i){return-1!=o.board[i]||1!=t.g.Dist(i,a)||1!=t.g.Dist(i,r)||t.g.Coord[i][0]!=n||(b+=3,!1)});var P=Math.max(E*t.g.gainSelfAmiralDistSubFactor,D*t.g.gainOtherAmiralDistSubFactor);b+=P,d.eval=b,void 0===c[d.index]&&(c[d.index]=[]),c[d.index].push(d)}}if(l.length>0)for(var f=0;f<l.length;f++){var d=l[f];this.mMoves.push({t:"m",m:[{f:d.f,t:d.t},{}]})}else{var L=[];for(var Y in c)if(c.hasOwnProperty(Y)){var H=c[Y];H.sort(function(t,i){return i.eval-t.eval}),L.push(H)}L.sort(function(t,i){return i[0].eval-t[0].eval});for(var W=1,I=0;L.length>0;)p.push(L[I].shift()),0==L[I].length?(L.splice(I,1),W--):I++,I==W&&(W<L.length&&W++,I=0);if(e){for(var B=[],k=-1,f=0;f<p.length;f++){var d=p[f],F=(t.g.Coord[d.t][0]-t.g.Coord[d.t][0])*this.mWho;F==k?B.push(d):F>k&&(k=F,B=[d])}this.mMoves=this.YohohoCaptures(t,this.mWho);for(var f=0;f<B.length;f++){var d=B[f];-1==this.board[d.t]&&this.mMoves.push({t:"m",m:[{f:d.f,t:d.t},{}]})}return void(0==this.mMoves.length&&(this.mFinished=!0,this.mWinner=JocGame.DRAW))}var S=[],O=this.YohohoAmiralCapture(t,this.mWho);if(O.risk){for(var f=0;f<O.capture.length;f++){var w=O.capture[f],J=JSON.parse(JSON.stringify(w.af));this.mMoves.push({t:"a",af:J,at:w.at})}for(var g=0;g<p.length&&S.length<s;g++)for(var f=0;f<O.escape.length&&S.length<s;f++){var T=this.amirals[this.mWho],_=this.pieces[T],q={f:_.pos,t:O.escape[f].t,index:T,reqEmpty:[O.escape[f].t]};if(p[g].index!=T){var N=i(q,p[g]);N?S.push({t:"m",m:[{f:q.f,t:q.t},{f:p[g].f,t:p[g].t}]}):i(p[g],q)&&S.push({t:"m",m:[{f:p[g].f,t:p[g].t},{f:q.f,t:q.t}]})}}return this.mMoves=this.mMoves.concat(S),void(0==this.mMoves.length&&(this.mFinished=!0,this.mWinner=-this.mWho))}if(this.first)for(var g=0;g<f&&S.length<s;g++)-1==this.board[p[g].t]&&S.push({t:"m",m:[{f:p[g].f,t:p[g].t},{}]});else for(var f=1;f<p.length&&S.length<s;f++)for(var g=0;g<f&&S.length<s;g++)p[f].index!=p[g].index&&(i(p[f],p[g])?S.push({t:"m",m:[{f:p[f].f,t:p[f].t},{f:p[g].f,t:p[g].t}]}):i(p[g],p[f])&&S.push({t:"m",m:[{f:p[g].f,t:p[g].t},{f:p[f].f,t:p[f].t}]}));this.mMoves=this.YohohoCaptures(t,this.mWho),this.mMoves=this.mMoves.concat(S),0==this.mMoves.length&&(this.mFinished=!0,this.mWinner=-this.mWho)}},Model.Board.IsValidMove=function(t,i){return!0},Model.Board.Evaluate=function(t,i,e){this.mEvaluation=0;var s=this.YohohoAmiralCapture(t,JocGame.PLAYER_A);s.risk&&s.end&&(this.mFinished=!0,this.mWinner=JocGame.PLAYER_B);var o=this.YohohoAmiralCapture(t,JocGame.PLAYER_B);o.risk&&o.end&&(this.mFinished=!0,this.mWinner=JocGame.PLAYER_A);var r=this.pieces[this.amirals[JocGame.PLAYER_A]].pos,a=this.pieces[this.amirals[JocGame.PLAYER_B]].pos,h=t.g.Coord[r][0];8==h&&(this.mFinished=!0,this.mWinner=JocGame.PLAYER_A);var n=t.g.Coord[a][0];if(0==n&&(this.mFinished=!0,this.mWinner=JocGame.PLAYER_B),!this.mFinished){var c=t.g.distAmiralToLastRowFactor;switch(t.g.Dist(r,a)){case 1:c=t.g.distAmiralToLastRowFactor;break;case 2:c=1.2*t.g.distAmiralToLastRowFactor;break;default:c=2*t.g.distAmiralToLastRowFactor}this.mEvaluation+=(h-8+n)*c,this.mEvaluation+=(this.piecesWeight[JocGame.PLAYER_A]-this.piecesWeight[JocGame.PLAYER_B])*t.g.weightFactor;for(var p=0,l=0,m=0;m<this.pieces.length;m++){var f=this.pieces[m];if(f.alive){var u=Math.min(t.g.Dist(f.pos,r),t.g.Dist(f.pos,a));f.s==JocGame.PLAYER_A?p+=u:l+=u}}this.mEvaluation+=.001*(l-p),this.mEvaluation+=(s?-t.g.yohohoFactor:0)+(o?t.g.yohohoFactor:0)}},Model.Board.yohohoUpdateAngle=function(t,i,e,s){var o=0;if(void 0===s||void 0===e)o=0;else{var r=t.g.Coord[e],a=t.g.Coord[s];o=a[1]>r[1]?a[0]>r[0]?-30:a[0]<r[0]?-150:-90:a[0]>r[0]?30:a[0]<r[0]?150:90}i.angle=o},Model.Board.ApplyMove=function(t,i){if("m"==i.t){var e=this.board[i.m[0].f],s=this.pieces[e].s;this.board[i.m[0].f]=-1,this.board[i.m[0].t]=e,this.pieces[e].pos=i.m[0].t,this.yohohoUpdateAngle(t,this.pieces[e],i.m[0].f,i.m[0].t),0==this.first&&void 0!==i.m[1].f&&(e=this.board[i.m[1].f],e<0&&JocLog("!!!! move from nowhere",i),this.board[i.m[1].f]=-1,this.board[i.m[1].t]=e,this.pieces[e].pos=i.m[1].t,this.yohohoUpdateAngle(t,this.pieces[e],i.m[1].f,i.m[1].t));var o=this.YohohoAmiralCapture(t,-s);this.yohoho=o.risk}else if("a"==i.t){var e=this.board[i.at];this.board[i.at]=-1,this.pieces[e].alive=0,this.piecesWeight[-this.mWho]-=t.g.pieceWeight[this.pieces[e].type]}this.first=!1},Model.Board.YohohoReachablePositions=function(t,i,e,s,o){var r=this,a=[],h=0,n=this.pieces[this.board[i]].s,c="YohohoEachDirectionWind";switch(e){case"C":h=1;break;case"c":h=2;break;case"p":h=3;break;case"r":c="YohohoEachDirection"}return t[c](i,function(i,c){for(var p=0;null!=i&&(0==h||p<h)&&(i==s||-1==r.board[i]&&i!=o);){var l=!0;if("C"==e){var m=0;t.YohohoEachDirection(i,function(i){var e=r.board[i];if(e>=0&&r.pieces[e].alive&&r.pieces[e].s==-n){var s=t.g.GetStrengthByType(r.pieces[e].type);m+=s}return!0}),m>5&&(l=!1)}l&&a.push(i),i=t.g.Graph[i][c],p++}return!0}),a},Model.Board.YohohoReachablePositionsThrough=function(t,i,e){var s=this,o=[],r=0,a=this.pieces[this.board[i]].s,h="YohohoEachDirectionWind";switch(e){case"C":r=1;break;case"c":r=2;break;case"p":r=3;break;case"r":h="YohohoEachDirection"}return t[h](i,function(i,h){for(var n=0,c=[];null!=i&&(0==r||n<r)&&(-1==s.board[i]||s.pieces[s.board[i]].s==a);){var p=!0;if("C"==e){var l=0;t.YohohoEachDirection(i,function(i){var e=s.board[i];if(e>=0&&s.pieces[e].alive&&s.pieces[e].s==-a){var o=t.g.GetStrengthByType(s.pieces[e].type);l+=o}return!0}),l>5&&(p=!1)}if(c.push(i),p){for(var m=[],f=0;f<c.length;f++)m.push(c[f]);o.push({pos:i,reqEmpty:m})}i=t.g.Graph[i][h],n++}return!0}),o},Model.Game.YohohoEachDirection=function(t,i){for(var e=0;e<6;e++){var s=this.g.Graph[t][e];if(null!=s&&0==i(s,e))return}},Model.Game.YohohoEachDirectionWind=function(t,i){for(var e=1;e<6;e++){var s=this.g.Graph[t][e];if(null!=s&&0==i(s,e))return}},Model.Board.YohohoAmiralCapture=function(t,i){var e=this,s={risk:!1},o=this.pieces[this.amirals[i]].pos,r=0,a=[];if(t.YohohoEachDirection(o,function(s){var o=e.board[s];if(o>=0&&e.pieces[o].alive&&e.pieces[o].s==-i){var h=t.g.GetStrengthByType(e.pieces[o].type);h>0&&a.push(o),r+=h}return!0}),r<=5)return s;s.risk=!0,s.attackers=a,s.capture=[];for(var h=0;h<a.length;h++){var n=a[h],c=t.g.GetStrengthByType(this.pieces[n].type);if(r-c<=5){var p=0,l=[];t.YohohoEachDirection(this.pieces[n].pos,function(s){var o=e.board[s];if(o>=0&&e.pieces[o].alive&&e.pieces[o].s==i){var r=t.g.GetStrengthByType(e.pieces[o].type);r>0&&l.push(e.pieces[o].pos),p+=r}return!0}),p>c&&s.capture.push({af:l,at:this.pieces[n].pos})}}return s.escape=[],t.YohohoEachDirectionWind(o,function(r){if(-1==e.board[r]){var a=0;t.YohohoEachDirection(r,function(s){var o=e.board[s];if(o>=0&&e.pieces[o].alive&&e.pieces[o].s==-i){var r=t.g.GetStrengthByType(e.pieces[o].type);a+=r}}),a<=5&&s.escape.push({f:o,t:r})}return!0}),s.end=0==s.escape.length&&0==s.capture.length,s},Model.Board.YohohoCaptures=function(t,i){for(var e=this,s=[],o=0;o<e.pieces.length;o++){var r=e.pieces[o];if(r.s==-i&&r.alive){var a=t.g.GetStrengthByType(r.type),h=[];if(a>0){var n=0;t.YohohoEachDirection(r.pos,function(s){var o=e.board[s];if(o>=0&&e.pieces[o].alive&&e.pieces[o].s==i){var r=t.g.GetStrengthByType(e.pieces[o].type);r>0&&h.push(s),n+=r}return!0}),n>a&&s.push({t:"a",af:h,at:r.pos})}}}return s};