+ if (!ChessRules.IsGoodFen(fen))
+ return false;
+ const fenParsed = V.ParseFen(fen);
+ // 5) Check reserves
+ if (!fenParsed.reserve || !fenParsed.reserve.match(/^[0-9]{10,10}$/))
+ return false;
+ // 6) Check promoted array
+ if (!fenParsed.promoted)
+ return false;
+ fenpromoted = fenParsed.promoted;
+ if (fenpromoted == "-")
+ return true; //no promoted piece on board
+ const squares = fenpromoted.split(",");
+ for (let square of squares)
+ {
+ const c = V.SquareToCoords(square);
+ if (c.y < 0 || c.y > V.size.y || isNaN(c.x) || c.x < 0 || c.x > V.size.x)
+ return false;
+ }
+ return true;
+ }
+
+ static ParseFen(fen)
+ {
+ const fenParts = fen.split(" ");
+ return Object.assign(
+ ChessRules.ParseFen(fen),
+ {
+ reserve: fenParts[4],
+ promoted: fenParts[5],
+ }
+ );
+ }
+
+ static GenRandInitFen()
+ {
+ return ChessRules.GenRandInitFen() + " 0000000000 -";
+ }
+
+ getFen()
+ {
+ return super.getFen() + " " + this.getReserveFen() + " " + this.getPromotedFen();
+ }
+
+ getReserveFen()
+ {
+ let counts = _.map(_.range(10), 0);
+ for (let i=0; i<V.PIECES.length; i++)
+ {
+ counts[i] = this.reserve["w"][V.PIECES[i]];
+ counts[5+i] = this.reserve["b"][V.PIECES[i]];
+ }
+ return counts.join("");
+ }
+
+ getPromotedFen()
+ {
+ let res = "";
+ for (let i=0; i<V.size.x; i++)
+ {
+ for (let j=0; j<V.size.y; j++)
+ {
+ if (this.promoted[i][j])
+ res += V.CoordsToSquare({x:i,y:j});
+ }
+ }
+ if (res.length > 0)
+ res = res.slice(0,-1); //remove last comma
+ else
+ res = "-";
+ return res;
+ }
+
+ setOtherVariables(fen)
+ {
+ super.setOtherVariables(fen);
+ const fenParsed = V.ParseFen(fen);
+ // Also init reserves (used by the interface to show landable pieces)