From 2316f8b8248589effc756d5c09c73a1acb431574 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Fri, 14 Dec 2018 16:52:36 +0100
Subject: [PATCH] Fix Checkered and Ultima rules. Write Chess960 rules and
 complete others

---
 public/javascripts/variants/Checkered.js |  11 +-
 public/javascripts/variants/Ultima.js    |   9 +-
 views/rules/Alice.pug                    |   9 +-
 views/rules/Checkered.pug                |  13 +-
 views/rules/Chess960.pug                 | 179 ++++++++++++++++++++++-
 views/rules/Extinction.pug               |   5 +
 views/rules/Grand.pug                    |   4 +-
 views/rules/Loser.pug                    |   6 +-
 views/rules/Magnetic.pug                 |   5 +
 views/rules/Switching.pug                |   5 +
 views/rules/Ultima.pug                   |  16 +-
 11 files changed, 239 insertions(+), 23 deletions(-)

diff --git a/public/javascripts/variants/Checkered.js b/public/javascripts/variants/Checkered.js
index 019e1e2c..814d91b8 100644
--- a/public/javascripts/variants/Checkered.js
+++ b/public/javascripts/variants/Checkered.js
@@ -76,10 +76,15 @@ class CheckeredRules extends ChessRules
 			return standardMoves; //king has to be treated differently (for castles)
 		let moves = [];
 		standardMoves.forEach(m => {
-			if (m.vanish[0].p == VariantRules.PAWN && Math.abs(m.end.x-m.start.x)==2
-				&& !this.pawnFlags[this.turn][m.start.y])
+			if (m.vanish[0].p == VariantRules.PAWN)
 			{
-				return; //skip forbidden 2-squares jumps
+				if (Math.abs(m.end.x-m.start.x)==2 && !this.pawnFlags[this.turn][m.start.y])
+					return; //skip forbidden 2-squares jumps
+				if (this.board[m.end.x][m.end.y] == VariantRules.EMPTY
+					&& m.vanish.length==2 && this.getColor(m.start.x,m.start.y) == 'c')
+				{
+					return; //checkered pawns cannot take en-passant
+				}
 			}
 			if (m.vanish.length == 1)
 				moves.push(m); //no capture
diff --git a/public/javascripts/variants/Ultima.js b/public/javascripts/variants/Ultima.js
index ac0cf957..ab12c716 100644
--- a/public/javascripts/variants/Ultima.js
+++ b/public/javascripts/variants/Ultima.js
@@ -67,14 +67,14 @@ class UltimaRules extends ChessRules
 				&& this.getColor(i,j) == oppCol)
 			{
 				const oppPiece = this.getPiece(i,j);
-				if (oppPiece == V.BISHOP && piece == V.IMMOBILIZER)
-					return true;
-				if (oppPiece == V.IMMOBILIZER && ![V.BISHOP,V.IMMOBILIZER].includes(piece))
+				if (oppPiece == V.IMMOBILIZER)
 				{
 					// 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 == x && j2 == y)
+							continue; //skip initial piece!
 						if (i2>=0 && i2<sizeX && j2>=0 && j2<sizeY
 							&& this.board[i2][j2] != V.EMPTY && this.getColor(i2,j2) == color)
 						{
@@ -84,6 +84,9 @@ class UltimaRules extends ChessRules
 					}
 					return true; //immobilizer isn't neutralized
 				}
+				// Chameleons can't be immobilized twice, because there is only one immobilizer
+				if (oppPiece == V.BISHOP && piece == V.IMMOBILIZER)
+					return true;
 			}
 		}
 		return false;
diff --git a/views/rules/Alice.pug b/views/rules/Alice.pug
index 7c5fca41..dca1d477 100644
--- a/views/rules/Alice.pug
+++ b/views/rules/Alice.pug
@@ -41,7 +41,14 @@ p
 	| As in the orthodox game, win by checkmating the king. It shouldn't be able to
 	| escape the check, not even by moving to the other board.
 
-p Note: en-passant and castle occur as they do in the standard game.
+p.
+	Note: en-passant and castle occur as they do in the standard game.
+	More specifically, en-passant is possible regardless of the worlds pawns are in.
+	This is justified because pawns "go through the mirror" while moving, and can
+	thus be captured either right after or just before they pass the mirror.
+	Castling should be legal according to orthodox rules on the board 1 (it cannot
+	occur on board 2, because it would mean king and rook moved). Moreover, the
+	king cannot be in check on board 2 after castling.
 
 h3 Credits
 
