From f6dbe8e31a3260487664f1e0b50710b3f3efaf5f Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Tue, 25 Dec 2018 02:08:30 +0100
Subject: [PATCH] Simplified underCheck / getCheckSquares logic. Debugging
 Berolina

---
 public/javascripts/base_rules.js          | 36 ++++++++++----------
 public/javascripts/components/game.js     | 40 +++++++++--------------
 public/javascripts/variants/Alice.js      | 18 +++++-----
 public/javascripts/variants/Antiking.js   | 22 +++++--------
 public/javascripts/variants/Atomic.js     | 27 ++++++---------
 public/javascripts/variants/Berolina.js   | 40 ++++++++++++++---------
 public/javascripts/variants/Checkered.js  | 18 ++++------
 public/javascripts/variants/Dark.js       | 31 +++++++++++-------
 public/javascripts/variants/Extinction.js |  4 +--
 public/javascripts/variants/Loser.js      |  2 +-
 public/javascripts/variants/Magnetic.js   | 12 ++-----
 public/javascripts/variants/Upsidedown.js | 14 ++++++--
 12 files changed, 127 insertions(+), 137 deletions(-)

diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js
index 6cdae328..0bf5114a 100644
--- a/public/javascripts/base_rules.js
+++ b/public/javascripts/base_rules.js
@@ -195,16 +195,12 @@ class ChessRules
 		return (this.turn == side && this.getColor(x,y) == side);
 	}
 
-	// On which squares is opponent under check after our move ? (for interface)
-	getCheckSquares(move)
+	// On which squares is color under check ? (for interface)
+	getCheckSquares(color)
 	{
-		this.play(move);
-		const color = this.turn; //opponent
-		let res = this.isAttacked(this.kingPos[color], [this.getOppCol(color)])
+		return this.isAttacked(this.kingPos[color], [this.getOppCol(color)])
 			? [JSON.parse(JSON.stringify(this.kingPos[color]))] //need to duplicate!
 			: [];
-		this.undo(move);
-		return res;
 	}
 
 	/////////////
@@ -766,9 +762,9 @@ class ChessRules
 	////////////////////
 	// MOVES VALIDATION
 
+	// For the interface: possible moves for the current turn from square sq
 	getPossibleMovesFrom(sq)
 	{
-		// Assuming color is right (already checked)
 		return this.filterValid( this.getPotentialMovesFrom(sq) );
 	}
 
@@ -777,7 +773,13 @@ class ChessRules
 	{
 		if (moves.length == 0)
 			return [];
-		return moves.filter(m => { return !this.underCheck(m); });
+		const color = this.turn;
+		return moves.filter(m => {
+			this.play(m);
+			const res = !this.underCheck(color);
+			this.undo(m);
+			return res;
+		});
 	}
 
 	// Search for all valid moves considering current turn (for engine and game end)
@@ -912,14 +914,10 @@ class ChessRules
 		return false;
 	}
 
-	// Is current player under check after his move ?
-	underCheck(move)
+	// Is color under check after his move ?
+	underCheck(color)
 	{
-		const color = this.turn;
-		this.play(move);
-		let res = this.isAttacked(this.kingPos[color], [this.getOppCol(color)]);
-		this.undo(move);
-		return res;
+		return this.isAttacked(this.kingPos[color], [this.getOppCol(color)]);
 	}
 
 	/////////////////
