This repository has been archived by the owner on Apr 3, 2020. It is now read-only.
forked from jhlywa/chess.js
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathxiangqi.min.js
executable file
·6 lines (6 loc) · 13.8 KB
/
xiangqi.min.js
1
2
3
4
5
6
/* @license
* Copyright (c) 2019, lengyanyu258 ([email protected])
* Released under the BSD license
* https://github.com/lengyanyu258/xiangqi.js/blob/master/LICENSE
*/
"use strict";var Xiangqi=function(e){var l="b",p="r",i=-1,m="p",y="c",q="r",A="n",w="b",N="a",R="k",t="pcrnbakPCRNBAK",r="rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR r - - 0 1",v=Object.freeze(["1-0","0-1","1/2-1/2","*"]),k=Object.freeze({b:[16,-1,1],r:[-16,-1,1]}),_=Object.freeze({c:[-16,16,-1,1],r:[-16,16,-1,1],n:[-33,-31,31,33,-18,14,-14,18],b:[-34,34,30,-30],a:[-17,17,15,-15],k:[-16,16,-1,1]}),o=Object.freeze({NORMAL:"n",CAPTURE:"c"}),O=Object.freeze({NORMAL:1,CAPTURE:2}),C=Object.freeze({a9:0,b9:1,c9:2,d9:3,e9:4,f9:5,g9:6,h9:7,i9:8,a8:16,b8:17,c8:18,d8:19,e8:20,f8:21,g8:22,h8:23,i8:24,a7:32,b7:33,c7:34,d7:35,e7:36,f7:37,g7:38,h7:39,i7:40,a6:48,b6:49,c6:50,d6:51,e6:52,f6:53,g6:54,h6:55,i6:56,a5:64,b5:65,c5:66,d5:67,e5:68,f5:69,g5:70,h5:71,i5:72,a4:80,b4:81,c4:82,d4:83,e4:84,f4:85,g4:86,h4:87,i4:88,a3:96,b3:97,c3:98,d3:99,e3:100,f3:101,g3:102,h3:103,i3:104,a2:112,b2:113,c2:114,d2:115,e2:116,f2:117,g2:118,h2:119,i2:120,a1:128,b1:129,c1:130,d1:131,e1:132,f1:133,g1:134,h1:135,i1:136,a0:144,b0:145,c0:146,d0:147,e0:148,f0:149,g0:150,h0:151,i0:152}),P=new Array(256),f={r:i,b:i},j=p,a=0,c=1,h=[],d={};function b(e){void 0===e&&(e=!1),P=new Array(256),f={r:i,b:i},j=p,a=0,c=1,h=[],e||(d={}),$(I())}function g(){E(r)}function E(e,r){if(void 0===r&&(r=!1),!x(e).valid)return!1;var n=e.split(/\s+/),i=n[0],t=0;b(r);for(var o=0;o<i.length;++o){var u=i.charAt(o);if("/"===u)t+=7;else if(-1!=="0123456789".indexOf(u))t+=parseInt(u,10);else{var s=u<"a"?p:l;B({type:u.toLowerCase(),color:s},Q(t)),t++}}return j=n[1],a=parseInt(n[4],10),c=parseInt(n[5],10),$(I()),!0}function x(e){var r={0:"No errors.",1:"FEN string must contain six space-delimited fields.",2:"6th field (move number) must be a positive integer.",3:"5th field (half move counter) must be a non-negative integer.",4:"4th field (en-passant square) should be '-'.",5:"3rd field (castling availability) should be '-'.",6:"2nd field (side to move) is invalid.",7:"1st field (piece positions) does not contain 10 '/'-delimited rows.",8:"1st field (piece positions) is invalid [consecutive numbers].",9:"1st field (piece positions) is invalid [invalid piece].",10:"1st field (piece positions) is invalid [row too large].",11:"1st field (piece positions) is invalid [each side has one king].",12:"1st field (piece positions) is invalid [each side has no more than 2 advisers].",13:"1st field (piece positions) is invalid [each side has no more than 2 bishops].",14:"1st field (piece positions) is invalid [each side has no more than 2 knights].",15:"1st field (piece positions) is invalid [each side has no more than 2 rooks].",16:"1st field (piece positions) is invalid [each side has no more than 2 cannons].",17:"1st field (piece positions) is invalid [each side has no more than 5 pawns].",18:"1st field (piece positions) is invalid [king should at palace].",19:"1st field (piece positions) is invalid [red adviser should at right position].",20:"1st field (piece positions) is invalid [black adviser should at right position].",21:"1st field (piece positions) is invalid [red bishop should at right position].",22:"1st field (piece positions) is invalid [black bishop should at right position].",23:"1st field (piece positions) is invalid [red pawn should at right position].",24:"1st field (piece positions) is invalid [black pawn should at right position]."};function n(e){return{valid:0===e,error_number:e,error:r[e]}}var i=e.split(/\s+/);if(6!==i.length)return n(1);if(isNaN(i[5])||parseInt(i[5],10)<=0)return n(2);if(isNaN(i[4])||parseInt(i[4],10)<0)return n(3);if(!/^-$/.test(i[3]))return n(4);if(!/^-$/.test(i[2]))return n(5);if(!/^([rb])$/.test(i[1]))return n(6);var t=i[0].split("/");if(10!==t.length)return n(7);var o,u={p:{number:0,squares:[]},P:{number:0,squares:[]},c:{number:0,squares:[]},C:{number:0,squares:[]},r:{number:0,squares:[]},R:{number:0,squares:[]},n:{number:0,squares:[]},N:{number:0,squares:[]},b:{number:0,squares:[]},B:{number:0,squares:[]},a:{number:0,squares:[]},A:{number:0,squares:[]},k:{number:0,squares:[]},K:{number:0,squares:[]}};for(o=0;o<t.length;o++){for(var s=0,a=!1,f=0;f<t[o].length;f++)if(isNaN(t[o][f])){try{++u[t[o][f]].number}catch(e){return n(9)}u[t[o][f]].squares.push(9-o<<4|s),s+=1,a=!1}else{if(a)return n(8);s+=parseInt(t[o][f],10),a=!0}if(9!==s)return n(10)}if(1!==u.k.number||1!==u.K.number)return n(11);if(2<u.a.number||2<u.A.number)return n(12);if(2<u.b.number||2<u.B.number)return n(13);if(2<u.n.number||2<u.N.number)return n(14);if(2<u.r.number||2<u.R.number)return n(15);if(2<u.c.number||2<u.C.number)return n(16);if(5<u.p.number||5<u.P.number)return n(17);if(Y(R,u.k.squares[0],p)||Y(R,u.K.squares[0],l))return n(18);for(o in u.a.squares)if(Y(N,u.a.squares[o],p))return n(19);for(o in u.A.squares)if(Y(N,u.A.squares[o],l))return n(20);for(o in u.b.squares)if(Y(w,u.b.squares[o],p))return n(21);for(o in u.B.squares)if(Y(w,u.B.squares[o],l))return n(22);for(o in u.p.squares)if(Y(m,u.p.squares[o],p))return n(23);for(o in u.P.squares)if(Y(m,u.P.squares[o],l))return n(24);return n(0)}function I(){for(var e=0,r="",n=C.a9;n<=C.i0;++n){if(null==P[n])e++;else{0<e&&(r+=e,e=0);var i=P[n].color,t=P[n].type;r+=i===p?t.toUpperCase():t.toLowerCase()}8<=H(n)&&(0<e&&(r+=e),n!==C.i0&&(r+="/"),e=0,n+=7)}return[r,j,"-","-",a,c].join(" ")}function L(e){for(var r=0;r<e.length;r+=2)"string"==typeof e[r]&&"string"==typeof e[r+1]&&(d[e[r]]=e[r+1]);return d}function $(e){0<h.length||(e!==r?d.FEN=e:delete d.FEN)}function n(e){var r=P[C[e]];return r?{type:r.type,color:r.color}:null}function B(e,r){if(!("type"in e&&"color"in e))return!1;if(-1===t.indexOf(e.type.toLowerCase()))return!1;if(!(r in C))return!1;var n=C[r];return(e.type!==R||f[e.color]===i||f[e.color]===n)&&(!Y(e.type,n,e.color)&&(P[n]={type:e.type,color:e.color},e.type===R&&(f[e.color]=n),$(I()),!0))}function K(e){function r(e,r,n,i,t){r.push(function(e,r,n,i){var t={color:j,from:r,to:n,flags:i,piece:e[r].type};return e[n]&&(t.captured=e[n].type),t}(e,n,i,t))}var n,i,t,o=[],u=j,s=V(u),a=C.a9,f=C.i0,l=!(void 0!==e&&"legal"in e)||e.legal,p=void 0!==e&&"opponent"in e&&e.opponent;if(void 0!==e&&"square"in e){if(!(e.square in C))return[];a=f=C[e.square]}for(p&&(s=V(u=j=V(j))),n=a;n<=f;++n){var c=P[n];if(null!=c&&c.color===u){var h=c.type===m?k[u]:_[c.type];for(i=0,t=h.length;i<t&&(!(c.type===m&&0<i)||W(n,u));++i)for(var v=h[i],d=n,b=!1;!(J(d+=v)||c.type===A&&ee(n,i)||c.type===w&&(void 0,[-17,17,15,-15],null!=P[n+[-17,17,15,-15][i]]||W(d,u))||(c.type===N||c.type===R)&&Y(c.type,d,u));){if(null==P[d]){if(c.type===y&&b)continue;r(P,o,n,d,O.NORMAL)}else{if(c.type!==y){P[d].color===s&&r(P,o,n,d,O.CAPTURE);break}if(b){P[d].color===s&&r(P,o,n,d,O.CAPTURE);break}b=!0}if(c.type!==y&&c.type!==q)break}8<=H(n)&&(n+=7)}}if(!l)return o;var g=[];for(n=0,t=o.length;n<t;n++)X(o[n]),T(u)||g.push(o[n]),G();return p&&(j=V(j)),g}function U(e){return Q(e.from)+Q(e.to)}function z(e){return e.replace(/=/,"").replace(/[+#]?[?!]*$/,"")}function T(e){var r,n,i,t=f[e],o=V(e);for(r=0,n=_[A].length;r<n;++r)if(i=t+_[A][r],null!=P[i]&&!J(i)&&P[i].color===o&&P[i].type===A&&!ee(i,r<4?3-r:11-r))return!0;for(r=0,n=_[q].length;r<n;++r){var u=_[q][r],s=!1;for(i=t+u;!J(i);i+=u){var a=P[i];if(null!=a){if(a.color===o)if(s){if(a.type===y)return!0}else if(a.type===q||a.type===R)return!0;if(s)break;s=!0}}}for(r=0,n=k[o].length;r<n;++r)if(i=t-k[o][r],null!=P[i]&&!J(i)&&P[i].color===o&&P[i].type===m)return!0;return!1}function u(){return T(j)}function s(){return u()&&0===K().length}function F(){return!u()&&0===K().length}function S(){var e={},r=0;for(var n in C){var i=P[C[n]];i&&(e[i.type]=i.type in e?e[i.type]+1:1,r++)}return 2===r||void 0===e[A]&&void 0===e[q]&&void 0===e[y]&&void 0===e[m]}function M(){for(var e=[],r={},n=!1;;){var i=G();if(!i)break;e.push(i)}for(;;){var t=I().split(" ").slice(0,2).join(" ");if(r[t]=t in r?r[t]+1:1,3<=r[t]&&(n=!0),!e.length)break;X(e.pop())}return n}function X(e){!function(e){h.push({move:e,kings:{b:f.b,r:f.r},turn:j,half_moves:a,move_number:c})}(e),null!=P[e.to]&&P[e.to].type===R&&(f[P[e.to].color]=i),P[e.to]=P[e.from],P[e.from]=null,P[e.to].type===R&&(f[P[e.to].color]=e.to),e.flags&O.CAPTURE?a=0:a++,j===l&&c++,j=V(j)}function G(){var e=h.pop();if(null==e)return null;var r=e.move;f=e.kings,j=e.turn,a=e.half_moves,c=e.move_number;var n=V(j);return P[r.from]=P[r.to],P[r.from].type=r.piece,P[r.to]=null,0<(r.flags&O.CAPTURE)&&(P[r.to]={type:r.captured,color:n}),r}function Z(e,r){var n,i,t,o=z(e),u=o.match(/([a-iA-I][0-9])-?([a-iA-I][0-9])/);r&&u&&(n=u[1],i=u[2],t=u[3]);for(var s=K(),a=0,f=s.length;a<f;a++){if(o===z(U(s[a]))||r&&o===z(U(s[a])))return s[a];if(u&&(!n||n.toLowerCase()===s[a].piece)&&C[i]===s[a].from&&C[t]===s[a].to)return s[a]}return null}function D(e){return e>>4}function H(e){return 15&e}function Q(e){var r=H(e),n=D(e);return"abcdefghi".substring(r,r+1)+"9876543210".substring(n,n+1)}function V(e){return e===p?l:p}function W(e,r){return r===p?D(e)<5:4<D(e)}function J(e){return e<0||9<D(e)||8<H(e)}function Y(e,r,n){var i={};if(e===m)return i=[0,2,4,6,8],n===p?6<D(r)||4<D(r)&&-1===i.indexOf(H(r)):D(r)<3||D(r)<5&&-1===i.indexOf(H(r));if(e===w)i[p]=[146,150,112,116,120,82,86],i[l]=[2,6,32,36,40,66,70];else if(e===N)i[p]=[147,149,132,115,117],i[l]=[3,5,20,35,37];else{if(e!==R)return J(r);i[p]=[147,148,149,131,132,133,115,116,117],i[l]=[3,4,5,19,20,21,35,36,37]}return-1===i[n].indexOf(r)}function ee(e,r){return null!=P[e+[-16,16,-1,1][Math.floor(r/2)]]}function re(e){var r=function e(r){var n=r instanceof Array?[]:{};for(var i in r)n[i]="object"==typeof i?e(r[i]):r[i];return n}(e);r.iccs=U(r),r.to=Q(r.to),r.from=Q(r.from);var n="";for(var i in O)0<(O[i]&r.flags)&&(n+=o[i]);return r.flags=n,r}function ne(e){return e.replace(/^\s+|\s+$/g,"")}return E(void 0===e?r:e),{RED:p,BLACK:l,PAWN:m,CANNON:y,ROOK:q,KNIGHT:A,BISHOP:w,ADVISER:N,KING:R,SQUARES:function(){for(var e=[],r=C.a9;r<=C.i0;r++)9!==H(r)?e.push(Q(r)):r+=6;return e}(),FLAGS:o,load:function(e){return E(e)},reset:function(){return g()},moves:function(e){for(var r=K(e),n=[],i=0,t=r.length;i<t;i++)void 0!==e&&"verbose"in e&&e.verbose?n.push(re(r[i])):n.push(U(r[i]));return n},in_check:function(){return u()},in_checkmate:function(){return s()},in_stalemate:function(){return F()},in_draw:function(){return 120<=a||M()||S()},insufficient_material:function(){return S()},in_threefold_repetition:function(){return M()},game_over:function(){return 120<=a||s()||F()||S()||M()||f[V(j)]===i},validate_fen:function(e){return x(e)},fen:function(){return I()},board:function(){for(var e=[],r=[],n=C.a9;n<=C.i0;n++)null==P[n]?r.push(null):r.push({type:P[n].type,color:P[n].color}),8&n&&(e.push(r),r=[],n+=7);return e},pgn:function(e){var r,n="object"==typeof e&&"string"==typeof e.newline_char?e.newline_char:"\n",i="object"==typeof e&&"number"==typeof e.max_width?e.max_width:0,t=[],o=!1;for(r in d)t.push("["+r+' "'+d[r]+'"]'+n),o=!0;o&&h.length&&t.push(n);for(var u=[];0<h.length;)u.push(G());for(var s=[],a="";0<u.length;){var f=u.pop();h.length||"b"!==f.color?"b"!==f.color&&(a.length&&s.push(a),a=c+"."):a=c+". ...",a=a+" "+U(f),X(f)}if(a.length&&s.push(a),void 0!==d.Result&&s.push(d.Result),0===i)return t.join("")+s.join(" ");var l=0;for(r=0;r<s.length;r++)l+s[r].length>i&&0!==r?(" "===t[t.length-1]&&t.pop(),t.push(n),l=0):0!==r&&(t.push(" "),l++),t.push(s[r]),l+=s[r].length;return t.join("")},load_pgn:function(e,r){var n=void 0!==r&&"sloppy"in r&&r.sloppy;function a(e){return e.replace(/\\/g,"\\")}var i="object"==typeof r&&"string"==typeof r.newline_char?r.newline_char:"\r?\n",t=new RegExp("^(\\[((?:"+a(i)+")|.)*\\])(?:"+a(i)+"){2}"),o=t.test(e)?t.exec(e)[1]:"";g();var u=function(e,r){for(var n="object"==typeof r&&"string"==typeof r.newline_char?r.newline_char:"\r?\n",i={},t=e.split(new RegExp(a(n))),o="",u="",s=0;s<t.length;s++)o=t[s].replace(/^\[([A-Z][A-Za-z]*)\s.*]$/,"$1"),u=t[s].replace(/^\[[A-Za-z]+\s"(.*)"]$/,"$1"),0<ne(o).length&&(i[o]=u);return i}(o,r);for(var s in u)u.hasOwnProperty(s)&&L([s,u[s]]);if("FEN"in u&&!E(u.FEN,!0))return!1;var f=e.replace(o,"").replace(new RegExp(a(i),"g")," ");f=f.replace(/({[^}]+})+?/g,"");for(var l=/(\([^()]+\))+?/g;l.test(f);)f=f.replace(l,"");var p=ne(f=(f=(f=f.replace(/\d+\.(\.\.)?/g,"")).replace(/\.\.\./g,"")).replace(/\$\d+/g,"")).split(new RegExp(/\s+/));p=p.join(",").replace(/,,+/g,",").split(",");for(var c="",h=0;h<p.length-1;h++){if(null==(c=Z(p[h],n)))return!1;X(c)}if(c=p[p.length-1],-1<v.indexOf(c))!function(e){for(var r in e)if(e.hasOwnProperty(r))return!0;return!1}(d)||void 0!==d.Result||L(["Result",c]);else{if(null==(c=Z(c,n)))return!1;X(c)}return!0},header:function(){return L(arguments)},ascii:function(){return function(){for(var e=" +---------------------------+\n",r=C.a9;r<=C.i0;r++){if(0===H(r)&&(e+=" "+"9876543210"[D(r)]+" |"),null==P[r])e+=" . ";else{var n=P[r].type;e+=" "+(P[r].color===p?n.toUpperCase():n.toLowerCase())+" "}8&r&&(e+="|\n",r+=7)}return e+=" +---------------------------+\n",e+=" a b c d e f g h i\n"}()},turn:function(){return j},move:function(e,r){var n=void 0!==r&&"sloppy"in r&&r.sloppy,i=null;if("string"==typeof e)i=Z(e,n);else if("object"==typeof e)for(var t=K(),o=0,u=t.length;o<u;o++)if(e.from===Q(t[o].from)&&e.to===Q(t[o].to)&&!(""in t[o])){i=t[o];break}if(!i)return null;var s=re(i);return X(i),s},undo:function(){var e=G();return e?re(e):null},clear:function(){return b()},put:function(e,r){return B(e,r)},get:function(e){return n(e)},remove:function(e){return function(e){var r=n(e);return P[C[e]]=null,r&&r.type===R&&(f[r.color]=i),$(I()),r}(e)},perft:function(e){return function e(r){for(var n=K({legal:!1}),i=0,t=0,o=n.length;t<o;t++)X(n[t]),T(j)||(0<r-1?i+=e(r-1):i++),G();return i}(e)},history:function(e){for(var r=[],n=[],i=(void 0!==e&&"verbose"in e&&e.verbose);0<h.length;)r.push(G());for(;0<r.length;){var t=r.pop();i?n.push(re(t)):n.push(U(t)),X(t)}return n}}};"undefined"!=typeof exports&&(exports.Xiangqi=Xiangqi),"undefined"!=typeof define&&define(function(){return Xiangqi});