Browse Source

Implement the threefold repetition rule

Chess.Position stores an array of past Zobrist hash keys.
isThreefoldRepetitionRuleDraw can then count the number of times the
current position has repeated.
master
Kaj Björklund 11 years ago
parent
commit
bd99862a1e
  1. 45
      chess.min.js
  2. 21
      src/position.js

45
chess.min.js

@ -2,27 +2,28 @@
function ia(a,b){return!u(a,b)}function y(a,b){b>>>=0;32>b?a.a=(a.a|1<<b)>>>0:a.b=(a.b|1<<b-32)>>>0;return a}function ja(a,b){b>>>=0;32>b?a.a=(a.a&~(1<<b))>>>0:a.b=(a.b&~(1<<b-32))>>>0}function A(a,b){a.a=(a.a&b.a)>>>0;a.b=(a.b&b.b)>>>0;return a}function B(a,b){a.a=(a.a&~b.a)>>>0;a.b=(a.b&~b.b)>>>0;return a}function C(a,b){a.a=(a.a|b.a)>>>0;a.b=(a.b|b.b)>>>0;return a}function ka(a,b){a.a=(a.a^b.a)>>>0;a.b=(a.b^b.b)>>>0}function la(a){a.a=~a.a>>>0;a.b=~a.b>>>0;return a}
function D(a,b){b>>>=0;31<b?(a.b=a.a<<b-32>>>0,a.a=0):0<b&&(a.b=(a.b<<b|a.a>>>32-b)>>>0,a.a=a.a<<b>>>0);return a}function E(a,b){b>>>=0;31<b?(a.a=a.b>>>b-32,a.b=0):0<b&&(a.a=(a.a>>>b|a.b<<32-b)>>>0,a.b>>>=b);return a}function F(a,b){63<b||-63>b?a.a=a.b=0:0<b?D(a,b):0>b&&E(a,-b);return a}function ma(a,b){return a.a===b.a&&a.b===b.b}function G(a){return I(a.a,a.b)}function I(a,b){return new da(a,b)}function J(a){return y(I(0,0),a)}
function na(){var a=oa;return F(A(I(270549120,16909320),F(I(4294967295,4294967295),8*a)),a)}function pa(){var a=qa;return F(A(I(134480385,2151686160),F(I(4294967295,4294967295),8*-a)),a)}function ra(){var a=y(I(0,0),sa),b=B(E(G(a),1),K[7]),c=B(B(E(G(a),2),K[7]),K[6]),d=B(D(G(a),1),K[0]),a=B(B(D(G(a),2),K[0]),K[1]),c=C(c,a),b=C(b,d);return C(C(C(D(G(c),8),E(c,8)),D(G(b),16)),E(b,16))}
function ta(){var a=y(I(0,0),ua),b=C(B(E(G(a),1),K[7]),B(D(G(a),1),K[0])),c=E(C(G(a),b),8),a=D(C(G(a),b),8);return C(C(b,c),a)}for(var va=I(4294967295,4294967295),wa=I(1437226410,1437226410),xa=I(2857740885,2857740885),ya=[],za=0;8>za;++za)ya.push(D(I(16843009,16843009),za));for(var K=ya,L=[],Aa=0;8>Aa;++Aa)L.push(D(I(255,0),8*Aa));for(var Ba=[],oa=-7;8>oa;++oa)Ba.push(na());for(var Ca=[],qa=-7;8>qa;++qa)Ca.push(pa());for(var Da=[],sa=0;64>sa;++sa)Da.push(ra());for(var Ea=[],ua=0;64>ua;++ua)Ea.push(ta());function Fa(){this.a=this.b=0}for(var Ga=[],Ha=0;1586>Ha;++Ha)Ga.push(1+4294967295*Math.random()>>>0);function M(a,b){a.b=(a.b^Ga[b])>>>0;a.a=(a.a^Ga[b+1])>>>0}function N(a,b){0<=b&&M(a,1570+(b&7))};function Ia(a,b,c,d,g){this.a=b&63|(a&63)<<6|(c&15)<<12|(d&7)<<16|((g|0)&7)<<19}function O(a){return a.a>>>6&63}function P(a){return a.a>>>12&15}function Q(a){return a.a>>>16&7}function Ja(a){return 2===P(a)||3===P(a)}function Ka(a){return 5!==P(a)?a.a&63:(a.a&63)+(O(a)<(a.a&63)?-8:8)}function La(a){return!Ja(a)?" NBRQK".charAt(Q(a))+q(O(a))+(P(a)&4?"x":"-")+q(a.a&63)+(5===P(a)?"e.p.":"")+(P(a)&8?" NBRQK".charAt(P(a)&8?1+(P(a)&3):0):""):"0-0"+(3===P(a)?"-0":"")};function Ma(){this.c=new Fa;this.a=[C(G(L[1]),L[6]),C(C(C(J(1),J(6)),J(57)),J(62)),C(C(C(J(2),J(5)),J(58)),J(61)),C(C(C(J(0),J(7)),J(56)),J(63)),C(J(3),J(59)),C(J(4),J(60)),C(G(L[0]),L[1]),C(G(L[6]),L[7])];this.f=[];this.b=0;this.e=15;this.d=-1;this.h=0;this.g=[];this.i=[];for(var a=this.f.length=0;64>a;++a){var b;a:{for(b=0;5>=b;++b)if(!u(this.a[b],a))break a;b=j}this.f.push(b)}this.c=new Fa;this.b&&M(this.c,0);for(a=0;1>=a;++a)for(b=0;5>=b;++b)for(var c=this.c,d=b,g=a,e=R(this,b,a),e=G(e);!t(e);){var h=
s(e);M(c,2+d+6*g+12*h)}M(this.c,1538+this.e);N(this.c,this.d)}var S=[7,63,0,56],Na=[la(D(I(16843009,16843009),7)),va,la(D(I(16843009,16843009),0))];
function T(a,b,c){function d(a,b,c){for(;!t(b);){var d=s(b);u(ib,d)&&h.push(new Ia(a,d,!u(v,d)?4:0,c,H.f[d]))}}function g(a,b,c){e(G(a),b,c?15:11);e(G(a),b,c?14:10);e(G(a),b,c?13:9);e(G(a),b,c?12:8)}function e(a,b,c){for(;!t(a);){var d=s(a);h.push(new Ia(d-b,d,c,0,H.f[d]))}}c=!!c;var h=[],k=a.b,v=a.a[6+(k^1)],l=U(a),H=a,n=1-2*k,x=8*n,w=R(a,0,k),p=L[k?0:7];if(!c){var z=B(B(F(A(G(w),L[k?6:1]),2*x),l),F(G(l),x));e(z,2*x,1);z=B(F(G(w),x),l);e(B(G(z),p),x,0);g(A(G(z),p),x,m)}var Ra=K[k?7:0],z=x-n,Y=A(F(B(G(w),
Ra),z),v);e(B(G(Y),p),z,4);g(A(G(Y),p),z,f);var Y=K[k?0:7],x=x+n,Sa=A(F(B(G(w),Y),x),v);e(B(G(Sa),p),x,4);g(A(G(Sa),p),x,f);0<=a.d&&(p=F(B(A(J(a.d+n),w),Ra),z),e(p,z,5),n=F(B(A(J(a.d-n),w),Y),x),e(n,x,5));for(var ib=a.a[6+k],n=c?v:va,w=G(R(a,1,k));!t(w);)p=s(w),d(p,A(G(Da[p]),n),1);for(w=G(R(a,4,k));!t(w);)p=s(w),d(p,A(C(Oa(J(p),l),Pa(J(p),l)),n),4);for(w=G(R(a,2,k));!t(w);)p=s(w),d(p,A(Oa(J(p),l),n),2);for(w=G(R(a,3,k));!t(w);)p=s(w),d(p,A(Pa(J(p),l),n),3);l=ha(R(a,5,k));d(l,A(G(Ea[l]),n),5);c||
(Qa(a,k,f)&&h.push(new Ia(l,l+2,2,5,j)),Qa(a,k,m)&&h.push(new Ia(l,l-2,3,5,j)));c=h;return b?c:c.filter(Ma.prototype.j,a)}function R(a,b,c){return A(G(a.a[b]),a.a[6+c])}function U(a){return C(G(a.a[6]),a.a[7])}function V(a){return Ta(a,a.b^1,ha(R(a,5,a.b)))}function Ua(a,b){var c=0===a,d=F(B(G(b),K[0]),c?7:-9),c=F(B(G(b),K[7]),c?9:-7);return C(d,c)}function W(a,b,c,d){var g=I(0,0);c=8*c+d;d=Na[1+d];for(F(a,c);!t(A(a,d));F(B(a,b),c))C(g,a);return g}
function Oa(a,b){return C(C(C(W(G(a),b,1,1),W(G(a),b,1,-1)),W(G(a),b,-1,1)),W(G(a),b,-1,-1))}function Pa(a,b){return C(C(C(W(G(a),b,0,1),W(G(a),b,0,-1)),W(G(a),b,1,0)),W(G(a),b,-1,0))}function Ta(a,b,c){var d=R(a,0,b);if(ia(Ua(b,d),c))return f;d=R(a,1,b);if(!t(A(G(Da[c]),d)))return f;d=R(a,5,b);if(!t(A(G(Ea[c]),d)))return f;var d=U(a),g=R(a,4,b),e=C(G(R(a,2,b)),g);if(ia(Oa(e,d),c))return f;a=C(G(R(a,3,b)),g);return ia(Pa(a,d),c)?f:m}
function X(a,b,c){M(a.c,1538+a.e);a.e&=~(1<<b+(c?0:2));M(a.c,1538+a.e)}function Qa(a,b,c){if(0===(a.e&1<<b+(c?0:2)))return m;var d=c?1:-1,g=0===b?4:60,e=U(a);if(!(d=!u(e,g+d)||!u(e,g+2*d)||!c&&!u(e,g+3*d)))d=b^1,c=c?1:-1,b=0===b?4:60,d=!(!Ta(a,d,b)&&!Ta(a,d,b+c)&&!Ta(a,d,b+2*c));return d?m:f}function Va(a){if(!t(a.a[0])||!t(a.a[3])||!t(a.a[4]))return m;if(4>r(a.a[6])+r(a.a[7]))return f;if(!t(a.a[1]))return m;a=a.a[2];return ma(A(G(a),wa),a)||ma(A(G(a),xa),a)?f:m}
function Wa(a,b,c,d,g){var e=C(J(d),J(g));ka(a.a[b],e);ka(a.a[6+c],e);a.f[d]=j;a.f[g]=b;M(a.c,2+b+6*c+12*d);M(a.c,2+b+6*c+12*g)}function Xa(a,b,c,d,g){ja(a.a[b],g);y(a.a[c],g);a.f[g]=c;M(a.c,2+b+6*d+12*g);M(a.c,2+c+6*d+12*g)}function Ya(a,b){if(P(b)&4){var c=b.a>>>19&7,d=a.b^1,g=Ka(b);ja(a.a[c],g);ja(a.a[6+d],g);a.f[g]=j;M(a.c,2+c+6*d+12*g)}Ja(b)&&(c=a.b,d=2===P(b),g=S[c+(d?0:2)],Wa(a,3,c,g,g+(d?-2:3)));Wa(a,Q(b),a.b,O(b),b.a&63);P(b)&8&&Xa(a,0,P(b)&8?1+(P(b)&3):0,a.b,b.a&63)}
function Za(a,b){P(b)&8&&Xa(a,P(b)&8?1+(P(b)&3):0,0,a.b,b.a&63);Wa(a,Q(b),a.b,b.a&63,O(b));if(Ja(b)){var c=a.b,d=2===P(b),g=S[c+(d?0:2)];Wa(a,3,c,g+(d?-2:3),g)}P(b)&4&&(c=b.a>>>19&7,d=a.b^1,g=Ka(b),y(a.a[c],g),y(a.a[6+d],g),a.f[g]=c,M(a.c,2+c+6*d+12*g))}Ma.prototype.j=function(a){Ya(this,a);var b=V(this);Za(this,a);return!b};
function Z(a,b){Ya(a,b);if(V(a))return Za(a,b),m;a.g.push(b);a.i.push(a.d);a.i.push(a.e);a.i.push(a.h);N(a.c,a.d);a.d=1===P(b)?b.a&63:-1;N(a.c,a.d);var c=a.b;5===Q(b)?(X(a,c,f),X(a,c,m)):3===Q(b)&&(O(b)===S[c+0]?X(a,c,f):O(b)===S[c+2]&&X(a,c,m));c^=1;3===(b.a>>>19&7)&&(Ka(b)===S[c+0]?X(a,c,f):Ka(b)===S[c+2]&&X(a,c,m));P(b)&4||0===Q(b)?a.h=0:++a.h;a.b=c;M(a.c,0);return f}
function $a(a){if(a.g.length){var b=a.g.pop();a.b^=1;M(a.c,0);Za(a,b);a.i.pop();M(a.c,1538+a.e);a.e=a.i.pop();M(a.c,1538+a.e);N(a.c,a.d);a.d=a.i.pop();N(a.c,a.d)}};var ab=[100,300,300,500,900,2E4],bb=[[0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50,10,10,20,30,30,20,10,10,5,5,10,25,25,10,5,5,0,0,0,20,20,0,0,0,5,-5,-10,0,0,-10,-5,5,5,10,10,-20,-20,10,10,5,0,0,0,0,0,0,0,0],[-50,-40,-30,-30,-30,-30,-40,-50,-40,-20,0,0,0,0,-20,-40,-30,0,10,15,15,10,0,-30,-30,5,15,20,20,15,5,-30,-30,0,15,20,20,15,0,-30,-30,5,10,15,15,10,5,-30,-40,-20,0,5,5,0,-20,-40,-50,-40,-30,-30,-30,-30,-40,-50],[-20,-10,-10,-10,-10,-10,-10,-20,-10,0,0,0,0,0,0,-10,-10,0,5,10,10,5,0,-10,-10,5,5,10,10,
function ta(){var a=y(I(0,0),ua),b=C(B(E(G(a),1),K[7]),B(D(G(a),1),K[0])),c=E(C(G(a),b),8),a=D(C(G(a),b),8);return C(C(b,c),a)}for(var va=I(4294967295,4294967295),wa=I(1437226410,1437226410),xa=I(2857740885,2857740885),ya=[],za=0;8>za;++za)ya.push(D(I(16843009,16843009),za));for(var K=ya,L=[],Aa=0;8>Aa;++Aa)L.push(D(I(255,0),8*Aa));for(var Ba=[],oa=-7;8>oa;++oa)Ba.push(na());for(var Ca=[],qa=-7;8>qa;++qa)Ca.push(pa());for(var Da=[],sa=0;64>sa;++sa)Da.push(ra());for(var Ea=[],ua=0;64>ua;++ua)Ea.push(ta());function Fa(a,b){this.b=a>>>0;this.a=b>>>0}for(var Ga=[],Ha=0;1586>Ha;++Ha)Ga.push(1+4294967295*Math.random()>>>0);function M(a,b){a.b=(a.b^Ga[b])>>>0;a.a=(a.a^Ga[b+1])>>>0}function N(a,b){0<=b&&M(a,1570+(b&7))};function Ia(a,b,c,d,g){this.a=b&63|(a&63)<<6|(c&15)<<12|(d&7)<<16|((g|0)&7)<<19}function O(a){return a.a>>>6&63}function P(a){return a.a>>>12&15}function Q(a){return a.a>>>16&7}function Ja(a){return 2===P(a)||3===P(a)}function Ka(a){return 5!==P(a)?a.a&63:(a.a&63)+(O(a)<(a.a&63)?-8:8)}function La(a){return!Ja(a)?" NBRQK".charAt(Q(a))+q(O(a))+(P(a)&4?"x":"-")+q(a.a&63)+(5===P(a)?"e.p.":"")+(P(a)&8?" NBRQK".charAt(P(a)&8?1+(P(a)&3):0):""):"0-0"+(3===P(a)?"-0":"")};function Ma(){this.b=new Fa(0,0);this.a=[C(G(L[1]),L[6]),C(C(C(J(1),J(6)),J(57)),J(62)),C(C(C(J(2),J(5)),J(58)),J(61)),C(C(C(J(0),J(7)),J(56)),J(63)),C(J(3),J(59)),C(J(4),J(60)),C(G(L[0]),L[1]),C(G(L[6]),L[7])];this.f=[];this.c=0;this.e=15;this.d=-1;this.h=0;this.g=[];this.i=[];for(var a=this.f.length=0;64>a;++a){var b;a:{for(b=0;5>=b;++b)if(!u(this.a[b],a))break a;b=j}this.f.push(b)}this.b=new Fa(0,0);this.c&&M(this.b,0);for(a=0;1>=a;++a)for(b=0;5>=b;++b)for(var c=this.b,d=b,g=a,e=R(this,b,a),e=
G(e);!t(e);){var h=s(e);M(c,2+d+6*g+12*h)}M(this.b,1538+this.e);N(this.b,this.d);this.j=[]}var S=[7,63,0,56],Na=[la(D(I(16843009,16843009),7)),va,la(D(I(16843009,16843009),0))];
function T(a,b,c){function d(a,b,c){for(;!t(b);){var d=s(b);u(jb,d)&&h.push(new Ia(a,d,!u(v,d)?4:0,c,H.f[d]))}}function g(a,b,c){e(G(a),b,c?15:11);e(G(a),b,c?14:10);e(G(a),b,c?13:9);e(G(a),b,c?12:8)}function e(a,b,c){for(;!t(a);){var d=s(a);h.push(new Ia(d-b,d,c,0,H.f[d]))}}c=!!c;var h=[],k=a.c,v=a.a[6+(k^1)],l=U(a),H=a,n=1-2*k,x=8*n,w=R(a,0,k),p=L[k?0:7];if(!c){var z=B(B(F(A(G(w),L[k?6:1]),2*x),l),F(G(l),x));e(z,2*x,1);z=B(F(G(w),x),l);e(B(G(z),p),x,0);g(A(G(z),p),x,m)}var Sa=K[k?7:0],z=x-n,Y=A(F(B(G(w),
Sa),z),v);e(B(G(Y),p),z,4);g(A(G(Y),p),z,f);var Y=K[k?0:7],x=x+n,Ta=A(F(B(G(w),Y),x),v);e(B(G(Ta),p),x,4);g(A(G(Ta),p),x,f);0<=a.d&&(p=F(B(A(J(a.d+n),w),Sa),z),e(p,z,5),n=F(B(A(J(a.d-n),w),Y),x),e(n,x,5));for(var jb=a.a[6+k],n=c?v:va,w=G(R(a,1,k));!t(w);)p=s(w),d(p,A(G(Da[p]),n),1);for(w=G(R(a,4,k));!t(w);)p=s(w),d(p,A(C(Oa(J(p),l),Pa(J(p),l)),n),4);for(w=G(R(a,2,k));!t(w);)p=s(w),d(p,A(Oa(J(p),l),n),2);for(w=G(R(a,3,k));!t(w);)p=s(w),d(p,A(Pa(J(p),l),n),3);l=ha(R(a,5,k));d(l,A(G(Ea[l]),n),5);c||
(Qa(a,k,f)&&h.push(new Ia(l,l+2,2,5,j)),Qa(a,k,m)&&h.push(new Ia(l,l-2,3,5,j)));c=h;return b?c:c.filter(Ma.prototype.k,a)}function R(a,b,c){return A(G(a.a[b]),a.a[6+c])}function U(a){return C(G(a.a[6]),a.a[7])}function V(a){return Ra(a,a.c^1,ha(R(a,5,a.c)))}function Ua(a,b){var c=0===a,d=F(B(G(b),K[0]),c?7:-9),c=F(B(G(b),K[7]),c?9:-7);return C(d,c)}function W(a,b,c,d){var g=I(0,0);c=8*c+d;d=Na[1+d];for(F(a,c);!t(A(a,d));F(B(a,b),c))C(g,a);return g}
function Oa(a,b){return C(C(C(W(G(a),b,1,1),W(G(a),b,1,-1)),W(G(a),b,-1,1)),W(G(a),b,-1,-1))}function Pa(a,b){return C(C(C(W(G(a),b,0,1),W(G(a),b,0,-1)),W(G(a),b,1,0)),W(G(a),b,-1,0))}function Ra(a,b,c){var d=R(a,0,b);if(ia(Ua(b,d),c))return f;d=R(a,1,b);if(!t(A(G(Da[c]),d)))return f;d=R(a,5,b);if(!t(A(G(Ea[c]),d)))return f;var d=U(a),g=R(a,4,b),e=C(G(R(a,2,b)),g);if(ia(Oa(e,d),c))return f;a=C(G(R(a,3,b)),g);return ia(Pa(a,d),c)?f:m}
function X(a,b,c){M(a.b,1538+a.e);a.e&=~(1<<b+(c?0:2));M(a.b,1538+a.e)}function Qa(a,b,c){if(0===(a.e&1<<b+(c?0:2)))return m;var d=c?1:-1,g=0===b?4:60,e=U(a);if(!(d=!u(e,g+d)||!u(e,g+2*d)||!c&&!u(e,g+3*d)))d=b^1,c=c?1:-1,b=0===b?4:60,d=!(!Ra(a,d,b)&&!Ra(a,d,b+c)&&!Ra(a,d,b+2*c));return d?m:f}function Va(a){var b=a.b;return 3<=a.j.reduce(function(a,d){return a+(d.b===b.b&&d.a===b.a?1:0)},0)}
function Wa(a){if(!t(a.a[0])||!t(a.a[3])||!t(a.a[4]))return m;if(4>r(a.a[6])+r(a.a[7]))return f;if(!t(a.a[1]))return m;a=a.a[2];return ma(A(G(a),wa),a)||ma(A(G(a),xa),a)?f:m}function Xa(a,b,c,d,g){var e=C(J(d),J(g));ka(a.a[b],e);ka(a.a[6+c],e);a.f[d]=j;a.f[g]=b;M(a.b,2+b+6*c+12*d);M(a.b,2+b+6*c+12*g)}function Ya(a,b,c,d,g){ja(a.a[b],g);y(a.a[c],g);a.f[g]=c;M(a.b,2+b+6*d+12*g);M(a.b,2+c+6*d+12*g)}
function Za(a,b){if(P(b)&4){var c=b.a>>>19&7,d=a.c^1,g=Ka(b);ja(a.a[c],g);ja(a.a[6+d],g);a.f[g]=j;M(a.b,2+c+6*d+12*g)}Ja(b)&&(c=a.c,d=2===P(b),g=S[c+(d?0:2)],Xa(a,3,c,g,g+(d?-2:3)));Xa(a,Q(b),a.c,O(b),b.a&63);P(b)&8&&Ya(a,0,P(b)&8?1+(P(b)&3):0,a.c,b.a&63)}
function $a(a,b){P(b)&8&&Ya(a,P(b)&8?1+(P(b)&3):0,0,a.c,b.a&63);Xa(a,Q(b),a.c,b.a&63,O(b));if(Ja(b)){var c=a.c,d=2===P(b),g=S[c+(d?0:2)];Xa(a,3,c,g+(d?-2:3),g)}P(b)&4&&(c=b.a>>>19&7,d=a.c^1,g=Ka(b),y(a.a[c],g),y(a.a[6+d],g),a.f[g]=c,M(a.b,2+c+6*d+12*g))}Ma.prototype.k=function(a){Za(this,a);var b=V(this);$a(this,a);return!b};
function Z(a,b){a.j.push(new Fa(a.b.b,a.b.a));Za(a,b);if(V(a))return $a(a,b),a.j.pop(),m;a.g.push(b);a.i.push(a.d);a.i.push(a.e);a.i.push(a.h);N(a.b,a.d);a.d=1===P(b)?b.a&63:-1;N(a.b,a.d);var c=a.c;5===Q(b)?(X(a,c,f),X(a,c,m)):3===Q(b)&&(O(b)===S[c+0]?X(a,c,f):O(b)===S[c+2]&&X(a,c,m));c^=1;3===(b.a>>>19&7)&&(Ka(b)===S[c+0]?X(a,c,f):Ka(b)===S[c+2]&&X(a,c,m));P(b)&4||0===Q(b)?a.h=0:++a.h;a.c=c;M(a.b,0);return f}
function ab(a){if(a.g.length){var b=a.g.pop();a.c^=1;M(a.b,0);$a(a,b);a.i.pop();M(a.b,1538+a.e);a.e=a.i.pop();M(a.b,1538+a.e);N(a.b,a.d);a.d=a.i.pop();N(a.b,a.d);a.j.pop()}};var bb=[100,300,300,500,900,2E4],cb=[[0,0,0,0,0,0,0,0,50,50,50,50,50,50,50,50,10,10,20,30,30,20,10,10,5,5,10,25,25,10,5,5,0,0,0,20,20,0,0,0,5,-5,-10,0,0,-10,-5,5,5,10,10,-20,-20,10,10,5,0,0,0,0,0,0,0,0],[-50,-40,-30,-30,-30,-30,-40,-50,-40,-20,0,0,0,0,-20,-40,-30,0,10,15,15,10,0,-30,-30,5,15,20,20,15,5,-30,-30,0,15,20,20,15,0,-30,-30,5,10,15,15,10,5,-30,-40,-20,0,5,5,0,-20,-40,-50,-40,-30,-30,-30,-30,-40,-50],[-20,-10,-10,-10,-10,-10,-10,-20,-10,0,0,0,0,0,0,-10,-10,0,5,10,10,5,0,-10,-10,5,5,10,10,
5,5,-10,-10,0,10,10,10,10,0,-10,-10,10,10,10,10,10,10,-10,-10,5,0,0,0,0,5,-10,-20,-10,-10,-10,-10,-10,-10,-20],[0,0,0,0,0,0,0,0,5,10,10,10,10,10,10,5,-5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5,-5,0,0,0,0,0,0,-5,0,0,0,5,5,0,0,0],[-20,-10,-10,-5,-5,-10,-10,-20,-10,0,0,0,0,0,0,-10,-10,0,5,5,5,5,0,-10,-5,0,5,5,5,5,0,-5,0,0,5,5,5,5,0,-5,-10,5,5,5,5,5,0,-10,-10,0,5,0,0,0,0,-10,-20,-10,-10,-5,-5,-10,-10,-20],[-30,-40,-40,-50,-50,-40,-40,-30,-30,-40,-40,-50,-50,-40,-40,-30,-30,
-40,-40,-50,-50,-40,-40,-30,-30,-40,-40,-50,-50,-40,-40,-30,-20,-30,-30,-40,-40,-30,-30,-20,-10,-20,-20,-20,-20,-20,-20,-10,20,20,0,0,0,0,20,20,20,30,10,0,0,10,30,20]],cb=ab[0]/2;function db(a,b){for(var c=0,d=0;5>d;++d)c+=r(R(a,d,b))*ab[d];1<r(R(a,2,b))&&(c+=cb);return c}function eb(a,b){for(var c=0,d=0;5>=d;++d)for(var g=G(R(a,d,b));!t(g);)var e=s(g),c=c+bb[d][b?e:56^e];return c}
function fb(a,b){var c=a.a[6+b],d=a.a[6+(b^1)],g=U(a),e=la(U(a)),h;h=0;var k,v=R(a,0,b),l=0===b;k=A(F(G(v),l?8:-8),e);e=A(A(F(A(G(v),L[l?1:6]),l?16:-16),e),F(G(e),l?8:-8));k=C(k,e);h=h+r(k);h+=r(A(Ua(b,R(a,0,b)),d));for(d=G(R(a,1,b));!t(d);)h+=r(B(G(Da[s(d)]),c));h+=r(B(G(Ea[ha(R(a,5,b))]),c));d=R(a,4,b);k=C(G(R(a,2,b)),d);h+=r(B(Oa(k,g),c));d=C(G(R(a,3,b)),d);h+=r(B(Pa(d,g),c));return h*ab[0]/100};function gb(){this.a=new Ma}function hb(){$("#chessboard table tr td, #chessboard table tr td div").removeClass("from to positional capture double-push en-passant promotion castle king-castle queen-castle")}function jb(){$("#chessboard table tr td div.ui-draggable").draggable("destroy");$("#chessboard table tr td.ui-droppable").droppable("destroy")}
function kb(a){$("#moves").html("");var b=$("#dim");b.fadeIn(function(){function c(a,b,e,h){if(1>b)return d(a,e,h);for(var p=g(T(a,f,m)),k=0===a.b,l=m,n=0;n<p.length;++n)if(Z(a,p[n])){var l=f,z=c(a,b-1,e,h);$a(a);k?e=z>e?z:e:h=z<h?z:h;if(h<=e)break}if(!l){if(!V(a))return 0;a=ab[5];return k?-a:a}return 100<=a.h||Va(a)?0:k?e:h}function d(a,b,c){if(100<=a.h||Va(a))return 0;var e=db(a,0)-db(a,1)+(eb(a,0)-eb(a,1));++k;var h=0===a.b;if(h){if(e>=c)return c;b=e>b?e:b}else{if(e<=b)return b;c=e<c?e:c}for(var e=
g(T(a,f,!V(a))),p=0;p<e.length;++p)if(Z(a,e[p])){var n=d(a,b,c);$a(a);if(h){if(n>=c)return c;b=n>b?n:b}else{if(n<=b)return b;c=n<c?n:c}}return h?b:c}function g(a){function b(a){var c=P(a)&4?(1+(a.a>>>19&7))/(1+Q(a)):0,c=6*c+Q(a),c=16*c+P(a),c=64*c+(a.a&63);return c=64*c+O(a)}a.sort(function(a,c){return b(c)-b(a)});return a}var e,h=a.a,k=0;e=j;for(var v=-Infinity,l=Infinity,H=g(T(h,f)),n=0;n<H.length;++n)if(Z(h,H[n])){var x=c(h,3,v,l);$a(h);0===h.b?x>v&&(v=x,e=H[n]):x<l&&(l=x,e=H[n])}window.console.log("Evaluations: "+
k+", result move: "+La(e)+", alpha: "+v+", beta: "+l);if(!e)throw Error("Move not found");Z(a.a,e);h=$("#"+q(O(e)));e=$("#"+q(e.a&63));var w=e.offset().left-h.offset().left,p=e.offset().top-h.offset().top,z=h.children("div");z.css({position:"relative",top:"0px",left:"0px"});b.fadeOut(function(){z.animate({top:p+"px",left:w+"px"},function(){lb(a)})})})}
function lb(a){window.console.log("Moves: "+a.a.g.length+", white material: "+db(a.a,0)+", black material: "+db(a.a,1)+", white mobility: "+fb(a.a,0)+", black mobility: "+fb(a.a,1)+", white location: "+eb(a.a,0)+", black location: "+eb(a.a,1));hb();jb();$("#chessboard table tr td div").remove();$("#chessboard table tr td").removeClass("white black turn last-move "+aa.join(" "));for(var b=a.a.a[6],c=a.a.a[7],d=0;64>d;++d)for(var g=$("#"+q(d)),e=0;5>=e;++e)if(!u(a.a.a[e],d)){var h=0===a.a.b?!u(b,d):
-40,-40,-50,-50,-40,-40,-30,-30,-40,-40,-50,-50,-40,-40,-30,-20,-30,-30,-40,-40,-30,-30,-20,-10,-20,-20,-20,-20,-20,-20,-10,20,20,0,0,0,0,20,20,20,30,10,0,0,10,30,20]],db=bb[0]/2;function eb(a,b){for(var c=0,d=0;5>d;++d)c+=r(R(a,d,b))*bb[d];1<r(R(a,2,b))&&(c+=db);return c}function fb(a,b){for(var c=0,d=0;5>=d;++d)for(var g=G(R(a,d,b));!t(g);)var e=s(g),c=c+cb[d][b?e:56^e];return c}
function gb(a,b){var c=a.a[6+b],d=a.a[6+(b^1)],g=U(a),e=la(U(a)),h;h=0;var k,v=R(a,0,b),l=0===b;k=A(F(G(v),l?8:-8),e);e=A(A(F(A(G(v),L[l?1:6]),l?16:-16),e),F(G(e),l?8:-8));k=C(k,e);h=h+r(k);h+=r(A(Ua(b,R(a,0,b)),d));for(d=G(R(a,1,b));!t(d);)h+=r(B(G(Da[s(d)]),c));h+=r(B(G(Ea[ha(R(a,5,b))]),c));d=R(a,4,b);k=C(G(R(a,2,b)),d);h+=r(B(Oa(k,g),c));d=C(G(R(a,3,b)),d);h+=r(B(Pa(d,g),c));return h*bb[0]/100};function hb(){this.a=new Ma}function ib(){$("#chessboard table tr td, #chessboard table tr td div").removeClass("from to positional capture double-push en-passant promotion castle king-castle queen-castle")}function kb(){$("#chessboard table tr td div.ui-draggable").draggable("destroy");$("#chessboard table tr td.ui-droppable").droppable("destroy")}
function lb(a){$("#moves").html("");var b=$("#dim");b.fadeIn(function(){function c(a,b,e,h){if(1>b)return d(a,e,h);for(var p=g(T(a,f,m)),k=0===a.c,l=m,n=0;n<p.length;++n)if(Z(a,p[n])){var l=f,z=c(a,b-1,e,h);ab(a);k?e=z>e?z:e:h=z<h?z:h;if(h<=e)break}if(!l){if(!V(a))return 0;a=bb[5];return k?-a:a}return 100<=a.h||Va(a)||Wa(a)?0:k?e:h}function d(a,b,c){if(100<=a.h||Va(a)||Wa(a))return 0;var e=eb(a,0)-eb(a,1)+(fb(a,0)-fb(a,1));++k;var h=0===a.c;if(h){if(e>=c)return c;b=e>b?e:b}else{if(e<=b)return b;c=
e<c?e:c}for(var e=g(T(a,f,!V(a))),p=0;p<e.length;++p)if(Z(a,e[p])){var n=d(a,b,c);ab(a);if(h){if(n>=c)return c;b=n>b?n:b}else{if(n<=b)return b;c=n<c?n:c}}return h?b:c}function g(a){function b(a){var c=P(a)&4?(1+(a.a>>>19&7))/(1+Q(a)):0,c=6*c+Q(a),c=16*c+P(a),c=64*c+(a.a&63);return c=64*c+O(a)}a.sort(function(a,c){return b(c)-b(a)});return a}var e,h=a.a,k=0;e=j;for(var v=-Infinity,l=Infinity,H=g(T(h,f)),n=0;n<H.length;++n)if(Z(h,H[n])){var x=c(h,3,v,l);ab(h);0===h.c?x>v&&(v=x,e=H[n]):x<l&&(l=x,e=H[n])}window.console.log("Evaluations: "+
k+", result move: "+La(e)+", alpha: "+v+", beta: "+l);if(!e)throw Error("Move not found");Z(a.a,e);h=$("#"+q(O(e)));e=$("#"+q(e.a&63));var w=e.offset().left-h.offset().left,p=e.offset().top-h.offset().top,z=h.children("div");z.css({position:"relative",top:"0px",left:"0px"});b.fadeOut(function(){z.animate({top:p+"px",left:w+"px"},function(){mb(a)})})})}
function mb(a){window.console.log("Moves: "+a.a.g.length+", white material: "+eb(a.a,0)+", black material: "+eb(a.a,1)+", white mobility: "+gb(a.a,0)+", black mobility: "+gb(a.a,1)+", white location: "+fb(a.a,0)+", black location: "+fb(a.a,1));ib();kb();$("#chessboard table tr td div").remove();$("#chessboard table tr td").removeClass("white black turn last-move "+aa.join(" "));for(var b=a.a.a[6],c=a.a.a[7],d=0;64>d;++d)for(var g=$("#"+q(d)),e=0;5>=e;++e)if(!u(a.a.a[e],d)){var h=0===a.a.c?!u(b,d):
!u(c,d),k=$("<div>");k.attr("title",g.attr("title")+"\nPiece: "+aa[e]+"\nColor: "+(!u(b,d)?"white":"black"));k.text("\u2659\u265f\u2658\u265e\u2657\u265d\u2656\u265c\u2655\u265b\u2654\u265a".charAt(2*e+(!u(b,d)?0:1)));var v=k.add(g);v.addClass(aa[e]);v.toggleClass("white",!u(b,d));v.toggleClass("black",!u(c,d));v.toggleClass("turn",h);g.append(k);break}b=!a.a.g.length?j:a.a.g[a.a.g.length-1];b!==j&&($("#"+q(O(b))).addClass("last-move"),$("#"+q(b.a&63)).addClass("last-move"));b=!T(a.a).length?V(a.a)?
1:2:100<=a.a.h?3:Va(a.a)?5:0;if(0===b&&1===a.a.b)kb(a);else{var l=T(a.a);$("#moves").html('<a href="#" id="undo" class="'+(a.a.g.length?"can":"cannot")+'">undo</a><br/><a href="#" id="auto" class="'+(0<l.length?"can":"cannot")+'">auto</a><br/>'+l.map(function(a,b){return'<a href="#" id="'+b+'">'+La(a)+"</a><br/>"}).join(""));$("#chessboard table tr td, #chessboard table tr td div").removeClass("can-move");l.forEach(function(a){a=$("#"+q(O(a)));a.add(a.children()).addClass("can-move")});var H=m;$("#chessboard table tr td div.can-move").mouseenter(function(){if(!H){var b=
$(this),c=b.parent(),d=ca(""+c.attr("id")),c=c.add(b);c.toggleClass("from",l.some(function(a){return O(a)===d}));c.hasClass("from")&&(l.forEach(function(a){if(O(a)===d){var b=$("#"+q(a.a&63)),b=b.add(b.children());b.addClass("to");b.addClass(0===P(a)?"positional":"");b.addClass(P(a)&4?"capture":"");b.addClass(1===P(a)?"double-push":"");b.addClass(5===P(a)?"en-passant":"");b.addClass(P(a)&8?"promotion":"");b.addClass(Ja(a)?"castle":"");b.addClass(2===P(a)?"king-castle":"");b.addClass(3===P(a)?"queen-castle":
"")}}),jb(),$("#chessboard table tr td.to").droppable({drop:function(){var b=ca(""+$(this).attr("id")),c=l.filter(function(a){return O(a)===d&&(a.a&63)===b});0<c.length?(Z(a.a,c[0]),lb(a)):(hb(),jb())}}),b.draggable({start:function(){H=f},stop:function(){H=m},containment:"#chessboard table",zIndex:10,revert:"invalid"}))}}).mouseleave(function(){H||hb()});$("#moves a").click(function(){var b=$(this).attr("id");"undo"===b?($a(a.a),$a(a.a),lb(a)):"auto"===b?kb(a):(Z(a.a,l[parseInt(b,10)]),lb(a))});$("#dim").css({display:"none"});
1===b?$("#moves").append("&#35;<br/>"+(a.a.b?"1-0":"0-1")):0!==b&&$("#moves").append("&frac12;-&frac12;")}};window.makeChessGame=function(){var a=$("<table>"),b="<tr><th></th>"+"abcdefgh".split("").map(function(a){return'<th class="file">'+a+"</th>"}).join("")+"<th></th></tr>";a.append(b);for(var c=0;8>c;++c){var d=7-c,g=$("<tr>");a.append(g);var e='<th class="rank">'+(8-c)+"</th>";g.append(e);for(var h=0;8>h;++h){var k=$("<td>"),v=(d+h)%2?"light":"dark";k.attr("id",ba(d,h));k.attr("title","Algebraic: "+ba(d,h)+"\nRank: "+d+"\nFile: "+h+"\nIndex: "+(h+8*d)+"\nColor: "+v);k.addClass(v);g.append(k)}g.append(e)}a.append(b);
$("#chessboard").append(a);lb(new gb)};})();
1:2:100<=a.a.h?3:Va(a.a)?4:Wa(a.a)?5:0;if(0===b&&1===a.a.c)lb(a);else{var l=T(a.a);$("#moves").html('<a href="#" id="undo" class="'+(a.a.g.length?"can":"cannot")+'">undo</a><br/><a href="#" id="auto" class="'+(0<l.length?"can":"cannot")+'">auto</a><br/>'+l.map(function(a,b){return'<a href="#" id="'+b+'">'+La(a)+"</a><br/>"}).join(""));$("#chessboard table tr td, #chessboard table tr td div").removeClass("can-move");l.forEach(function(a){a=$("#"+q(O(a)));a.add(a.children()).addClass("can-move")});
var H=m;$("#chessboard table tr td div.can-move").mouseenter(function(){if(!H){var b=$(this),c=b.parent(),d=ca(""+c.attr("id")),c=c.add(b);c.toggleClass("from",l.some(function(a){return O(a)===d}));c.hasClass("from")&&(l.forEach(function(a){if(O(a)===d){var b=$("#"+q(a.a&63)),b=b.add(b.children());b.addClass("to");b.addClass(0===P(a)?"positional":"");b.addClass(P(a)&4?"capture":"");b.addClass(1===P(a)?"double-push":"");b.addClass(5===P(a)?"en-passant":"");b.addClass(P(a)&8?"promotion":"");b.addClass(Ja(a)?
"castle":"");b.addClass(2===P(a)?"king-castle":"");b.addClass(3===P(a)?"queen-castle":"")}}),kb(),$("#chessboard table tr td.to").droppable({drop:function(){var b=ca(""+$(this).attr("id")),c=l.filter(function(a){return O(a)===d&&(a.a&63)===b});0<c.length?(Z(a.a,c[0]),mb(a)):(ib(),kb())}}),b.draggable({start:function(){H=f},stop:function(){H=m},containment:"#chessboard table",zIndex:10,revert:"invalid"}))}}).mouseleave(function(){H||ib()});$("#moves a").click(function(){var b=$(this).attr("id");"undo"===
b?(ab(a.a),ab(a.a),mb(a)):"auto"===b?lb(a):(Z(a.a,l[parseInt(b,10)]),mb(a))});$("#dim").css({display:"none"});1===b?$("#moves").append("&#35;<br/>"+(a.a.c?"1-0":"0-1")):0!==b&&$("#moves").append("&frac12;-&frac12;")}};window.makeChessGame=function(){var a=$("<table>"),b="<tr><th></th>"+"abcdefgh".split("").map(function(a){return'<th class="file">'+a+"</th>"}).join("")+"<th></th></tr>";a.append(b);for(var c=0;8>c;++c){var d=7-c,g=$("<tr>");a.append(g);var e='<th class="rank">'+(8-c)+"</th>";g.append(e);for(var h=0;8>h;++h){var k=$("<td>"),v=(d+h)%2?"light":"dark";k.attr("id",ba(d,h));k.attr("title","Algebraic: "+ba(d,h)+"\nRank: "+d+"\nFile: "+h+"\nIndex: "+(h+8*d)+"\nColor: "+v);k.addClass(v);g.append(k)}g.append(e)}a.append(b);
$("#chessboard").append(a);mb(new hb)};})();