@@ -945,8 +943,8 @@ class ChessRules
 	// Before move is played, update variables + flags
 	updateVariables(move)
 	{
-		const piece = this.getPiece(move.start.x,move.start.y);
-		const c = this.turn;
+		const piece = move.vanish[0].p;
+		const c = move.vanish[0].c;
 		const firstRank = (c == "w" ? V.size.x-1 : 0);
 
 		// Update king position + flags
@@ -986,6 +984,7 @@ class ChessRules
 	play(move, ingame)
 	{
 		// DEBUG:
+//		console.log("DO");
 //		if (!this.states) this.states = [];
 //		if (!ingame) this.states.push(this.getFen());
 
@@ -1020,6 +1019,7 @@ class ChessRules
 		this.unupdateVariables(move);
 
 		// DEBUG:
+//		console.log("UNDO "+this.getNotation(move));
 //		if (this.getFen() != this.states[this.states.length-1])
 //			debugger;
 //		this.states.pop();
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index 3474ea84..c14130b5 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -24,7 +24,7 @@ Vue.component('my-game', {
 			incheck: [],
 			pgnTxt: "",
 			hints: (!localStorage["hints"] ? true : localStorage["hints"] === "1"),
-			color: localStorage["color"] || "lichess", //lichess, chesscom or chesstempo
+			bcolor: localStorage["bcolor"] || "lichess", //lichess, chesscom or chesstempo
 			// sound level: 0 = no sound, 1 = sound only on newgame, 2 = always
 			sound: parseInt(localStorage["sound"] || "2"),
 			// Web worker to play computer moves without freezing interface:
@@ -342,7 +342,7 @@ Vue.component('my-game', {
 										['board'+sizeY]: true,
 										'light-square': (i+j)%2==0,
 										'dark-square': (i+j)%2==1,
-										[this.color]: true,
+										[this.bcolor]: true,
 										'in-shadow': variant=="Dark" && this.score=="*"
 											&& !this.vr.enlightened[this.mycolor][ci][cj],
 										'highlight': showLight && !!lm && _.isMatch(lm.end, {x:ci,y:cj}),
@@ -695,7 +695,7 @@ Vue.component('my-game', {
 									h("select",
 										{
 											attrs: { "id": "selectColor" },
-											on: { "change": this.setColor },
+											on: { "change": this.setBoardColor },
 										},
 										[
 											h("option",
@@ -1239,9 +1239,9 @@ Vue.component('my-game', {
 			this.hints = !this.hints;
 			localStorage["hints"] = (this.hints ? "1" : "0");
 		},
-		setColor: function(e) {
-			this.color = e.target.options[e.target.selectedIndex].value;
-			localStorage["color"] = this.color;
+		setBoardColor: function(e) {
+			this.bcolor = e.target.options[e.target.selectedIndex].value;
+			localStorage["bcolor"] = this.bcolor;
 		},
 		setSound: function(e) {
 			this.sound = parseInt(e.target.options[e.target.selectedIndex].value);
@@ -1280,7 +1280,7 @@ Vue.component('my-game', {
 			this.endGame(this.mycolor=="w"?"0-1":"1-0");
 		},
 		newGame: function(mode, fenInit, color, oppId) {
-			let fen = fenInit || VariantRules.GenRandInitFen();
+			const fen = fenInit || VariantRules.GenRandInitFen();
 			console.log(fen); //DEBUG
 			if (mode=="human" && !oppId)
 			{
@@ -1352,7 +1352,9 @@ Vue.component('my-game', {
 				if (this.mycolor != this.vr.turn)
 					this.playComputerMove();
 			}
-			//else: against a (IRL) friend or problem solving: nothing more to do
+			else if (mode == "friend")
+				this.mycolor = "w"; //convention...
+			//else: problem solving: nothing more to do
 		},
 		continueGame: function(mode) {
 			this.mode = mode;
@@ -1364,6 +1366,7 @@ Vue.component('my-game', {
 			const score = localStorage.getItem(prefix+"score"); //set in "endGame()"
 			this.fenStart = localStorage.getItem(prefix+"fenStart");
 			this.vr = new VariantRules(fen, moves);
+			this.incheck = this.vr.getCheckSquares(this.vr.turn);
 			if (mode == "human")
 			{
 				this.gameId = localStorage.getItem("gameId");
@@ -1377,13 +1380,6 @@ Vue.component('my-game', {
 				if (this.mycolor != this.vr.turn)
 					this.playComputerMove();
 			}
-			if (moves.length > 0)
-			{
-				const lastMove = moves[moves.length-1];
-				this.vr.undo(lastMove);
-				this.incheck = this.vr.getCheckSquares(lastMove);
-				this.vr.play(lastMove, "ingame");
-			}
 			if (score != "*")
 			{
 				// Small delay required when continuation run faster than drawing page
@@ -1444,6 +1440,7 @@ Vue.component('my-game', {
 					if (this.vr.canIplay(color,startSquare))
 						this.possibleMoves = this.vr.getPossibleMovesFrom(startSquare);
 				}
+				console.log(this.possibleMoves);
 				// Next line add moving piece just after current image
 				// (required for Crazyhouse reserve)
 				e.target.parentNode.insertBefore(this.selectedPiece, e.target.nextSibling);
@@ -1554,8 +1551,9 @@ Vue.component('my-game', {
 				// TODO: robustify this...
 				if (this.mode == "human" && !!move.computer)
 					return;
-				this.incheck = this.vr.getCheckSquares(move); //is opponent in check?
 				this.vr.play(move, "ingame");
+				// Is opponent in check?
+				this.incheck = this.vr.getCheckSquares(this.vr.turn);
 				if (this.sound == 2)
 					new Audio("/sounds/move.mp3").play().catch(err => {});
 				if (this.mode == "computer")
@@ -1606,15 +1604,7 @@ Vue.component('my-game', {
 				this.vr.undo(lm);
 				if (this.sound == 2)
 					new Audio("/sounds/undo.mp3").play().catch(err => {});
-				const lmBefore = this.vr.lastMove;
-				if (!!lmBefore)
-				{
-					this.vr.undo(lmBefore);
-					this.incheck = this.vr.getCheckSquares(lmBefore);
-					this.vr.play(lmBefore, "ingame");
-				}
-				else
-					this.incheck = [];
+				this.incheck = this.vr.getCheckSquares(this.vr.turn);
 			}
 		},
 	},
diff --git a/public/javascripts/variants/Alice.js b/public/javascripts/variants/Alice.js
index 1cbfccf3..2be714f0 100644
--- a/public/javascripts/variants/Alice.js
+++ b/public/javascripts/variants/Alice.js
@@ -160,7 +160,13 @@ class AliceRules extends ChessRules
 		if (moves.length == 0)
 			return [];
 		let sideBoard = [this.getSideBoard(1), this.getSideBoard(2)];
-		return moves.filter(m => { return !this.underCheck(m, sideBoard); });
+		const color = this.turn;
+		return moves.filter(m => {
+			this.playSide(m, sideBoard); //no need to track flags
+			const res = !this.underCheck(color, sideBoard);
+			this.undoSide(m, sideBoard);
+			return res;
+		});
 	}
 
 	getAllValidMoves()
@@ -221,24 +227,19 @@ class AliceRules extends ChessRules
 		});
 	}
 
-	underCheck(move, sideBoard) //sideBoard arg always provided
+	underCheck(color, sideBoard) //sideBoard arg always provided
 	{
-		const color = this.turn;
-		this.playSide(move, sideBoard); //no need to track flags
 		const kp = this.kingPos[color];
 		const mirrorSide = (sideBoard[0][kp[0]][kp[1]] != V.EMPTY ? 1 : 2);
 		let saveBoard = this.board;
 		this.board = sideBoard[mirrorSide-1];
 		let res = this.isAttacked(kp, [this.getOppCol(color)]);
 		this.board = saveBoard;
-		this.undoSide(move, sideBoard);
 		return res;
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
-		this.play(move);
-		const color = this.turn; //opponent
 		const pieces = Object.keys(V.ALICE_CODES);
 		const kp = this.kingPos[color];
 		const mirrorSide = (pieces.includes(this.getPiece(kp[0],kp[1])) ? 1 : 2);
@@ -249,7 +250,6 @@ class AliceRules extends ChessRules
 			? [ JSON.parse(JSON.stringify(this.kingPos[color])) ]
 			: [ ];
 		this.board = saveBoard;
-		this.undo(move);
 		return res;
 	}
 
diff --git a/public/javascripts/variants/Antiking.js b/public/javascripts/variants/Antiking.js
index 25a9dfcd..ed69ab71 100644
--- a/public/javascripts/variants/Antiking.js
+++ b/public/javascripts/variants/Antiking.js
@@ -88,25 +88,19 @@ class AntikingRules extends ChessRules
 			V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
-		const c = this.turn;
-		const oppCol = this.getOppCol(c);
-		this.play(move)
-		let res = this.isAttacked(this.kingPos[c], [oppCol])
-			|| !this.isAttacked(this.antikingPos[c], [oppCol]);
-		this.undo(move);
+		const oppCol = this.getOppCol(color);
+		let res = this.isAttacked(this.kingPos[color], [oppCol])
+			|| !this.isAttacked(this.antikingPos[color], [oppCol]);
 		return res;
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
-		let res = super.getCheckSquares(move);
-		this.play(move);
-		const c = this.turn;
-		if (!this.isAttacked(this.antikingPos[c], [this.getOppCol(c)]))
-			res.push(JSON.parse(JSON.stringify(this.antikingPos[c])));
-		this.undo(move);
+		let res = super.getCheckSquares(color);
+		if (!this.isAttacked(this.antikingPos[color], [this.getOppCol(color)]))
+			res.push(JSON.parse(JSON.stringify(this.antikingPos[color])));
 		return res;
 	}
 
diff --git a/public/javascripts/variants/Atomic.js b/public/javascripts/variants/Atomic.js
index 666c50b2..2adb9884 100644
--- a/public/javascripts/variants/Atomic.js
+++ b/public/javascripts/variants/Atomic.js
@@ -102,37 +102,30 @@ class AtomicRules extends ChessRules
 		}
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
-		const c = this.turn;
-		const oppCol = this.getOppCol(c);
-		this.play(move);
+		const oppCol = this.getOppCol(color);
 		let res = undefined;
 		// If our king disappeared, move is not valid
-		if (this.kingPos[c][0] < 0)
+		if (this.kingPos[color][0] < 0)
 			res = true;
 		// If opponent king disappeared, move is valid
 		else if (this.kingPos[oppCol][0] < 0)
 			res = false;
 		// Otherwise, if we remain under check, move is not valid
 		else
-			res = this.isAttacked(this.kingPos[c], [oppCol]);
-		this.undo(move);
+			res = this.isAttacked(this.kingPos[color], [oppCol]);
 		return res;
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
-		const c = this.getOppCol(this.turn);
-		// King might explode:
-		const saveKingPos = JSON.parse(JSON.stringify(this.kingPos[c]));
-		this.play(move);
 		let res = [ ];
-		if (this.kingPos[c][0] < 0)
-			res = [saveKingPos];
-		else if (this.isAttacked(this.kingPos[c], [this.getOppCol(c)]))
-			res = [ JSON.parse(JSON.stringify(this.kingPos[c])) ]
-		this.undo(move);
+		if (this.kingPos[color][0] >= 0 //king might have exploded
+			&& this.isAttacked(this.kingPos[color], [this.getOppCol(color)]))
+		{
+			res = [ JSON.parse(JSON.stringify(this.kingPos[color])) ]
+		}
 		return res;
 	}
 
diff --git a/public/javascripts/variants/Berolina.js b/public/javascripts/variants/Berolina.js
index c556f517..dc9e2574 100644
--- a/public/javascripts/variants/Berolina.js
+++ b/public/javascripts/variants/Berolina.js
@@ -18,15 +18,14 @@ class BerolinaRules extends ChessRules
 		if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) == 2)
 		{
 			return {
-				x: ex,
+				x: (ex + sx)/2,
 				y: (move.end.y + sy)/2
 			};
 		}
 		return undefined; //default
 	}
 
-	// Special pawn rules: promotions to captured friendly pieces,
-	// optional on ranks 8-9 and mandatory on rank 10.
+	// Special pawns movements
 	getPotentialPawnMoves([x,y])
 	{
 		const color = this.turn;
@@ -48,14 +47,12 @@ class BerolinaRules extends ChessRules
 				if (this.board[x+shiftX][y+shiftY] == V.EMPTY)
 				{
 					for (let piece of finalPieces)
-					{
-						moves.push(this.getBasicMove([x,y], [x+shiftX,y+shiftY],
-							{c:pawnColor,p:piece}));
-					}
-					if (x == startRank && this.board[x+2*shiftX][y] == V.EMPTY)
+						moves.push(this.getBasicMove([x,y], [x+shiftX,y+shiftY], {c:color,p:piece}));
+					if (x == startRank && y+2*shiftY>=0 && y+2*shiftY<sizeY
+						&& this.board[x+2*shiftX][y+2*shiftY] == V.EMPTY)
 					{
 						// Two squares jump
-						moves.push(this.getBasicMove([x,y], [x+2*shiftX,y+2*shiftY]);
+						moves.push(this.getBasicMove([x,y], [x+2*shiftX,y+2*shiftY]));
 					}
 				}
 			}
@@ -64,10 +61,7 @@ class BerolinaRules extends ChessRules
 				&& this.canTake([x,y], [x+shiftX,y]))
 			{
 				for (let piece of finalPieces)
-				{
-					moves.push(this.getBasicMove([x,y], [x+shiftX,y+shiftY],
-						{c:pawnColor,p:piece}));
-				}
+					moves.push(this.getBasicMove([x,y], [x+shiftX,y], {c:color,p:piece}));
 			}
 		}
 
@@ -76,18 +70,32 @@ class BerolinaRules extends ChessRules
 		const epSquare = this.epSquares[Lep-1]; //always at least one element
 		if (!!epSquare && epSquare.x == x+shiftX && epSquare.y == y)
 		{
-			let enpassantMove = this.getBasicMove([x,y], [x+shift,y]);
+			let enpassantMove = this.getBasicMove([x,y], [x+shiftX,y]);
 			enpassantMove.vanish.push({
 				x: epSquare.x,
-				y: y,
+				y: epSquare.y,
 				p: 'p',
-				c: this.getColor(epSquare.x,y)
+				c: this.getColor(epSquare.x,epSquare.y)
 			});
 			moves.push(enpassantMove);
 		}
 
 		return moves;
 	}
+
+	isAttackedByPawn([x,y], colors)
+	{
+		for (let c of colors)
+		{
+			let pawnShift = (c=="w" ? 1 : -1);
+			if (x+pawnShift>=0 && x+pawnShift<V.size.x)
+			{
+				if (this.getPiece(x+pawnShift,y)==V.PAWN && this.getColor(x+pawnShift,y)==c)
+					return true;
+			}
+		}
+		return false;
+	}
 }
 
 const VariantRules = BerolinaRules;
diff --git a/public/javascripts/variants/Checkered.js b/public/javascripts/variants/Checkered.js
index d73cef41..eee21b82 100644
--- a/public/javascripts/variants/Checkered.js
+++ b/public/javascripts/variants/Checkered.js
@@ -151,7 +151,10 @@ class CheckeredRules extends ChessRules
 			const L = this.moves.length;
 			if (L > 0 && this.oppositeMoves(this.moves[L-1], m))
 				return false;
-			return !this.underCheck(m);
+			this.play(m);
+			const res = !this.underCheck(color);
+			this.undo(m);
+			return res;
 		});
 	}
 
@@ -176,19 +179,13 @@ class CheckeredRules extends ChessRules
 		return false;
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
-		const color = this.turn;
-		this.play(move);
-		let res = this.isAttacked(this.kingPos[color], [this.getOppCol(color),'c']);
-		this.undo(move);
-		return res;
+		return this.isAttacked(this.kingPos[color], [this.getOppCol(color),'c']);
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
-		this.play(move);
-		const color = this.turn;
 		// Artifically change turn, for checkered pawns
 		this.turn = this.getOppCol(color);
 		const kingAttacked = this.isAttacked(
@@ -197,7 +194,6 @@ class CheckeredRules extends ChessRules
 			? [JSON.parse(JSON.stringify(this.kingPos[color]))] //need to duplicate!
 			: [];
 		this.turn = color;
-		this.undo(move);
 		return res;
 	}
 
diff --git a/public/javascripts/variants/Dark.js b/public/javascripts/variants/Dark.js
index 4031462c..e3e093b1 100644
--- a/public/javascripts/variants/Dark.js
+++ b/public/javascripts/variants/Dark.js
@@ -39,6 +39,23 @@ class DarkRules extends ChessRules
 			this.enlightened["b"][move.end.x][move.end.y] = true;
 	}
 
+	// Has to be redefined to avoid an infinite loop
+	getAllValidMoves()
+	{
+		const color = this.turn;
+		const oppCol = this.getOppCol(color);
+		let potentialMoves = [];
+		for (let i=0; i<V.size.x; i++)
+		{
+			for (let j=0; j<V.size.y; j++)
+			{
+				if (this.board[i][j] != V.EMPTY && this.getColor(i,j) == color)
+					Array.prototype.push.apply(potentialMoves, this.getPotentialMovesFrom([i,j]));
+			}
+		}
+		return potentialMoves; //because there are no checks
+	}
+
 	atLeastOneMove()
 	{
 		if (this.kingPos[this.turn][0] < 0)
@@ -46,22 +63,14 @@ class DarkRules extends ChessRules
 		return true; //TODO: is it right?
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
 		return false; //there is no check
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
-		const c = this.getOppCol(this.turn); //opponent
-		const saveKingPos = this.kingPos[c]; //king might be taken
-		this.play(move);
-		// The only way to be "under check" is to have lost the king (thus game over)
-		let res = this.kingPos[c][0] < 0
-			? [JSON.parse(JSON.stringify(saveKingPos))]
-			: [];
-		this.undo(move);
-		return res;
+		return [];
 	}
 
 	updateVariables(move)
diff --git a/public/javascripts/variants/Extinction.js b/public/javascripts/variants/Extinction.js
index bc061629..2f57260a 100644
--- a/public/javascripts/variants/Extinction.js
+++ b/public/javascripts/variants/Extinction.js
@@ -64,12 +64,12 @@ class ExtinctionRules extends ChessRules
 		return true; //always at least one possible move
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
 		return false; //there is no check
 	}
 
-	getCheckSquares(move)
+	getCheckSquares(color)
 	{
 		return [];
 	}
diff --git a/public/javascripts/variants/Loser.js b/public/javascripts/variants/Loser.js
index e6eb3207..dcc5c112 100644
--- a/public/javascripts/variants/Loser.js
+++ b/public/javascripts/variants/Loser.js
@@ -87,7 +87,7 @@ class LoserRules extends ChessRules
 		return moves;
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
 		return false; //No notion of check
 	}
diff --git a/public/javascripts/variants/Magnetic.js b/public/javascripts/variants/Magnetic.js
index 1ccc192e..7b0d096c 100644
--- a/public/javascripts/variants/Magnetic.js
+++ b/public/javascripts/variants/Magnetic.js
@@ -139,22 +139,14 @@ class MagneticRules extends ChessRules
 		return true; //TODO: is it right?
 	}
 
-	underCheck(move)
+	underCheck(color)
 	{
 		return false; //there is no check
 	}
 
 	getCheckSquares(move)
 	{
-		const c = this.getOppCol(this.turn); //opponent
-		const saveKingPos = this.kingPos[c]; //king might be taken
-		this.play(move);
-		// The only way to be "under check" is to have lost the king (thus game over)
-		let res = this.kingPos[c][0] < 0
-			? [JSON.parse(JSON.stringify(saveKingPos))]
-			: [];
-		this.undo(move);
-		return res;
+		return [];
 	}
 
 	updateVariables(move)
diff --git a/public/javascripts/variants/Upsidedown.js b/public/javascripts/variants/Upsidedown.js
index aa9a696d..f9668997 100644
--- a/public/javascripts/variants/Upsidedown.js
+++ b/public/javascripts/variants/Upsidedown.js
@@ -1,7 +1,15 @@
-class UpsidedownRules extends ChessRUles
+class UpsidedownRules extends ChessRules
 {
 	static HasFlags() { return false; }
 
+	// Forbid two knights moves in a row at moves 1 and 2
+	getPotentialKnightMoves(sq)
+	{
+		// But this will also affect FEN for problems, and...
+		// does it really solve the problem ?
+		//if (this.moves. ...)
+	}
+
 	getPotentialKingMoves(sq)
 	{
 		// No castle
@@ -47,9 +55,9 @@ class UpsidedownRules extends ChessRUles
 			pieces[c][knight2Pos] = 'n';
 			pieces[c][rook2Pos] = 'r';
 		}
-		return pieces["w"].join("") +
+		return pieces["w"].join("").toUpperCase() +
 			"/PPPPPPPP/8/8/8/8/pppppppp/" +
-			pieces["b"].join("").toUpperCase() +
+			pieces["b"].join("") +
 			" w 1111 -"; //add turn + flags + enpassant
 	}
 }
-- 
2.44.0