diff --git a/views/rules/Checkered.pug b/views/rules/Checkered.pug
index 96e4475e..ea9b9413 100644
--- a/views/rules/Checkered.pug
+++ b/views/rules/Checkered.pug
@@ -41,7 +41,7 @@ ol
 span Remarks:
 ul
 	li A checkered move cannot be "undone" right after if this repeat the position.
-	li Checkered chess pieces cannot be captured.
+	li Checkered pieces cannot be captured.
 
 figure.diagram-container
 	.diagram
@@ -53,8 +53,15 @@ figure.diagram-container
 h3 Pawn moves
 
 ul
-	li A pawn captured on its starting square keeps the right to advance two squares.
-	li Checkered pawns cannot capture en passant.
+	li.
+		Pawns can jump two squares only from their initial rank, and only once in the game:
+		a checkered pawn returning on the pawns' start rank cannot jump. However:
+	li.
+		A pawn captured on its starting square (thus becoming "checkered") keeps the
+		right to advance two squares.
+	li.
+		Checkered pawns cannot capture en passant, because while the pawn was "passing"
+		they were of the same color.
 
 h2.stageDelimiter Stage 2
 
diff --git a/views/rules/Chess960.pug b/views/rules/Chess960.pug
index 8f70e458..a5c6e657 100644
--- a/views/rules/Chess960.pug
+++ b/views/rules/Chess960.pug
@@ -1,3 +1,178 @@
 p.boxed
