From 90b52a76d0330b726b06b39bf7127d80bb3d2fb1 Mon Sep 17 00:00:00 2001 From: Max Irwin Date: Sun, 29 Dec 2013 22:32:23 +0000 Subject: [PATCH] Improvements to generatemoves --- README.md | 2 +- automin.sh | 4 ++- backgammon.min.js | 17 +++++------ build/board.min.js | 6 ++-- build/game.min.js | 9 ++++-- build/main.min.js | 2 +- example.html | 12 +++----- src/board.js | 15 ++++++---- src/game.js | 72 ++++++++++++++++++++++++++++++++++------------ src/main.js | 14 ++++----- 10 files changed, 95 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index c5c78a0..977bd91 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# backgammon.js v0.1 +# backgammon.js v0.1 (alpha) Backgammon via JavaScript Backgammon.js consists of four modules: diff --git a/automin.sh b/automin.sh index 5e0c692..89e910a 100755 --- a/automin.sh +++ b/automin.sh @@ -1,5 +1,7 @@ #!/bin/sh +./min.sh + # get the current path CURPATH=`pwd` @@ -11,7 +13,7 @@ inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \ # convert absolute path to relative FILECHANGEREL=`echo "$FILECHANGE" | sed 's_'$CURPATH'/__'` - /home/max/apps/backgammon.js/min.sh + ./min.sh echo "At ${time} on ${date}, file $FILECHANGE triggered a minify" ./automin.sh done \ No newline at end of file diff --git a/backgammon.min.js b/backgammon.min.js index 90f095d..f0726d4 100644 --- a/backgammon.min.js +++ b/backgammon.min.js @@ -1,4 +1,4 @@ -;var backgammon=(function(context){"use strict";var gammon=context.backgammon={};gammon.sequence=function(type){var id=0;return function(){return type+(id++);}};gammon.rand1=function(max){return Math.floor(Math.random()*max);};gammon.rand2=function(min,max){return Math.floor(Math.random()*(max-min+1))+min;};gammon.defaults={orientation:true,delay:505,position:'2W////5B/3B///5W5B///3W/5W////2B W 00 0 00'};return gammon;})(this);;(function(backgammon){var rand1=backgammon.rand1;var rand2=backgammon.rand2;backgammon.game=(function(){"use strict";var moveid=backgammon.sequence("move");var Move=function(die,source,target,hit){this.id=moveid();this.die=die;this.source=source;this.target=target;this.hit=hit;this.used=0;this.candidate=-999;};var gameid=backgammon.sequence("game");var Game=function(config){var self=this;self.id=gameid();self.wtm=true;self.rolls=[];self.moves=[];self.okmoves=[];self.movenum=0;self.pieces={white:new Array(24),black:new Array(24),offwhite:0,offblack:0,barwhite:0,barblack:0};self.toroll=null;self.board=config.ui||null;self.white=config.white||null;self.black=config.black||null;self.delay=config.delay||null;self.setup(config.position);if(self.white){self.white.init(self);} +;var backgammon=(function(context){"use strict";var main=context.backgammon={};main.sequence=function(type){var id=0;return function(){return type+(id++);}};main.rand1=function(max){return Math.floor(Math.random()*max);};main.rand2=function(min,max){return Math.floor(Math.random()*(max-min+1))+min;};main.defaults={orientation:true,delay:505,position:'2W////5B/3B///5W5B///3W/5W////2B W 00 0 00'};return main;})(this);;(function(backgammon){var rand1=backgammon.rand1;var rand2=backgammon.rand2;backgammon.game=(function(){"use strict";var moveid=backgammon.sequence("move");var Move=function(die,source,target,hit){this.id=moveid();this.die=die;this.source=source;this.target=target;this.hit=hit;this.used=0;this.candidate=-999;};var gameid=backgammon.sequence("game");var Game=function(config){var self=this;self.id=gameid();self.wtm=true;self.rolls=[];self.moves=[];self.okmoves=[];self.movenum=0;self.pieces={white:new Array(24),black:new Array(24),offwhite:0,offblack:0,barwhite:0,barblack:0};self.toroll=null;self.board=config.ui||null;self.white=config.white||null;self.black=config.black||null;self.delay=config.delay||null;self.setup(config.position);if(self.white){self.white.init(self);} if(self.black){self.black.init(self);}};Game.prototype.setup=function(positionstring){var self=this;var posarray=(positionstring||backgammon.defaults.position).toUpperCase().split(' ');var position=self.position=posarray[0];var c,n,p=23,i=0,l=position.length;var D='/'.charCodeAt(0),W='W'.charCodeAt(0),B='B'.charCodeAt(0);self.pieces.offwhite=0;self.pieces.offblack=0;self.pieces.barwhite=0;self.pieces.barblack=0;while(i-1){c=position.charCodeAt(i);n=position.charCodeAt(i+1);self.pieces.white[p]=0;self.pieces.black[p]=0;if(c===D){p--;}else if(n&&(c>=49||c<=57)){self.pieces.white[p]=n===W?c-48:0;self.pieces.black[p]=n===B?c-48:0;i++;p--;} i++;} self.wtm=(posarray[1]||'W')==='W';positionstring=posarray[2]||'00';self.pieces.barwhite=parseInt(positionstring.charAt(0),16);self.pieces.barblack=parseInt(positionstring.charAt(1),16);self.fullmove=parseInt(posarray[3]||'0');positionstring=posarray[4]||'00';if(positionstring!=='00'){self.toroll={die1:parseInt(positionstring.charAt(0)),die2:parseInt(positionstring.charAt(1))};}};Game.prototype.start=function(){var self=this;if(self.toroll){self.roll(self.toroll.die1,self.toroll.die2);self.toroll=null;}else{self.roll();}};Game.prototype.toString=function(){var self=this;var pos="";var whites=self.pieces.white;var blacks=self.pieces.black;var wtot=self.pieces.barwhite,btot=self.pieces.barblack;for(var point=23;point>=0;point--){if(whites[point])pos+=whites[point]+'W';else if(blacks[point])pos+=blacks[point]+'B';else pos+='/';wtot+=whites[point];btot+=blacks[point];} @@ -8,7 +8,7 @@ return true;};Game.prototype.move=function(okmove){var self=this;var player=self if(okmove.roll.die1===okmove.die)okmove.roll.used1++;else if(okmove.roll.die2===okmove.die)okmove.roll.used2++;self.moves.push(okmove);self.okmoves[self.movenum].moved=(self.okmoves[self.movenum].moved||0)+1;if(self.board)self.board.update(okmove);if(self.haswon()){console.log('WINNER!',self.id,player);self.winner=player;return null;}else if(self.okmoves[self.movenum].moved>(self.rolls[self.movenum].doubles?3:1)){self.nextmove();}else if(!self.canmove()){self.nextmove();} return okmove;};Game.prototype.roll=function(die1,die2){var self=this;var roll=self.rolls[self.movenum];if(!roll){die1=parseInt(die1);die2=parseInt(die2);var val1=(!isNaN(die1)&&die1>=1&&die1<=6)?die1:rand2(1,6);var val2=(!isNaN(die2)&&die2>=1&&die2<=6)?die2:rand2(1,6);var roll={die1:val1,die2:val2,used1:0,used2:0,doubles:val1===val2,color:self.wtm?'white':'black'} self.rolls[self.movenum]=roll;self.generatemoves();if(self.okmoves[self.movenum].length===0){self.nextmove();}} -if(self.board)self.board.onroll(roll);if(self.white)self.white.onroll(roll);if(self.black)self.black.onroll(roll);return roll;};Game.prototype.onbar=function(){var self=this;return((self.wtm&&self.pieces.barwhite>0)||(!self.wtm&&self.pieces.barblack>0));};Game.prototype.canclear=function(){var self=this;if(self.onbar())return false;var begin=self.wtm?5:0;var end=self.wtm?24:18;var pieces=self.wtm?self.pieces.white:self.pieces.black;for(var point=begin;point0)return false;if(self.wtm){for(var point=5;point>=0;point--){if(pieces[point]>0)return point;}}else{for(var point=19;point<=23;point++){if(pieces[point]>0)return point;}} +if(self.board)self.board.onroll(roll);if(self.white)self.white.onroll(roll);if(self.black)self.black.onroll(roll);return roll;};Game.prototype.onbar=function(){var self=this;return((self.wtm&&self.pieces.barwhite>0)||(!self.wtm&&self.pieces.barblack>0));};Game.prototype.canclear=function(){var self=this;if(self.onbar())return false;var begin=self.wtm?6:0;var end=self.wtm?24:18;var pieces=self.wtm?self.pieces.white:self.pieces.black;for(var point=begin;point0)return false;if(self.wtm){for(var point=5;point>=0;point--){if(pieces[point]>0)return point;}}else{for(var point=19;point<=23;point++){if(pieces[point]>0)return point;}} return self.wtm?0:23;};Game.prototype.generatemoves=function(){var self=this;var moves=[];var roll=self.rolls[self.movenum];var die1=roll.die1;var die2=roll.die2;var die0;var player=self.wtm?self.pieces.white:self.pieces.black;var waiter=self.wtm?self.pieces.black:self.pieces.white;var direction=self.wtm?-1:1;var hittarget0,hittarget1,hittarget2,hittarget3,hittarget4;var oktarget0,oktarget1,oktarget2,oktarget3,oktarget4;var target0,target1,target2,target3,target4;var possible,doublesource,barsource,bartarget,bardie;if(self.onbar()){barsource=self.wtm?24:-1;for(var d=1;d<3;d++){bardie=(d===1?die1:die2) bartarget=self.wtm?Math.abs(bardie-24):bardie-1;if(waiter[bartarget]<2){hittarget0=waiter[bartarget]===1?true:false;possible=new Move(bardie,barsource,bartarget,hittarget0);moves.push(possible);die0=(d===1?die2:die1) target0=self.wtm?bartarget-die0:bartarget+die0;if(waiter[target0]<2){hittarget0=waiter[target0]===1?true:false;possible=new Move(die0,bartarget,target0,hittarget0);moves.push(possible);}}} @@ -16,8 +16,11 @@ if(!moves.length){self.okmoves[self.movenum]=moves;return moves;}} var check=function(source,target,die){if((0<=target&&target<=23)&&(waiter[target]<2)){var hit=waiter[target]===1?true:false;var possible=new Move(die,source,target,hit);moves.push(possible);return true;} return false;} for(var point=0;point<24;point++){oktarget1=false;oktarget2=false;oktarget3=false;if(player[point]>0){if(!roll.doubles){target1=point+die1*direction;target2=point+die2*direction;target3=point+die1*direction+die2*direction;oktarget1=check(point,target1,die1);oktarget2=check(point,target2,die2);if(oktarget1)oktarget3=check(target1,target3,die2);if(oktarget2)oktarget4=check(target2,target3,die1);}else{doublesource=point;target4=point+die1*direction;for(var d=0;d<4;d++){if(check(doublesource,target4,die1)){doublesource+=die1*direction;target4+=die1*direction;}}}}} -var canclear=self.canclear();if(canclear!==false){var clearfrom=self.wtm?0:canclear;var clearto=self.wtm?canclear:23;for(var point=clearfrom;point<=clearto;point++){if(!roll.doubles){if(clearto-point<=roll.die1){var possible=new Move(die1,point,999,false);moves.push(possible);} -if(clearto-point<=roll.die2){var possible=new Move(die2,point,999,false);moves.push(possible);}}else{if(clearto-point<=roll.die1){for(var i=0;i<4;i++){var possible=new Move(die1,point,999,false);moves.push(possible);}}}}} +var canclear=self.canclear();if(canclear!==false){var greater=false;var maxdie=Math.max(roll.die1,roll.die2);var mindie=Math.min(roll.die1,roll.die2);if(self.wtm){var diepoint;var pieces=self.pieces.white;for(var point=canclear;point>=0;point--){diepoint=point+1;if(pieces[point]>0){if(!roll.doubles){if(diepoint===maxdie||(!greater&&diepoint0){if(!roll.doubles){if(diepoint===maxdie||(!greater&&diepoint24||target<0||(target>24&&!canclear))return false;var pieces=self.wtm?self.pieces.white:self.pieces.black;if(self.onbar()){if(self.wtm&&source!==24)return null;if(!self.wtm&&source!==-1)return null;}else if(!pieces[source]){return null;} var okmove=null;var okmoves=self.okmoves[self.movenum];var roll=self.rolls[self.movenum];var dist=Math.abs(target-source);var clear=self.wtm?source:24-source;var max=roll.doubles?3:1;var dist1=dist===roll.die1;var dist2=dist===roll.die2;var used1=roll.used1=0&&game.okmoves[game.movenum]))return false;var okmoves=game.okmoves[game.movenum].slice();var points=self.white?game.pieces.white:game.pieces.black;var possible=[];var clearstart=game.wtm?0:19;var clearend=game.wtm?5:23;var inclear=false;while(movenum=canclear))};possible=[];for(var p=0,poss,l=okmoves.length;p=clearstart&&poss.source<=clearend);if(game.point(poss.source)===1)poss.candidate+=10;if(game.point(poss.hit))poss.candidate+=8;if(game.point(poss.source)===2)poss.candidate-=5;if(game.point(poss.target)===1)poss.candidate+=12;if(game.point(poss.target)===0)poss.candidate-=7;if(inclear&&(game.point(poss.source)===2||game.point(poss.source)===3))poss.candidate-=15;if(poss.target===999)poss.candidate+=50;possible.push(poss);}} @@ -27,8 +30,7 @@ return points;};html+=' ';for(point=11;poin html+=' ';for(point=5;point>=0;point--){html+=''+(24-point)+'';} html+=' ';html+=' ';html+=makepoints(11,5,-1,'top');html+='
';html+=makepoints(5,-1,-1,'top');html+='';html+='
';html+='
';html+='';html+=' ';html+=makepoints(12,18,1,'bottom');html+='
';html+=makepoints(18,24,1,'bottom');html+='';html+='
';html+='
';html+='';html+=' ';for(point=12;point<18;point++){html+=''+(24-point)+'';} html+=' ';for(point=18;point<24;point++){html+=''+(24-point)+'';} -html+=' ';html+='' -self.container.html(html);self.container.find(".backgammon-point").each(function(){var point=$(this);self.points[parseInt(point.attr("data-point"))]=point;});self.container.find(".backgammon-checkers").each(function(){var slot=$(this);self.checkerslots[parseInt(slot.attr("data-point"))]=slot;});self.dice[0]=self.container.find(".backgammon-die0");self.dice[1]=self.container.find(".backgammon-die1");self.dice[2]=self.container.find(".backgammon-die2");self.dice[3]=self.container.find(".backgammon-die3");self.barwhite=self.container.find(".backgammon-bar-white");self.barblack=self.container.find(".backgammon-bar-black");self.barwhiteslot=self.barwhite.find(".backgammon-checkers");self.barblackslot=self.barblack.find(".backgammon-checkers");for(var n=0;n0){var barred=self.points[mymove.target].find('.backgammon-checker.backgammon-black');barred.remove().appendTo(self.barblack.find('.backgammon-checkers'));} var piece=self.container.find(".backgammon-checker[data-dirty='1']");if(!piece.length){switch(mymove.source){case-1:piece=self.barblackslot.children(":first-child");break;case 24:piece=self.barwhiteslot.children(":first-child");break;default:piece=self.checkerslots[mymove.source].children(":last-child");break;}} if(piece.length)self.place(piece,mymove.target);};Board.prototype.move=function(source,target){var self=this;var okmove=self.game.okmove(source,target);if(!okmove)return'snapback' -return self.game.move(okmove);};Board.prototype.roll=function(){var self=this;self.game.roll();};Board.prototype.onroll=function(roll){var self=this;if(roll.color==='white'){self.dice[0].fadeIn(roll.die1);self.dice[1].fadeIn(roll.die2);self.dice[2].hide();self.dice[3].hide();}else{self.dice[0].hide();self.dice[1].hide();self.dice[2].fadeIn(roll.die1);self.dice[3].fadeIn(roll.die2);}};Board.prototype.onpoint=function(piece){var self=this;var piecex=parseInt(piece.offset().left+piece.width()/2);var piecey=parseInt(piece.offset().top+piece.height()/2);var $point=null;self.container.find(".backgammon-point").each(function(){var point=$(this);var pointtop=parseInt(point.offset().top);var pointleft=parseInt(point.offset().left);var pointright=parseInt(pointleft+point.outerWidth());var pointbottom=parseInt(pointtop+point.outerHeight());if(pieceypointtop&&piecexpointleft){$point=point;return false;}});return $point;};var api=function(board,width,config){return new Board(board,width,config||{});};return api;})();})(backgammon);(function(){var getBoardWidth=function(total){var ratio=1.2189;var cols=4;while(total%cols>0)cols--;var rows=total/cols;var x=window.innerWidth;var y=window.innerHeight;while(x/y>ratio)x--;var w=x;var h=w/ratio;while(w*cols>x)w--;return w-10;} -backgammon.new0PGame=function(id,total,delay,position){var width=getBoardWidth(total);var whiteai=backgammon.brain({color:'white',level:0});var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,white:whiteai,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.new1PGame=function(delay,position){var id=nextid();var width=parseInt(window.innerWidth-10);var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.tournament=function(total,delay,position){total=total||1;var boards={};var nextid=backgammon.sequence("board");for(var i=0,id;ipointtop&&piecexpointleft){$point=point;return false;}});return $point;};var api=function(board,width,config){return new Board(board,width,config||{});};return api;})();})(backgammon);(function(backgammon){"use strict";var getBoardWidth=function(total){var ratio=1.2189;var cols=4;while(total%cols>0)cols--;var rows=total/cols;var x=window.innerWidth;var y=window.innerHeight;while(x/y>ratio)x--;var w=x;var h=w/ratio;while(w*cols>x)w--;return w-20;};backgammon.new0PGame=function(id,total,delay,position){var width=getBoardWidth(total);var whiteai=backgammon.brain({color:'white',level:0});var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,white:whiteai,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.new1PGame=function(delay,position){var id=nextid();var width=parseInt(window.innerWidth-10);var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.tournament=function(total,delay,position){total=total||1;var boards={};var nextid=backgammon.sequence("board");for(var i=0,id;i=0;point--){html+=''+(24-point)+'';} html+=' ';html+=' ';html+=makepoints(11,5,-1,'top');html+='
';html+=makepoints(5,-1,-1,'top');html+='';html+='
';html+='
';html+='';html+=' ';html+=makepoints(12,18,1,'bottom');html+='
';html+=makepoints(18,24,1,'bottom');html+='';html+='
';html+='
';html+='';html+=' ';for(point=12;point<18;point++){html+=''+(24-point)+'';} html+=' ';for(point=18;point<24;point++){html+=''+(24-point)+'';} -html+=' ';html+='
' -self.container.html(html);self.container.find(".backgammon-point").each(function(){var point=$(this);self.points[parseInt(point.attr("data-point"))]=point;});self.container.find(".backgammon-checkers").each(function(){var slot=$(this);self.checkerslots[parseInt(slot.attr("data-point"))]=slot;});self.dice[0]=self.container.find(".backgammon-die0");self.dice[1]=self.container.find(".backgammon-die1");self.dice[2]=self.container.find(".backgammon-die2");self.dice[3]=self.container.find(".backgammon-die3");self.barwhite=self.container.find(".backgammon-bar-white");self.barblack=self.container.find(".backgammon-bar-black");self.barwhiteslot=self.barwhite.find(".backgammon-checkers");self.barblackslot=self.barblack.find(".backgammon-checkers");for(var n=0;n0){var barred=self.points[mymove.target].find('.backgammon-checker.backgammon-black');barred.remove().appendTo(self.barblack.find('.backgammon-checkers'));} var piece=self.container.find(".backgammon-checker[data-dirty='1']");if(!piece.length){switch(mymove.source){case-1:piece=self.barblackslot.children(":first-child");break;case 24:piece=self.barwhiteslot.children(":first-child");break;default:piece=self.checkerslots[mymove.source].children(":last-child");break;}} if(piece.length)self.place(piece,mymove.target);};Board.prototype.move=function(source,target){var self=this;var okmove=self.game.okmove(source,target);if(!okmove)return'snapback' -return self.game.move(okmove);};Board.prototype.roll=function(){var self=this;self.game.roll();};Board.prototype.onroll=function(roll){var self=this;if(roll.color==='white'){self.dice[0].fadeIn(roll.die1);self.dice[1].fadeIn(roll.die2);self.dice[2].hide();self.dice[3].hide();}else{self.dice[0].hide();self.dice[1].hide();self.dice[2].fadeIn(roll.die1);self.dice[3].fadeIn(roll.die2);}};Board.prototype.onpoint=function(piece){var self=this;var piecex=parseInt(piece.offset().left+piece.width()/2);var piecey=parseInt(piece.offset().top+piece.height()/2);var $point=null;self.container.find(".backgammon-point").each(function(){var point=$(this);var pointtop=parseInt(point.offset().top);var pointleft=parseInt(point.offset().left);var pointright=parseInt(pointleft+point.outerWidth());var pointbottom=parseInt(pointtop+point.outerHeight());if(pieceypointtop&&piecexpointleft){$point=point;return false;}});return $point;};var api=function(board,width,config){return new Board(board,width,config||{});};return api;})();})(backgammon);(function(){var getBoardWidth=function(total){var ratio=1.2189;var cols=4;while(total%cols>0)cols--;var rows=total/cols;var x=window.innerWidth;var y=window.innerHeight;while(x/y>ratio)x--;var w=x;var h=w/ratio;while(w*cols>x)w--;return w-10;} -backgammon.new0PGame=function(id,total,delay,position){var width=getBoardWidth(total);var whiteai=backgammon.brain({color:'white',level:0});var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,white:whiteai,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.new1PGame=function(delay,position){var id=nextid();var width=parseInt(window.innerWidth-10);var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.tournament=function(total,delay,position){total=total||1;var boards={};var nextid=backgammon.sequence("board");for(var i=0,id;ipointtop&&piecexpointleft){$point=point;return false;}});return $point;};var api=function(board,width,config){return new Board(board,width,config||{});};return api;})();})(backgammon);(function(backgammon){"use strict";var getBoardWidth=function(total){var ratio=1.2189;var cols=4;while(total%cols>0)cols--;var rows=total/cols;var x=window.innerWidth;var y=window.innerHeight;while(x/y>ratio)x--;var w=x;var h=w/ratio;while(w*cols>x)w--;return w-20;};backgammon.new0PGame=function(id,total,delay,position){var width=getBoardWidth(total);var whiteai=backgammon.brain({color:'white',level:0});var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,white:whiteai,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.new1PGame=function(delay,position){var id=nextid();var width=parseInt(window.innerWidth-10);var blackai=backgammon.brain({color:'black',level:1});var boardui=$("
");if(isNaN(delay))delay=gammon.defaults.delay;var config={delay:delay,black:blackai};if(position)config.position=position;$("#boards").append(boardui);return backgammon.board(id,width,config);};backgammon.tournament=function(total,delay,position){total=total||1;var boards={};var nextid=backgammon.sequence("board");for(var i=0,id;i(self.rolls[self.movenum].doubles?3:1)){self.nextmove();}else if(!self.canmove()){self.nextmove();} return okmove;};Game.prototype.roll=function(die1,die2){var self=this;var roll=self.rolls[self.movenum];if(!roll){die1=parseInt(die1);die2=parseInt(die2);var val1=(!isNaN(die1)&&die1>=1&&die1<=6)?die1:rand2(1,6);var val2=(!isNaN(die2)&&die2>=1&&die2<=6)?die2:rand2(1,6);var roll={die1:val1,die2:val2,used1:0,used2:0,doubles:val1===val2,color:self.wtm?'white':'black'} self.rolls[self.movenum]=roll;self.generatemoves();if(self.okmoves[self.movenum].length===0){self.nextmove();}} -if(self.board)self.board.onroll(roll);if(self.white)self.white.onroll(roll);if(self.black)self.black.onroll(roll);return roll;};Game.prototype.onbar=function(){var self=this;return((self.wtm&&self.pieces.barwhite>0)||(!self.wtm&&self.pieces.barblack>0));};Game.prototype.canclear=function(){var self=this;if(self.onbar())return false;var begin=self.wtm?5:0;var end=self.wtm?24:18;var pieces=self.wtm?self.pieces.white:self.pieces.black;for(var point=begin;point0)return false;if(self.wtm){for(var point=5;point>=0;point--){if(pieces[point]>0)return point;}}else{for(var point=19;point<=23;point++){if(pieces[point]>0)return point;}} +if(self.board)self.board.onroll(roll);if(self.white)self.white.onroll(roll);if(self.black)self.black.onroll(roll);return roll;};Game.prototype.onbar=function(){var self=this;return((self.wtm&&self.pieces.barwhite>0)||(!self.wtm&&self.pieces.barblack>0));};Game.prototype.canclear=function(){var self=this;if(self.onbar())return false;var begin=self.wtm?6:0;var end=self.wtm?24:18;var pieces=self.wtm?self.pieces.white:self.pieces.black;for(var point=begin;point0)return false;if(self.wtm){for(var point=5;point>=0;point--){if(pieces[point]>0)return point;}}else{for(var point=19;point<=23;point++){if(pieces[point]>0)return point;}} return self.wtm?0:23;};Game.prototype.generatemoves=function(){var self=this;var moves=[];var roll=self.rolls[self.movenum];var die1=roll.die1;var die2=roll.die2;var die0;var player=self.wtm?self.pieces.white:self.pieces.black;var waiter=self.wtm?self.pieces.black:self.pieces.white;var direction=self.wtm?-1:1;var hittarget0,hittarget1,hittarget2,hittarget3,hittarget4;var oktarget0,oktarget1,oktarget2,oktarget3,oktarget4;var target0,target1,target2,target3,target4;var possible,doublesource,barsource,bartarget,bardie;if(self.onbar()){barsource=self.wtm?24:-1;for(var d=1;d<3;d++){bardie=(d===1?die1:die2) bartarget=self.wtm?Math.abs(bardie-24):bardie-1;if(waiter[bartarget]<2){hittarget0=waiter[bartarget]===1?true:false;possible=new Move(bardie,barsource,bartarget,hittarget0);moves.push(possible);die0=(d===1?die2:die1) target0=self.wtm?bartarget-die0:bartarget+die0;if(waiter[target0]<2){hittarget0=waiter[target0]===1?true:false;possible=new Move(die0,bartarget,target0,hittarget0);moves.push(possible);}}} @@ -16,8 +16,11 @@ if(!moves.length){self.okmoves[self.movenum]=moves;return moves;}} var check=function(source,target,die){if((0<=target&&target<=23)&&(waiter[target]<2)){var hit=waiter[target]===1?true:false;var possible=new Move(die,source,target,hit);moves.push(possible);return true;} return false;} for(var point=0;point<24;point++){oktarget1=false;oktarget2=false;oktarget3=false;if(player[point]>0){if(!roll.doubles){target1=point+die1*direction;target2=point+die2*direction;target3=point+die1*direction+die2*direction;oktarget1=check(point,target1,die1);oktarget2=check(point,target2,die2);if(oktarget1)oktarget3=check(target1,target3,die2);if(oktarget2)oktarget4=check(target2,target3,die1);}else{doublesource=point;target4=point+die1*direction;for(var d=0;d<4;d++){if(check(doublesource,target4,die1)){doublesource+=die1*direction;target4+=die1*direction;}}}}} -var canclear=self.canclear();if(canclear!==false){var clearfrom=self.wtm?0:canclear;var clearto=self.wtm?canclear:23;for(var point=clearfrom;point<=clearto;point++){if(!roll.doubles){if(clearto-point<=roll.die1){var possible=new Move(die1,point,999,false);moves.push(possible);} -if(clearto-point<=roll.die2){var possible=new Move(die2,point,999,false);moves.push(possible);}}else{if(clearto-point<=roll.die1){for(var i=0;i<4;i++){var possible=new Move(die1,point,999,false);moves.push(possible);}}}}} +var canclear=self.canclear();if(canclear!==false){var greater=false;var maxdie=Math.max(roll.die1,roll.die2);var mindie=Math.min(roll.die1,roll.die2);if(self.wtm){var diepoint;var pieces=self.pieces.white;for(var point=canclear;point>=0;point--){diepoint=point+1;if(pieces[point]>0){if(!roll.doubles){if(diepoint===maxdie||(!greater&&diepoint0){if(!roll.doubles){if(diepoint===maxdie||(!greater&&diepoint24||target<0||(target>24&&!canclear))return false;var pieces=self.wtm?self.pieces.white:self.pieces.black;if(self.onbar()){if(self.wtm&&source!==24)return null;if(!self.wtm&&source!==-1)return null;}else if(!pieces[source]){return null;} var okmove=null;var okmoves=self.okmoves[self.movenum];var roll=self.rolls[self.movenum];var dist=Math.abs(target-source);var clear=self.wtm?source:24-source;var max=roll.doubles?3:1;var dist1=dist===roll.die1;var dist2=dist===roll.die2;var used1=roll.used1 - + + -
- + @@ -25,11 +25,7 @@ backgammon.boards = backgammon.tournament(24,505); //Google Analytics - var _gaq=[['_setAccount','UA-22107593-8'],['_trackPageview']]; - (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0]; - g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js'; - s.parentNode.insertBefore(g,s)}(document,'script')); - + var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-22107593-1']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); diff --git a/src/board.js b/src/board.js index f042dc3..11685a8 100644 --- a/src/board.js +++ b/src/board.js @@ -200,7 +200,7 @@ for(point=18;point<24;point++) { html += '' + (24-point) + ''; } html += ' '; - html += '
' + html += '
'; //Create the board inside the container self.container.html(html); @@ -409,10 +409,11 @@ })(backgammon); -(function(){ +(function(backgammon){ + "use strict"; var getBoardWidth = function(total) { - var ratio = 1.2189; + var ratio = 1.2189; //Magic number - hardcoded w/h ratio of a backgammon board var cols = 4; while (total%cols>0) cols--; var rows = total/cols; @@ -422,9 +423,10 @@ var w = x; var h = w/ratio; while(w*cols>x) w--; - return w-10; - } - + return w-20; + }; + + //Zero player game backgammon.new0PGame = function(id,total,delay,position) { var width = getBoardWidth(total); var whiteai = backgammon.brain({color:'white',level:0}); @@ -438,6 +440,7 @@ }; + //One player game backgammon.new1PGame = function(delay,position) { var id = nextid(); var width=parseInt(window.innerWidth-10); diff --git a/src/game.js b/src/game.js index b53acf9..18e9102 100644 --- a/src/game.js +++ b/src/game.js @@ -326,11 +326,10 @@ Game.prototype.canclear = function() { var self = this; if(self.onbar()) return false; - var begin = self.wtm?5:0; + var begin = self.wtm?6:0; var end = self.wtm?24:18; var pieces = self.wtm?self.pieces.white:self.pieces.black; for(var point=begin;point0) return false; - //TODO - find maximum point if(self.wtm) { for(var point=5;point>=0;point--) {if(pieces[point]>0) return point;} } else { @@ -435,26 +434,61 @@ //Can clear checkers from the board var canclear = self.canclear(); if (canclear!==false) { - var clearfrom = self.wtm?0:canclear; - var clearto = self.wtm?canclear:23; - for(var point = clearfrom;point<=clearto;point++) { - if (!roll.doubles) { - if (clearto-point<=roll.die1) { - var possible = new Move(die1,point,999,false); - moves.push(possible); - } - if (clearto-point<=roll.die2) { - var possible = new Move(die2,point,999,false); - moves.push(possible); + var greater = false; + var maxdie = Math.max(roll.die1,roll.die2); + var mindie = Math.min(roll.die1,roll.die2); + if(self.wtm) { + var diepoint; + var pieces = self.pieces.white; + for(var point = canclear;point>=0;point--) { + diepoint = point+1; + if (pieces[point]>0) { + if (!roll.doubles) { + if (diepoint === maxdie || (!greater && diepoint0) { + if (!roll.doubles) { + if (diepoint === maxdie || (!greater && diepoint