jocly
Version:
Board games 3D/2D UI and AI web library
1 lines • 7.24 kB
JavaScript
exports.model=Model={Game:{},Board:{},Move:{}},function(){var t,s,o="undefined"!=typeof Int8Array;o?(t=function(t){return new Int8Array(t)},s=function(t){var s=new Int8Array(t.length);return s.set(t),s}):(t=function(t){for(var s=[],o=0;o<t;o++)s.push(0);return s},s=function(t){for(var s=[],o=t.length,i=0;i<o;i++)s.push(t[i]);return s}),Model.Game.isAlive=function(t,s){return this.POS(s,t)in this.g.confine},Model.Game.C=function(t){return t%this.mOptions.width},Model.Game.R=function(t){return Math.floor(t/this.mOptions.width)},Model.Game.RC=function(t){return{r:Math.floor(t/this.mOptions.width),c:t%this.mOptions.width}},Model.Game.POS=function(t,s){return s*this.mOptions.width+t},Model.Game.STR2POS=function(t){var s=/^(\d+):(\d+)$/.exec(t);if(s){var o=parseInt(s[1]),i=parseInt(s[2]);return this.POS(i,o)}return null},Model.Game.InitGame=function(){var s=this.NBCOLS=this.mOptions.width,o=this.NBROWS=this.mOptions.height;this.g.confine={},this.g.totalCount=o*s;for(var i=0;i<o;i++)for(var r=0;r<s;r++)this.g.confine[this.POS(r,i)]=1;if(this.mOptions.deadCells)for(var e in this.mOptions.deadCells){var a=this.STR2POS(e);null!=a&&(this.g.totalCount--,delete this.g.confine[a])}this.g.dirDeltaRC=[[1,-1],[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1]],this.g.Graph={};for(var i=0;i<o;i++)for(var r=0;r<s;r++){var a=this.POS(r,i);if(a in this.g.confine){for(var h=t(this.g.dirDeltaRC.length),n=0;n<this.g.dirDeltaRC.length;n++){var l=this.g.dirDeltaRC[n],v=i+l[0],d=r+l[1],u=v*s+d;v>=0&&d>=0&&v<o&&d<s&&u in this.g.confine?h[n]=u:h[n]=-1}this.g.Graph[a]=h}}this.g.corners={};for(var a in this.g.confine){for(var f=0,l=0;l<8;l++){var u=this.g.Graph[a][l];u<0&&(f|=1<<l)}15!=(15&f)&&30!=(30&f)&&60!=(60&f)&&120!=(120&f)&&240!=(240&f)&&225!=(225&f)&&195!=(195&f)&&135!=(135&f)||(this.g.corners[a]=1)}this.g.borders={};for(var a in this.g.confine)if(!(a in this.g.corners)){for(var f=0,l=0;l<8;l++){var u=this.g.Graph[a][l];u<0&&(f|=1<<l)}7!=(7&f)&&14!=(14&f)&&28!=(28&f)&&56!=(56&f)&&112!=(112&f)&&224!=(224&f)&&193!=(193&f)&&131!=(131&f)||(this.g.borders[a]=1)}this.zobrist=new JocGame.Zobrist({board:{type:"array",size:s*o,values:["1","-1"]}})},Model.Move.Init=function(t){this.row=t.row,this.col=t.col,this.pass=t.pass},Model.Move.CopyFrom=function(t){this.row=t.row,this.col=t.col,this.pass=t.pass},Model.Move.ToString=function(){return this.pass?"-":String.fromCharCode("a".charCodeAt(0)+this.col)+(this.row+1)},Model.Move.Equals=function(t){return!(!t.pass||!this.pass)||this.row==t.row&&this.col==t.col},Model.Board.Init=function(t){this.zSign=0},Model.Board.InitialPosition=function(s){this.board=t(s.mOptions.width*s.mOptions.height),this.counts=[0,0],this.freeClose={},this.passes=0,this.lastMove=null;var o=this;[1,-1].forEach(function(t){var i=(1-t)/2;s.mOptions.initial[t].forEach(function(r){o.counts[i]++;var e=s.STR2POS(r);o.board[e]=t,delete o.freeClose[e];for(var a=0;a<8;a++){var h=s.g.Graph[e][a];h<0||(o.board[h]||(o.freeClose[h]=1))}o.zSign=s.zobrist.update(o.zSign,"board",t,e)})}),this.FindMoves(s),this.stable={};for(var i in s.g.corners)this.stable[i]=3;this.aboutStable={},this.aboutBorder={},this.rvUpdateStable(s,s.g.corners),this.rvUpdateAboutBorder(s)},Model.Board.CopyFrom=function(t){this.mWho=t.mWho,this.zSign=t.zSign,this.board=s(t.board),this.counts=[t.counts[0],t.counts[1]],this.freeClose={};for(var o in t.freeClose)this.freeClose[o]=1;this.passes=t.passes,this.lastMove=null,t.lastMove?this.lastMove={row:t.lastMove.row,col:t.lastMove.col}:this.lastMove=null,this.movePoss={1:s(t.movePoss[1]),"-1":s(t.movePoss[-1])},this.stable=t.stable,this.aboutStable=t.aboutStable,this.aboutBorder=t.aboutBorder},Model.Board.GenerateMoves=function(t){this.mMoves=[];for(var s=0;s<this.movePoss[this.mWho].length;s++){var o=this.movePoss[this.mWho][s],i=t.RC(o);this.PushMove(t,{row:i.r,col:i.c})}0==this.mMoves.length&&this.PushMove(t,{pass:!0,row:-1,col:-1})},Model.Board.FindMoves=function(t){this.movePoss={1:[],"-1":[]};var s=t.g.Graph;for(var o in this.freeClose){for(var i=s[o],r=0,e=0;e<8;e++){var a=i[e];if(a>=0){var h=-this.board[a];if(h){var n=1==h?1:2;if(!(r&n)){for(!0,a=s[a][e];this.board[a]==-h;)a=s[a][e];if(a>=0&&this.board[a]==h&&(r|=n),3==r)break}}}}1&r&&this.movePoss[1].push(o),2&r&&this.movePoss[-1].push(o)}},Model.Board.ApplyMove=function(t,s){if(this.lastMove=null,s.pass)return void this.passes++;this.lastMove={row:s.row,col:s.col},this.passes=0;var o=(1-this.mWho)/2,i=1<<o;this.counts[o]++;var r=t.POS(s.col,s.row),e=t.g.Graph,a=e[r];this.board[r]=this.mWho,this.zSign=t.zobrist.update(this.zSign,"board",this.mWho,r),delete this.freeClose[r];var h=!1,n={};(this.stable[r]||0)&i&&(h=!0,n[r]=1);for(var l=0;l<8;l++){var v=a[l];v>=0&&0==this.board[v]&&(this.freeClose[v]=1);for(var d=[];v>=0&&this.board[v]==-this.mWho;)d.push(v),v=e[v][l];if(v>=0&&d.length>0&&this.board[v]==this.mWho)for(var u=d.length-1;u>=0;u--){var f=d[u];this.zSign=t.zobrist.update(this.zSign,"board",-this.mWho,f),this.zSign=t.zobrist.update(this.zSign,"board",this.mWho,f),this.board[f]=this.mWho,this.counts[o]++,this.counts[1-o]--,(this.stable[f]||0)&i&&(h=!0,n[f]=1)}}h&&this.rvUpdateStable(t,n),r in t.g.borders&&this.rvUpdateAboutBorder(t),this.FindMoves(t)},Model.Board.rvUpdateStable=function(t,s){var o=this.stable;this.stable={};for(var i in o)this.stable[i]=o[i];for(var r=!0,e=1==this.mWho?1:2,a=t.g.Graph;r;){r=!1;var h={};for(var i in s)for(var n=a[i],l=0;l<8;l++){var v=n[l];v>=0&&!((this.stable[v]||0)&e)&&(h[v]=1)}var s={};for(var i in h){for(var n=a[i],d=0,l=0;l<8;l++){var v=n[l];(v<0||this.board[v]==this.mWho&&(this.stable[v]||0)&e)&&(d|=1<<l)}15!=(15&d)&&30!=(30&d)&&60!=(60&d)&&120!=(120&d)&&240!=(240&d)&&225!=(225&d)&&195!=(195&d)&&135!=(135&d)||(this.stable[i]=(this.stable[i]||0)|e,r=!0,s[i]=1)}}this.aboutStable={};for(var i in this.stable)if(!this.board[i])for(var n=a[i],l=0;l<8;l++){var v=n[l];v>=0&&!(v in this.stable)&&(this.aboutStable[v]=(this.aboutStable[v]||0)|this.stable[i])}},Model.Board.rvUpdateAboutBorder=function(t){this.aboutBorder={};var s=t.g.Graph,o=t.g.borders;for(var i in o)if(!this.board[i])for(var r=s[i],e=0;e<8;e++){var a=r[e];!(a>=0)||a in this.stable||a in this.aboutStable||a in o||(this.aboutBorder[a]=1)}},Model.Board.Evaluate=function(t){this.mEvaluation=0;t.mOptions.width,t.mOptions.height;if(2==this.passes||this.counts[0]+this.counts[1]==t.g.totalCount||0==this.counts[0]||0==this.counts[1])return this.mFinished=!0,void(this.counts[0]>this.counts[1]?this.mWinner=JocGame.PLAYER_A:this.counts[0]<this.counts[1]?this.mWinner=JocGame.PLAYER_B:this.mWinner=JocGame.DRAW);var s=t.mOptions.levelOptions,o={},i={1:0,"-1":0},r={1:0,"-1":0},e={1:0,"-1":0},a={1:0,"-1":0},h=t.g.confine,n=t.g.borders;for(var l in h){var v=this.board[l];if(v){var d=1==v?1:2,u=1==v?2:1;(this.stable[l]||0)&d?i[v]++:(this.aboutStable[l]||0)&u?l in n?e[v]++:r[v]++:l in n&&a[v]++}}o.stable=i[1]-i[-1],o.aboutStable=r[1]-r[-1],o.aboutStableBorder=e[1]-e[-1],o.border=a[1]-a[-1],o.count=this.counts[0]-this.counts[1];var f=this.movePoss[1].length+this.movePoss[-1].length;o.mobility=f?(this.movePoss[1].length-this.movePoss[-1].length)/f:0;for(var b in o){var c=o[b],m=s[b+"Factor"]||0,g=c*m;this.mEvaluation+=g}},Model.Board.GetSignature=function(){return this.zSign}}();