From 8a196305a09269888497995373658f953b9b5bf8 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Tue, 27 Nov 2018 11:05:57 +0100
Subject: [PATCH] Fixed bigger board variants. Still buggish

---
 public/javascripts/components/game.js     |   4 +-
 public/javascripts/variants/Grand.js      |   6 +-
 public/javascripts/variants/Wildebeest.js | 112 ++++++++++++++--------
 public/stylesheets/variant.sass           |   2 +-
 4 files changed, 79 insertions(+), 45 deletions(-)

diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index fcae2f11..aaef522b 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -129,7 +129,7 @@ Vue.component('my-game', {
 						{
 							'class': {
 								'board': true,
-								['board'+sizeX]: true,
+								['board'+sizeY]: true,
 							},
 							style: {
 								'width': (100/this.choices.length) + "%",
@@ -207,7 +207,7 @@ Vue.component('my-game', {
 								{
 									'class': {
 										'board': true,
-										['board'+sizeX]: true,
+										['board'+sizeY]: true,
 										'light-square': (i+j)%2==0 && (this.expert || !highlight),
 										'dark-square': (i+j)%2==1 && (this.expert || !highlight),
 										'highlight': !this.expert && highlight,
diff --git a/public/javascripts/variants/Grand.js b/public/javascripts/variants/Grand.js
index f4e325dc..db0543fc 100644
--- a/public/javascripts/variants/Grand.js
+++ b/public/javascripts/variants/Grand.js
@@ -76,7 +76,7 @@ class GrandRules extends ChessRules
 				{
 					// Two squares jump
 					moves.push(this.getBasicMove([x,y], [x+2*shift,y]));
-					if (x == startRanks[0] && this.board[x+2*shift][y] == V.EMPTY)
+					if (x == startRanks[0] && this.board[x+3*shift][y] == V.EMPTY)
 					{
 						// 3-squares jump
 						moves.push(this.getBasicMove([x,y], [x+3*shift,y]));
@@ -93,7 +93,7 @@ class GrandRules extends ChessRules
 		if (lastRanks.includes(x+shift))
 		{
 			// Promotion
-			let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+			let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN,V.MARSHALL,V.CARDINAL];
 			promotionPieces.forEach(p => {
 				if (!this.captures[color][p] || this.captures[color][p]==0)
 					return;
@@ -134,6 +134,8 @@ class GrandRules extends ChessRules
 		return moves;
 	}
 
+	// TODO: different castle?
+
 	getPotentialMarshallMoves(sq)
 	{
 		const V = VariantRules;
diff --git a/public/javascripts/variants/Wildebeest.js b/public/javascripts/variants/Wildebeest.js
index 330db3fb..2ecc01be 100644
--- a/public/javascripts/variants/Wildebeest.js
+++ b/public/javascripts/variants/Wildebeest.js
@@ -1,5 +1,5 @@
 //https://www.chessvariants.com/large.dir/wildebeest.html
-class GrandRules extends ChessRules
+class WildebeestRules extends ChessRules
 {
 	static getPpath(b)
 	{
@@ -7,6 +7,8 @@ class GrandRules extends ChessRules
 		return ([V.CAMEL,V.WILDEBEEST].includes(b[1]) ? "Wildebeest/" : "") + b;
 	}
 
+	static get size() { return [10,11]; }
+
 	static get CAMEL() { return 'c'; }
 	static get WILDEBEEST() { return 'w'; }
 
@@ -17,17 +19,25 @@ class GrandRules extends ChessRules
 		);
 	}
 
-// TODO: IN epSquares (return array), not return singleton. Easy. Adapt
-// just here for now...
+	// En-passant after 2-sq or 3-sq jumps
 	getEpSquare(move)
 	{
 		const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x];
-		if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) == 2)
+		if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) >= 2)
 		{
-			return {
-				x: (sx + ex)/2,
+			const step = (ex-sx) / Math.abs(ex-sx);
+			let res = [{
+				x: sx + step,
 				y: sy
-			};
+			}];
+			if (sx + 2*step != ex) //3-squares move
+			{
+				res.push({
+					x: sx + 2*step,
+					y: sy
+				});
+			}
+			return res;
 		}
 		return undefined; //default
 	}
@@ -45,7 +55,7 @@ class GrandRules extends ChessRules
 		}
 	}
 
-	// TODO: several changes (promote to queen or wildebeest)
+	// Pawns jump 2 or 3 squares, and promote to queen or wildebeest
 	getPotentialPawnMoves([x,y])
 	{
 		const color = this.turn;
@@ -53,8 +63,7 @@ class GrandRules extends ChessRules
 		const V = VariantRules;
 		const [sizeX,sizeY] = VariantRules.size;
 		const shift = (color == "w" ? -1 : 1);
-		const firstRank = (color == 'w' ? sizeY-1 : 0);
-		const startRank = (color == "w" ? sizeY-2 : 1);
+		const startRanks = (color == "w" ? [sizeY-2,sizeY-3] : [1,2]);
 		const lastRank = (color == "w" ? 0 : sizeY-1);
 
 		if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
@@ -63,11 +72,15 @@ class GrandRules extends ChessRules
 			if (this.board[x+shift][y] == V.EMPTY)
 			{
 				moves.push(this.getBasicMove([x,y], [x+shift,y]));
-				// Next condition because variants with pawns on 1st rank generally allow them to jump
-				if ([startRank,firstRank].includes(x) && this.board[x+2*shift][y] == V.EMPTY)
+				if (startRanks.includes(x) && this.board[x+2*shift][y] == V.EMPTY)
 				{
 					// Two squares jump
 					moves.push(this.getBasicMove([x,y], [x+2*shift,y]));
+					if (x == startRanks[0] && this.board[x+3*shift][y] == V.EMPTY)
+					{
+						// 3-squares jump
+						moves.push(this.getBasicMove([x,y], [x+3*shift,y]));
+					}
 				}
 			}
 			// Captures
@@ -80,7 +93,7 @@ class GrandRules extends ChessRules
 		if (x+shift == lastRank)
 		{
 			// Promotion
-			let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+			let promotionPieces = [V.QUEEN,V.WILDEBEEST];
 			promotionPieces.forEach(p => {
 				// Normal move
 				if (this.board[x+shift][y] == V.EMPTY)
@@ -96,22 +109,31 @@ class GrandRules extends ChessRules
 		// En passant
 		const Lep = this.epSquares.length;
 		const epSquare = Lep>0 ? this.epSquares[Lep-1] : undefined;
-		if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1)
+		if (!!epSquare)
 		{
-			let epStep = epSquare.y - y;
-			var enpassantMove = this.getBasicMove([x,y], [x+shift,y+epStep]);
-			enpassantMove.vanish.push({
-				x: x,
-				y: y+epStep,
-				p: 'p',
-				c: this.getColor(x,y+epStep)
-			});
-			moves.push(enpassantMove);
+			for (let epsq of epSquare)
+			{
+				// TODO: some redundant checks
+				if (epsq.x == x+shift && Math.abs(epsq.y - y) == 1)
+				{
+					let epStep = epsq.y - y;
+					var enpassantMove = this.getBasicMove([x,y], [x+shift,y+epStep]);
+					enpassantMove.vanish.push({
+						x: x,
+						y: y+epStep,
+						p: 'p',
+						c: this.getColor(x,y+epStep)
+					});
+					moves.push(enpassantMove);
+				}
+			}
 		}
 
 		return moves;
 	}
 
+	// TODO: wildebeest castle
+
 	getPotentialCamelMoves(sq)
 	{
 		return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.CAMEL], "oneStep");
@@ -120,17 +142,12 @@ class GrandRules extends ChessRules
 	getPotentialWildebeestMoves(sq)
 	{
 		const V = VariantRules;
-		return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT].concat(V.steps[V.CAMEL]));
+		return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT].concat(V.steps[V.CAMEL]), "oneStep");
 	}
 
-	// TODO: getCastleMoves, generalize a bit to include castleSquares as static variables
-	// ==> but this won't be exactly Wildebeest... think about it.
-
-	// TODO: also generalize lastRank ==> DO NOT HARDCODE 7 !!!
-
 	isAttacked(sq, colors)
 	{
-		return (super.isAttacked(sq, colors)
+		return super.isAttacked(sq, colors)
 			|| this.isAttackedByCamel(sq, colors)
 			|| this.isAttackedByWildebeest(sq, colors);
 	}
@@ -157,38 +174,50 @@ class GrandRules extends ChessRules
 
 	static get SEARCH_DEPTH() { return 2; }
 
-	// TODO:
 	static GenRandInitFen()
 	{
-		let pieces = [new Array(8), new Array(8)];
+		let pieces = [new Array(10), new Array(10)];
 		// Shuffle pieces on first and last rank
 		for (let c = 0; c <= 1; c++)
 		{
-			let positions = _.range(8);
+			let positions = _.range(11);
 
 			// Get random squares for bishops
-			let randIndex = 2 * _.random(3);
+			let randIndex = 2 * _.random(5);
 			let bishop1Pos = positions[randIndex];
 			// The second bishop must be on a square of different color
-			let randIndex_tmp = 2 * _.random(3) + 1;
+			let randIndex_tmp = 2 * _.random(4) + 1;
 			let bishop2Pos = positions[randIndex_tmp];
 			// Remove chosen squares
 			positions.splice(Math.max(randIndex,randIndex_tmp), 1);
 			positions.splice(Math.min(randIndex,randIndex_tmp), 1);
 
 			// Get random squares for knights
-			randIndex = _.random(5);
+			randIndex = _.random(8);
 			let knight1Pos = positions[randIndex];
 			positions.splice(randIndex, 1);
-			randIndex = _.random(4);
+			randIndex = _.random(7);
 			let knight2Pos = positions[randIndex];
 			positions.splice(randIndex, 1);
 
 			// Get random square for queen
-			randIndex = _.random(3);
+			randIndex = _.random(6);
 			let queenPos = positions[randIndex];
 			positions.splice(randIndex, 1);
 
+			// ...random square for camels
+			randIndex = _.random(5);
+			let camel1Pos = positions[randIndex];
+			positions.splice(randIndex, 1);
+			randIndex = _.random(4);
+			let camel2Pos = positions[randIndex];
+			positions.splice(randIndex, 1);
+
+			// ...random square for wildebeest
+			randIndex = _.random(3);
+			let wildebeestPos = positions[randIndex];
+			positions.splice(randIndex, 1);
+
 			// Rooks and king positions are now fixed, because of the ordering rook-king-rook
 			let rook1Pos = positions[0];
 			let kingPos = positions[1];
@@ -199,15 +228,18 @@ class GrandRules extends ChessRules
 			pieces[c][knight1Pos] = 'n';
 			pieces[c][bishop1Pos] = 'b';
 			pieces[c][queenPos] = 'q';
+			pieces[c][camel1Pos] = 'c';
+			pieces[c][camel2Pos] = 'c';
+			pieces[c][wildebeestPos] = 'w';
 			pieces[c][kingPos] = 'k';
 			pieces[c][bishop2Pos] = 'b';
 			pieces[c][knight2Pos] = 'n';
 			pieces[c][rook2Pos] = 'r';
 		}
 		let fen = pieces[0].join("") +
-			"/pppppppp/8/8/8/8/PPPPPPPP/" +
+			"/ppppppppppp/11/11/11/11/11/11/PPPPPPPPPPP/" +
 			pieces[1].join("").toUpperCase() +
-			" 1111"; //add flags
+			" 1111";
 		return fen;
 	}
 }
diff --git a/public/stylesheets/variant.sass b/public/stylesheets/variant.sass
index e28bc84c..73181854 100644
--- a/public/stylesheets/variant.sass
+++ b/public/stylesheets/variant.sass
@@ -86,7 +86,7 @@ div.board10
   padding-bottom: 10%
 
 div.board11
-  width: 9.1%
+  width: 9.09%
   padding-bottom: 9.1%
 
 .game
-- 
2.44.0