From 9d218497ab97bc0e94ec4c1f0a40cf02df3ea0d4 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Thu, 13 Dec 2018 02:44:20 +0100
Subject: [PATCH] Slight change in Ultima rules. TODO: merge with removed code
 'isAttacked'

---
 TODO                                    |  3 ++
 public/javascripts/components/game.js   |  4 +-
 public/javascripts/variants/Magnetic.js | 18 ++------
 public/javascripts/variants/Ultima.js   | 56 +++++++++++--------------
 4 files changed, 32 insertions(+), 49 deletions(-)

diff --git a/TODO b/TODO
index 07cef481..b3568538 100644
--- a/TODO
+++ b/TODO
@@ -1,2 +1,5 @@
 Full detection of repeated positions (including turn)
 In UltimaChess, consider these rules modifications: http://www.inference.org.uk/mackay/ultima/ultima.html
+Reintroduce isAttackedBy in Ultima, and fix it for pawns --> underCheck + stalemate
+--> take into account that an immobilized piece does not give check.
+(chameleons cannot be immobilized)
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index 208e0482..6af331b3 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -1008,7 +1008,7 @@ Vue.component('my-game', {
 			this.endGame(this.mycolor=="w"?"0-1":"1-0");
 		},
 		newGame: function(mode, fenInit, color, oppId, moves, continuation) {
-			const fen = fenInit || VariantRules.GenRandInitFen();
+			const fen = "M7/8/8/3K1k2/8/8/8/8 0000";//fenInit || VariantRules.GenRandInitFen();
 			console.log(fen); //DEBUG
 			if (mode=="human" && !oppId)
 			{
@@ -1066,7 +1066,7 @@ Vue.component('my-game', {
 			}
 			else if (mode == "computer")
 			{
-				this.mycolor = Math.random() < 0.5 ? 'w' : 'b';
+				this.mycolor = "w";//Math.random() < 0.5 ? 'w' : 'b';
 				if (this.mycolor == 'b')
 					setTimeout(this.playComputerMove, 500);
 			}
diff --git a/public/javascripts/variants/Magnetic.js b/public/javascripts/variants/Magnetic.js
index b17bb74a..ec2c9752 100644
--- a/public/javascripts/variants/Magnetic.js
+++ b/public/javascripts/variants/Magnetic.js
@@ -137,10 +137,11 @@ class MagneticRules extends ChessRules
 		return moves;
 	}
 
-	// TODO: verify this assertion
 	atLeastOneMove()
 	{
-		return true; //always at least one possible move
+		if (this.kingPos[this.turn][0] < 0)
+			return false;
+		return true; //TODO: is it right?
 	}
 
 	underCheck(move)
@@ -205,19 +206,6 @@ class MagneticRules extends ChessRules
 		}
 	}
 
-	checkGameOver()
-	{
-		if (this.checkRepetition())
-			return "1/2";
-
-		const color = this.turn;
-		// TODO: do we need "atLeastOneMove()"?
-		if (this.atLeastOneMove() && this.kingPos[color][0] >= 0)
-			return "*";
-
-		return this.checkGameEnd();
-	}
-
 	checkGameEnd()
 	{
 		// No valid move: our king disappeared
diff --git a/public/javascripts/variants/Ultima.js b/public/javascripts/variants/Ultima.js
index 7f9531eb..c98822dc 100644
--- a/public/javascripts/variants/Ultima.js
+++ b/public/javascripts/variants/Ultima.js
@@ -53,13 +53,13 @@ class UltimaRules extends ChessRules
 	getPotentialMovesFrom([x,y])
 	{
 		// Pre-check: is thing on this square immobilized?
-		// In this case add potential suicide as a move "taking the immobilizer"
 		const piece = this.getPiece(x,y);
 		const color = this.getColor(x,y);
 		const oppCol = this.getOppCol(color);
 		const V = VariantRules;
 		const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
 		const [sizeX,sizeY] = V.size;
+		outerLoop:
 		for (let step of adjacentSteps)
 		{
 			const [i,j] = [x+step[0],y+step[1]];
@@ -67,15 +67,23 @@ class UltimaRules extends ChessRules
 				&& this.getColor(i,j) == oppCol)
 			{
 				const oppPiece = this.getPiece(i,j);
-				if (oppPiece == V.IMMOBILIZER
-					|| (oppPiece == V.BISHOP && piece == V.IMMOBILIZER))
+				if (oppPiece == V.BISHOP && piece == V.IMMOBILIZER)
+					return [];
+				if (oppPiece == V.IMMOBILIZER && ![V.BISHOP,V.IMMOBILIZER].includes(piece))
 				{
-					return [ new Move({
-						appear: [],
-						vanish: [new PiPo({x:x,y:y,p:piece,c:color})],
-						start: {x:x,y:y},
-						end: {x:i,y:j}
-					}) ];
+					// Moving is impossible only if this immobilizer is not neutralized
+					for (let step2 of adjacentSteps)
+					{
+						const [i2,j2] = [i+step2[0],j+step2[1]];
+						if (i2>=0 && i2<sizeX && j2>=0 && j2<sizeY
+							&& this.board[i2][j2] != V.EMPTY && this.getColor(i2,j2) == color)
+						{
+							const friendlyPiece = this.getPiece(i2,j2);
+							if ([V.BISHOP,V.IMMOBILIZER].includes(friendlyPiece))
+								break outerLoop;
+						}
+					}
+					return []; //immobilizer isn't neutralized
 				}
 			}
 		}
@@ -368,6 +376,13 @@ class UltimaRules extends ChessRules
 			V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
 	}
 
+	atLeastOneMove()
+	{
+		if (this.kingPos[this.turn][0] < 0)
+			return false;
+		return super.atLeastOneMove();
+	}
+
 	underCheck(move)
 	{
 		return false; //there is no check
@@ -428,18 +443,6 @@ class UltimaRules extends ChessRules
 		}
 	}
 
-	checkGameOver()
-	{
-		if (this.checkRepetition())
-			return "1/2";
-
-		const color = this.turn;
-		if (this.atLeastOneMove() && this.kingPos[color][0] >= 0)
-			return "*";
-
-		return this.checkGameEnd();
-	}
-
 	checkGameEnd()
 	{
 		// Stalemate, or our king disappeared
@@ -521,15 +524,4 @@ class UltimaRules extends ChessRules
 	{
 		return "0000"; //TODO: or "-" ?
 	}
-
-	getNotation(move)
-	{
-		if (move.appear.length == 0)
-		{
-			const startSquare =
-				String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
-			return "^" + startSquare; //suicide
-		}
-		return super.getNotation(move);
-	}
 }
-- 
2.44.0