From dbcc32e95d526fe518ac866f7b3cdac546f1178e Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Wed, 26 Dec 2018 02:11:20 +0100
Subject: [PATCH] A few fixes + prepare translations + rules for last 4
 variants

---
 public/javascripts/base_rules.js      | 16 ++++++++--
 public/javascripts/components/game.js | 30 ++++++++---------
 views/rules/Berolina/en.pug           | 28 ++++++++++++++++
 views/rules/Dark/en.pug               | 33 +++++++++++++++++++
 views/rules/Marseille/en.pug          | 35 ++++++++++++++++++++
 views/rules/Upsidedown/en.pug         | 46 +++++++++++++++++++++++++++
 views/translations/en.pug             |  4 +++
 views/translations/es.pug             |  4 +++
 views/translations/fr.pug             |  4 +++
 9 files changed, 183 insertions(+), 17 deletions(-)
 create mode 100644 views/rules/Berolina/en.pug
 create mode 100644 views/rules/Dark/en.pug
 create mode 100644 views/rules/Marseille/en.pug
 create mode 100644 views/rules/Upsidedown/en.pug

diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js
index ba77d718..389ba342 100644
--- a/public/javascripts/base_rules.js
+++ b/public/javascripts/base_rules.js
@@ -975,8 +975,20 @@ class ChessRules
 	// After move is played, update variables + flags
 	updateVariables(move)
 	{
-		const piece = move.vanish[0].p;
-		let c = move.vanish[0].c;
+		let piece = undefined;
+		let c = undefined;
+		if (move.vanish.length >= 1)
+		{
+			// Usual case, something is moved
+			piece = move.vanish[0].p;
+			c = move.vanish[0].c;
+		}
+		else
+		{
+			// Crazyhouse-like variants
+			piece = move.appear[0].p;
+			c = move.appear[0].c;
+		}
 		if (c == "c") //if (!["w","b"].includes(c))
 		{
 			// 'c = move.vanish[0].c' doesn't work for Checkered
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
index d8f06b33..94340e66 100644
--- a/public/javascripts/components/game.js
+++ b/public/javascripts/components/game.js
@@ -1105,7 +1105,7 @@ Vue.component('my-game', {
 		this.conn.onclose = socketCloseListener;
 		// Listen to keyboard left/right to navigate in game
 		document.onkeydown = event => {
-			if (["idle","chat"].includes(this.mode) &&
+			if (["human","computer"].includes(this.mode) &&
 				!!this.vr && this.vr.moves.length > 0 && [37,39].includes(event.keyCode))
 			{
 				event.preventDefault();
@@ -1307,7 +1307,7 @@ Vue.component('my-game', {
 			this.endGame(this.mycolor=="w"?"0-1":"1-0");
 		},
 		newGame: function(mode, fenInit, color, oppId) {
-			const fen = "rnbbqkrn/1ppppp1p/p5p1/8/8/3P4/PPP1PPPP/BNQBRKRN w1 1111 -"; //fenInit || VariantRules.GenRandInitFen();
+			const fen = fenInit || VariantRules.GenRandInitFen();
 			console.log(fen); //DEBUG
 			if (mode=="human" && !oppId)
 			{
@@ -1388,7 +1388,7 @@ Vue.component('my-game', {
 			else if (mode == "computer")
 			{
 				this.compWorker.postMessage(["init",this.vr.getFen()]);
-				this.mycolor = "w";//(Math.random() < 0.5 ? 'w' : 'b');
+				this.mycolor = (Math.random() < 0.5 ? 'w' : 'b');
 				if (this.mycolor != this.vr.turn)
 					this.playComputerMove();
 			}
@@ -1598,24 +1598,24 @@ Vue.component('my-game', {
 					// Send the move to web worker (TODO: including his own moves?!)
 					this.compWorker.postMessage(["newmove",move]);
 				}
+				const eog = this.vr.checkGameOver();
+				if (eog != "*")
+				{
+					if (["human","computer"].includes(this.mode))
+						this.endGame(eog);
+					else
+					{
+						// Just show score on screen (allow undo)
+						this.score = eog;
+						this.showScoreMsg();
+					}
+				}
 			}
 			else
 			{
 				VariantRules.PlayOnBoard(this.vr.board, move);
 				this.$forceUpdate(); //TODO: ?!
 			}
-			const eog = this.vr.checkGameOver();
-			if (eog != "*")
-			{
-				if (["human","computer"].includes(this.mode))
-					this.endGame(eog);
-				else
-				{
-					// Just show score on screen (allow undo)
-					this.score = eog;
-					this.showScoreMsg();
-				}
-			}
 			if (["human","computer","friend"].includes(this.mode))
 				this.updateStorage(); //after our moves and opponent moves
 			if (this.mode == "computer" && this.vr.turn != this.mycolor && this.score == "*")
diff --git a/views/rules/Berolina/en.pug b/views/rules/Berolina/en.pug
new file mode 100644
index 00000000..60080ea7
--- /dev/null
+++ b/views/rules/Berolina/en.pug
@@ -0,0 +1,28 @@
+p.boxed
+	| Pawns advance diagonally and capture by moving forward.
+
+h3 Specifications
+
+ul
+	li Chessboard: standard.
+	li Material: standard.
+	li Non-capturing moves: different pawn moves.
+	li Special moves: standard (different en-passant).
+	li Captures: standard (except pawns).
+	li End of game: standard.
+
+h3 Basics
+
+p.
+	TODO: explain...
+
+figure.diagram-container
+	.diagram
+		| fen:r3kbnr/pp3ppp/3p4/4p3/8/8/PPPPPPPP/R1BQKBNR:
+	figcaption After the moves 1.Nc3 d6?? 2.Nd5 e5 3.Nxc7
+
+h3 More information
+
+p.
+	Possible starting point Wikipedia page ?
+
diff --git a/views/rules/Dark/en.pug b/views/rules/Dark/en.pug
new file mode 100644
index 00000000..49a4fc8d
--- /dev/null
+++ b/views/rules/Dark/en.pug
@@ -0,0 +1,33 @@
+p.boxed
+	| You only see what your pieces can reach. Incomplete information game.
+
+h3 Specifications
+
+ul
+	li Chessboard: standard.
+	li Material: standard.
+	li Non-capturing moves: standard.
+	li Special moves: standard.
+	li Captures: standard.
+	li End of game: capture the king.
+
+p Incomplete information version of the orthodox game (also shuffled).
+
+h3 Basics
+
+p.
+	TODO
+
+figure.diagram-container
+	.diagram
+		| fen:r3kbnr/pp3ppp/3p4/4p3/8/8/PPPPPPPP/R1BQKBNR:
+	figcaption After the moves 1.Nc3 d6?? 2.Nd5 e5 3.Nxc7
+
+h3 End of the game
+
+p Win by capturing the king (no checks, no stalemate).
+
+h3 More information
+
+p.
+	TODO: quote buho21, ...
diff --git a/views/rules/Marseille/en.pug b/views/rules/Marseille/en.pug
new file mode 100644
index 00000000..221bd831
--- /dev/null
+++ b/views/rules/Marseille/en.pug
@@ -0,0 +1,35 @@
+p.boxed
+	| Move twice at every turn.
+
+h3 Specifications
+
+ul
+	li Chessboard: standard.
+	li Material: standard.
+	li Non-capturing moves: standard.
+	li Special moves: standard.
+	li Captures: standard.
+	li End of game: standard.
+
+p.
+	The only difference with orthodox chess is the double-move rule,
+	but this affects the game a lot.
+
+h3 Basics
+
+p.
+	TODO: explain, every turn twice except if check on 1st turn, or
+	very first move in game.
+	En-passant: possible in any order if 2 ep squares,
+	otherwise has to be the first move.
+	OK even if opponent moved his pawn at subturn 1.
+
+figure.diagram-container
+	.diagram
+		| fen:r3kbnr/pp3ppp/3p4/4p3/8/8/PPPPPPPP/R1BQKBNR:
+	figcaption After the moves 1.Nc3 d6?? 2.Nd5 e5 3.Nxc7
+
+h3 More information
+
+p.
+	Possible starting point Wikipedia page ?
diff --git a/views/rules/Upsidedown/en.pug b/views/rules/Upsidedown/en.pug
new file mode 100644
index 00000000..695cbe48
--- /dev/null
+++ b/views/rules/Upsidedown/en.pug
@@ -0,0 +1,46 @@
+p.boxed
+	| Pawns start on the 7th rank. Move a knight to promote them.
+
+Diagram: ... threatens Nc5-Nd3# and allow 2.b8=Q
+
+figure.diagram-container
+	.diagram
+		| fen::
+	figcaption Standard initial position after 1.Na6
+
+h3 Specifications
+
+ul
+	li Chessboard: standard.
+	li Material: standard.
+	li Non-capturing moves: standard.
+	li Special moves: no castling (and no en-passant).
+	li Captures: standard.
+	li End of game: standard.
+
+p.
+	...(Almost) Only the initial position changes, but this is a very big change.
+	In particular, castling would be rather pointless so it's disabled here.
+	En-passant captures are impossible because all pawns already reached 7th rank.
+
+h3 Note on initial position
+
+p.
+	Since truly random start can allow un-defendable mate in 3 with a knight,
+	the kings touch at least one knight in the initial position.
+	This allows to move free out of potential check from the very beginning.
+	Here is an example:
+
+// TODO: diagram
+figure.diagram-container
+	.diagram
+		| fen:r7/2n5/1q6/5k2/8/8/K7/8:
+	figcaption.
+		The king cannot take on a8 because it's guarded by the knight: it's checkmate
+
+h3 Source
+
+p
+	| See for example the 
+	a(href="https://www.chessvariants.com/diffsetup.dir/upside.html") Upside down chess
+	| &nbsp;page on chessvariants.com.
diff --git a/views/translations/en.pug b/views/translations/en.pug
index a05b1fa8..f07764b0 100644
--- a/views/translations/en.pug
+++ b/views/translations/en.pug
@@ -20,6 +20,10 @@
 		"Exotic captures": "Exotic captures",
 		"Balanced sliders & leapers": "Balanced sliders & leapers",
 		"Reverse captures": "Reverse captures",
+		"Pawns move diagonally": "Pawns move diagonally",
+		"In the shadow": "In the shadow",
+		"Move twice": "Move twice",
+		"Head upside down": "Head upside down",
 
 		// Variant page:
 		"New game": "New game",
diff --git a/views/translations/es.pug b/views/translations/es.pug
index 6c2dbcf2..b589fb16 100644
--- a/views/translations/es.pug
+++ b/views/translations/es.pug
@@ -20,6 +20,10 @@
 		"Exotic captures": "Capturas exóticas",
 		"Balanced sliders & leapers": "Modos de desplazamiento equilibrados",
 		"Reverse captures": "Capturas invertidas",
+		"Pawns move diagonally": "Peones se mueven en diagonal",
+		"In the shadow": "En la sombra",
+		"Move twice": "Mover dos veces",
+		"Head upside down": "Cabeza al revés",
 
 		// Variant page:
 		"New game": "Nueva partida",
diff --git a/views/translations/fr.pug b/views/translations/fr.pug
index e4197b41..8a86df38 100644
--- a/views/translations/fr.pug
+++ b/views/translations/fr.pug
@@ -20,6 +20,10 @@
 		"Exotic captures": "Captures exotiques",
 		"Balanced sliders & leapers": "Modes de déplacement équilibrés",
 		"Reverse captures": "Captures inversées",
+		"Pawns move diagonally": "Les pions vont en diagonale",
+		"In the shadow": "Dans l'ombre",
+		"Move twice": "Jouer deux coups",
+		"Head upside down": "La tête à l'envers",
 
 		// Variant page:
 		"New game": "Nouvelle partie",
-- 
2.44.0