-	| Orthodox rules (still with shuffled starting position). See for example the 
-	a(href="https://en.wikipedia.org/wiki/Rules_of_chess") Wikipedia page.
+	| Orthodox rules (with shuffled starting position).
+
+h3 Basics
+
+p.
+	Chess is played between two players, one moving the white pieces and the other
+	the black pieces. A "move" consists of a piece's movement on the board.
+	White and black moves alternate until a specific situation occurs (checkmate,
+	stalemate, or draw criteria met; this is detailed later).
+	White pieces always make the first move.
+
+p.
+	Each piece has a particular way to move, but almost always captures by moving to an
+	occupied square (with only one exception, detailed later).
+
+figure.diagram-container
+	.diagram
+		| fen:rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR:
+	figcaption Standard initial position.
+
+p.
+	Board coordinates: squares are always identified by a couple (letter, number).
+	The letter starts from 'a' and indicates the column, while the number starts
+	at '1' and indicates the row.
+	Since the chessboard is 64 squares, 8x8, this results in a coordinates system
+	from a1 to h8. 'a1' is the bottom left corner square from the white pieces
+	player perspective, while 'h8' is in the upper right corner.
+
+h3 Regular moves
+
+h4 Pawns
+
+p.
+	They are the weakest pieces on board, but the most complex to move.
+	From their initial rank they can either jump two squares forward (vertically),
+	or advance only one square in this same direction. After that first move they
+	only advance one square at a time, vertically, moving up.
+
+p.
+	Pawns capture by moving forward (upper on the board) one square diagonally,
+	when an enemy piece sits on that square.
+
+p.
+	When reaching the last rank, pawns must promote into any (friendly)
+	other non-royal piece: queen, rook, knight or bishop.
+
+p.
+	Moves notations: "pawn" is implicit, so for a simple move we only write the
+	destination square (because only one pawn at most can move forward to a specific
+	square). Thus, 1.e4 means "pawn from e2 to e4". However, in case of captures
+	the situation could be ambiguous (two pawns on the same rank), so the column
+	is specified too: "fxe6" (for example).
+	As you can see capture is marked by a cross symbol: "x".
+
+figure.diagram-container
+	.diagram
+		| fen:k7/8/8/1prp4/1P1P4/8/6P1/7K:
+	figcaption Possible pawn moves: g3, g4, dxc5, bxc5
+
+p
+	| For a piece movement, we just prepend the upper-case piece initial before the
+	| previously described notation. A rook taking something on f3 square writes:
+	| Rxf3. There are rules for ambiguous situation, but discussing them now would
+	| be too far off-topic. Please visit for example the 
+	a(href="https://en.wikipedia.org/wiki/Algebraic_notation_(chess)")
+		| Wikipedia page 
+	| for full information on this subject.
+
+h4 Rooks
+
+p.
+	They move either horizontally or vertically, as far as they want while the path
+	is free of pieces. If this path ends with an enemy piece, it can a priori be captured
+	(a priori because if the move ends up with the king in check, then it's illegal).
+
+h4 Knights
+
+p.
+	They are the only units able to jump over other pieces (without capturing them).
+	They do "L" moves: two squares in one direction (horizontally or vertically),
+	and then one square in an orthogonal direction.
+
+figure.diagram-container
+	.diagram
+		| fen:k7/2p5/5q2/2b5/4N3/2R3r1/3P4/7K w f6,d6,c5,f2,g3,g5:
+	figcaption Possible knight moves from e4.
+
+h4 Bishops
+
+p.
+	They move diagonally, as far as they want while the path is free of pieces.
+	If this path ends with an enemy piece, it can a priori be captured.
+
+h4 Queen
+
+p This piece combines the movement of a rook and a bishop, with the same conditions.
+
+h4 King
+
+p.
+	This piece moves like a queen, but only by one square at a time. The final square
+	must be either vacant or occupied by an enemy piece (therefore captured).
+
+p.
+	The king cannot be captured, but a move may ends up attacking enemy's king.
+	It is said to be "under check" (or "in check") and the opponent must either:
+ul
+	li move the king to a safe square, or
+	li capture the attacker, or
+	li intercept the attacking line.
+p Depending on the situation one or more of these counter-measures could be impossible.
+
+p Leaving our king in check after a move is forbidden.
+
+TODO: diagram let king in check capturing queen, bishop pinned
+figure.diagram-container
+	.diagram
+		| fen:r6k/4q3/8/8/8/B7/8/K7:
+	figcaption Bxe7 is illegal (it allows Rxa1).
+
+h3 Special moves
+
+p Apart from pawn promotion which has already been introduced, two special moves exist:
+ul
+	li.
+		castle: if both the king and the right-most (from white player perspective) rook
+		haven't moved yet, and if nothing stand in the path from king to rook, and if the
+		squares f1 and g1 are either free or occupied by the king or rook implied, then
+		the king can go to g1 while the rook moves to f1. Note that since positions are
+		shuffled one of these two pieces may apparently not move.
+		The same can be done on the other side (left-most rook), and end squares are c1
+		for king and d1 for rook. The former is small castle, and the latter large castle.
+		Notation: small castle writes "0-0" while large castle is "0-0-0".
+	li.
+		en-passant: after a pawn has jumped two squares, if an enemy pawn stands just next
+		to it then it can capture the jumping pawn "en passant", exactly as if it had
+		advanced only one square. The move is noted as usual, but with "e.p." in the end
+		to indicate the special move.
+		The capture is possible only right after the pawn jump: not later in the game.
+
+figure.diagram-container
+	.diagram
+		| fen:nr1kb1r1/ppp3pp/8/2Pp4/8/7P/PP3PP1/1R3KBR:
+	figcaption Black just played d5 (jump from d7).
+
+figure.diagram-container
+	.diagram
+		| fen:nr1kb1r1/ppp3pp/3P4/8/8/7P/PP3PP1/2KR2BR:
+	figcaption After cxd6 e.p. and 0-0-0.
+
+h3 End of the game
+
+p.
+	The best-known way to end a game is by "checkmating" the enemy king.
+	This means that you end a move in a situation where the king can be captured,
+	and your opponent has no way to avoid the capture.
+	The checkmating player has one point and the other zero, so the score writes 1-0
+	or 0-1 depending if white pieces or black pieces mated.
+
+figure.diagram-container
+	.diagram
+		| fen:rnbqkbnr/ppp2Qpp/2np4/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR:
+	figcaption Famous mating pattern: 1-0
+
+p All other ways to end the game lead to a draw (1/2-1/2): nobody wins:
+ul
+	li when a player has no legal move but is not under check,
+	li.
+		when a position is repeated three times with the same castling right and
+		same player in turn,
+	li when 50 moves are played without pawn movement or capture.
+p.
+	Note: this last way to end a game is not implemented, because it quite seldom occurs,
+	does not generalize so well to variants (it depends), and more important because
+	games played on this website are not official tournament games. If you feel like
+	manoeuvring for 200 moves and your opponent isn't bored, then why would I stop you?
+	&#9786;
diff --git a/views/rules/Extinction.pug b/views/rules/Extinction.pug
index 56725864..3133cc94 100644
--- a/views/rules/Extinction.pug
+++ b/views/rules/Extinction.pug
@@ -27,6 +27,11 @@ p.
 	Win by eliminating all enemy pawns, or rooks, or knights, or bishops, or queen(s),
 	or king(s) (there may be several if promotions happened).
 
+figure.diagram-container
+	.diagram
+		| fen:n3brk1/5ppp/3q4/8/8/8/1Q3PPP/K1R1B1N1:
+	figcaption White can win in 2 moves: 1.Qb7, 2.QxN
+
 h3 Credits
 
 p
diff --git a/views/rules/Grand.pug b/views/rules/Grand.pug
index acafca81..4d614319 100644
--- a/views/rules/Grand.pug
+++ b/views/rules/Grand.pug
@@ -35,7 +35,9 @@ p.
 	promote into a friendly piece captured (which is back on the board). If none is
 	available, the promotion on last rank is impossible and the pawn cannot move.
 
-p Pawn promotion is possible (but not forced) on the two ranks before last.
+p.
+	Pawn promotion is possible (but not forced) on the two ranks before last,
+	only in an already captured (friendly) piece.
 
 h3 End of the game
 
diff --git a/views/rules/Loser.pug b/views/rules/Loser.pug
index 3b6b1b62..584af485 100644
--- a/views/rules/Loser.pug
+++ b/views/rules/Loser.pug
@@ -18,6 +18,8 @@ p.
 	The king has no royal status: it can be taken as any other piece.
 	Thus, there is no castle rule, no checks.
 
+p Captures are mandatory, but when several capturing moves are possible you can choose.
+
 figure.diagram-container
 	.diagram
 		| fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
@@ -31,7 +33,9 @@ p.
 
 h3 End of the game
 
-p You can win by losing all material or be stalemated.
+p.
+	Win by losing all material or be stalemated (for example with only blocked pawns
+	remaining on board).
 
 h3 Credits
 
diff --git a/views/rules/Magnetic.pug b/views/rules/Magnetic.pug
index 7a0ac2ec..baad36ff 100644
--- a/views/rules/Magnetic.pug
+++ b/views/rules/Magnetic.pug
@@ -29,6 +29,11 @@ figure.diagram-container
 		| fen:3b4/8/3K4/qR1Qr1P1/3b4/8/8/8:
 	figcaption After white move Qd5
 
+p.
+	Remember that since kings have a neutral charge, any of their movement does not
+	change anything on the board. They also block magnetic actions which go in
+	their direction.
+
 h3 End of the game
 
 p Win by capturing opponent's king. There is no notion of check or stalemate here.
diff --git a/views/rules/Switching.pug b/views/rules/Switching.pug
index 4d1dcd52..ce2fdbcc 100644
--- a/views/rules/Switching.pug
+++ b/views/rules/Switching.pug
@@ -21,6 +21,11 @@ p
 	| Switching must involves two different units.
 	| Switching while the king is under check is not allowed.
 
+figure.diagram-container
+	.diagram
+		| fen:1RB3k1/5ppp/8/8/8/8/8/K7:
+	figcaption White can mate in 1 by switching b8-c8
+
 p.
 	Note: if the king and rook are on two adjacent squares, castling and switching
 	from the king are triggered in the same way. Castling takes priority:
diff --git a/views/rules/Ultima.pug b/views/rules/Ultima.pug
index a2f55f39..b3856277 100644
--- a/views/rules/Ultima.pug
+++ b/views/rules/Ultima.pug
@@ -39,19 +39,17 @@ p
 	| one square in any direction.
 	| All other pieces move like an orthodox queen.
 
-p When a piece is adjacent to an enemy immobilizer, it cannot move unless
-ul
-	li it is an immobilizer or a chameleon; or
-	li.
-		the enemy immobilizer is adjacent to a friendly immobilizer or chameleon
-		(cancelling the powers of the opponent's immobilizer)
+p.
+	When a piece is adjacent to an enemy immobilizer, it cannot move unless
+	the enemy immobilizer is adjacent to a friendly immobilizer or chameleon
+	(cancelling the powers of the opponent's immobilizer).
 p
 	| Note : this corresponds to the "pure rules" described on 
 	a(href="http://www.inference.org.uk/mackay/ultima/ultima.html") this page
 	| , which slightly differ from the initial rules.
-	| The aim is to get rid of the weird suicide rule, weakening the immobilizers lock
-	| (in particular, in the original rules two adjacent immobilizer are stuck forever
-	| until one is captured).
+	| The aim is to get rid of the weird suicide rule by weakening the immobilizers lock.
+	| In particular, in the original rules two adjacent immobilizer are stuck forever
+	| until one is captured. Note that it's still the case if all chameleons disappeared.
 
 h3 Capturing moves
 
-- 
2.44.0