21
src/position.js

@ -72,7 +72,11 @@ Chess.Position = function() {
this.fillPiecesFromBitboards();
this.updateHashKey();
// TODO: repetition rule data: array or hash of Zobrist keys
/**
* @type {!Array.<!Chess.Zobrist>}
*/
this.hashHistory = [];
// TODO: checking pieces?
// TODO: separate occupied squares bitboard?
// TODO: store kings as indices instead of bitboards?
@ -450,8 +454,16 @@ Chess.Position.prototype.isFiftyMoveRuleDraw = function() {
/** @return {boolean} */
Chess.Position.prototype.isThreefoldRepetitionRuleDraw = function() {
// TODO: implement e.g. by using hash history
return false;
var currentHashKey = this.hashKey;
return this.hashHistory.reduce(
/**
* @param {number} previousValue
* @param {!Chess.Zobrist} currentValue
* @param {number} index (unused; please the Closure Compiler)
* @param {Array} array (unused; please the Closure Compiler)
* @return {number}
*/
function(previousValue, currentValue, index, array) { return previousValue + (currentValue.isEqual(currentHashKey) ? 1 : 0); }, 0) >= 3;
};
/**
@ -792,10 +804,12 @@ Chess.Position.prototype.isMoveLegal = function(move) {
* @return {boolean} true if the move was made
*/
Chess.Position.prototype.makeMove = function(move) {
this.hashHistory.push(this.hashKey.dup());
this.updatePieces(move);
if (this.isKingInCheck()) {
this.revertPieces(move);
this.hashHistory.pop();
return false;
}
@ -892,6 +906,7 @@ Chess.Position.prototype.unmakeMove = function() {
this.hashKey.updateEnPassantSquare(this.enPassantSquare);
this.enPassantSquare = /** @type {number} */(this.irreversibleHistory.pop());
this.hashKey.updateEnPassantSquare(this.enPassantSquare);
this.hashHistory.pop();
return move;
};

Loading…
Cancel
Save