From bc97fdd1302473b774cfb19e65dc3ed3ed388901 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sat, 28 Jan 2023 21:42:02 +0100
Subject: [PATCH] Some improvements. Testing variants: Baroque has some issues

---
 base_rules.js                                 |  9 ++-
 .../pieces => pieces/Alapo}/black_CIRCLE.svg  |  0
 .../pieces => pieces/Alapo}/black_SQUARE.svg  |  0
 .../Alapo}/black_TRIANGLE.svg                 |  0
 .../Alapo}/black_TRIANGLE_inv.svg             |  0
 .../pieces => pieces/Alapo}/black_circle.svg  |  0
 .../pieces => pieces/Alapo}/black_square.svg  |  0
 .../Alapo}/black_triangle.svg                 |  0
 .../Alapo}/black_triangle_inv.svg             |  0
 .../pieces => pieces/Alapo}/white_CIRCLE.svg  |  0
 .../pieces => pieces/Alapo}/white_SQUARE.svg  |  0
 .../Alapo}/white_TRIANGLE.svg                 |  0
 .../Alapo}/white_TRIANGLE_inv.svg             |  0
 .../pieces => pieces/Alapo}/white_circle.svg  |  0
 .../pieces => pieces/Alapo}/white_square.svg  |  0
 .../Alapo}/white_triangle.svg                 |  0
 .../Alapo}/white_triangle_inv.svg             |  0
 .../Ambiguous}/red_target.svg                 |  0
 .../Ambiguous}/yellow_target.svg              |  0
 .../pieces => pieces/Avalam}/generateSVG.py   |  0
 .../pieces => pieces/Balaklava}/CREDITS       |  0
 .../Balaklava}/black_mammoth.svg              |  0
 .../Balaklava}/white_mammoth.svg              |  0
 .../Baroque}/black_immobilizer.svg            |  0
 .../Baroque}/white_immobilizer.svg            |  0
 .../pieces => pieces/Benedict}/CREDITS        |  0
 .../Benedict}/black_cleopatra.svg             |  0
 .../Benedict}/black_cleopatra_TODO.svg        |  0
 .../Benedict}/white_cleopatra.svg             |  0
 .../Benedict}/white_cleopatra_TODO.svg        |  0
 .../Chakart/pieces => pieces/Chakart}/CREDITS |  0
 .../pieces => pieces/Chakart}/banana.svg      |  0
 .../pieces => pieces/Chakart}/bomb.svg        |  0
 .../Chakart/pieces => pieces/Chakart}/egg.svg |  0
 .../pieces => pieces/Chakart}/mushroom.svg    |  0
 .../pieces => pieces/Chakart}/shell.svg       |  0
 .../pieces => pieces/Checkered}/cb.svg        |  0
 .../pieces => pieces/Checkered}/cn.svg        |  0
 .../pieces => pieces/Checkered}/cp.svg        |  0
 .../pieces => pieces/Checkered}/cq.svg        |  0
 .../pieces => pieces/Checkered}/cr.svg        |  0
 .../Weiqi/pieces => pieces/Weiqi}/CREDITS     |  0
 .../pieces => pieces/Weiqi}/black_stone.svg   |  0
 .../pieces => pieces/Weiqi}/white_stone.svg   |  0
 .../_Antiking}/black_antiking.svg             |  0
 .../_Antiking}/white_antiking.svg             |  0
 .../pieces => pieces/_Berolina}/CREDITS       |  0
 .../_Berolina}/black_pawn.svg                 |  0
 .../_Berolina}/white_pawn.svg                 |  0
 .../_SpecialCaptures}/CREDITS                 |  0
 .../_SpecialCaptures}/capture_pull.svg        |  0
 .../_SpecialCaptures}/capture_push.svg        |  0
 variants.js                                   |  2 +-
 variants/Alapo/style.css                      | 32 +++++-----
 variants/Atarigo/class.js                     |  2 +-
 variants/Avalam/class.js                      |  2 +-
 variants/Avalam/pieces/.gitignore             |  1 -
 variants/Avalam/style.css                     | 20 +++---
 variants/Avalanche/class.js                   | 63 ++++++++++++-------
 variants/Avalanche/rules.html                 |  1 +
 variants/Balaklava/class.js                   | 10 ++-
 variants/Balaklava/style.css                  |  4 +-
 variants/Baroque/class.js                     |  4 +-
 variants/Baroque/style.css                    |  4 +-
 variants/Benedict/style.css                   |  4 +-
 variants/Chakart/style.css                    | 10 +--
 variants/Checkered/style.css                  | 10 +--
 variants/Weiqi/style.css                      |  4 +-
 variants/_Antiking/style.css                  |  4 +-
 variants/_Berolina/style.css                  |  4 +-
 variants/_SpecialCaptures/class.js            | 10 +--
 variants/_SpecialCaptures/style.css           |  4 +-
 72 files changed, 116 insertions(+), 88 deletions(-)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_CIRCLE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_SQUARE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_TRIANGLE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_TRIANGLE_inv.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_circle.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_square.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_triangle.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/black_triangle_inv.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_CIRCLE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_SQUARE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_TRIANGLE.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_TRIANGLE_inv.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_circle.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_square.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_triangle.svg (100%)
 rename {variants/Alapo/pieces => pieces/Alapo}/white_triangle_inv.svg (100%)
 rename {variants/Ambiguous/pieces => pieces/Ambiguous}/red_target.svg (100%)
 rename {variants/Ambiguous/pieces => pieces/Ambiguous}/yellow_target.svg (100%)
 rename {variants/Avalam/pieces => pieces/Avalam}/generateSVG.py (100%)
 rename {variants/Balaklava/pieces => pieces/Balaklava}/CREDITS (100%)
 rename {variants/Balaklava/pieces => pieces/Balaklava}/black_mammoth.svg (100%)
 rename {variants/Balaklava/pieces => pieces/Balaklava}/white_mammoth.svg (100%)
 rename {variants/Baroque/pieces => pieces/Baroque}/black_immobilizer.svg (100%)
 rename {variants/Baroque/pieces => pieces/Baroque}/white_immobilizer.svg (100%)
 rename {variants/Benedict/pieces => pieces/Benedict}/CREDITS (100%)
 rename {variants/Benedict/pieces => pieces/Benedict}/black_cleopatra.svg (100%)
 rename {variants/Benedict/pieces => pieces/Benedict}/black_cleopatra_TODO.svg (100%)
 rename {variants/Benedict/pieces => pieces/Benedict}/white_cleopatra.svg (100%)
 rename {variants/Benedict/pieces => pieces/Benedict}/white_cleopatra_TODO.svg (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/CREDITS (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/banana.svg (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/bomb.svg (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/egg.svg (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/mushroom.svg (100%)
 rename {variants/Chakart/pieces => pieces/Chakart}/shell.svg (100%)
 rename {variants/Checkered/pieces => pieces/Checkered}/cb.svg (100%)
 rename {variants/Checkered/pieces => pieces/Checkered}/cn.svg (100%)
 rename {variants/Checkered/pieces => pieces/Checkered}/cp.svg (100%)
 rename {variants/Checkered/pieces => pieces/Checkered}/cq.svg (100%)
 rename {variants/Checkered/pieces => pieces/Checkered}/cr.svg (100%)
 rename {variants/Weiqi/pieces => pieces/Weiqi}/CREDITS (100%)
 rename {variants/Weiqi/pieces => pieces/Weiqi}/black_stone.svg (100%)
 rename {variants/Weiqi/pieces => pieces/Weiqi}/white_stone.svg (100%)
 rename {variants/_Antiking/pieces => pieces/_Antiking}/black_antiking.svg (100%)
 rename {variants/_Antiking/pieces => pieces/_Antiking}/white_antiking.svg (100%)
 rename {variants/_Berolina/pieces => pieces/_Berolina}/CREDITS (100%)
 rename {variants/_Berolina/pieces => pieces/_Berolina}/black_pawn.svg (100%)
 rename {variants/_Berolina/pieces => pieces/_Berolina}/white_pawn.svg (100%)
 rename {variants/_SpecialCaptures/pieces => pieces/_SpecialCaptures}/CREDITS (100%)
 rename {variants/_SpecialCaptures/pieces => pieces/_SpecialCaptures}/capture_pull.svg (100%)
 rename {variants/_SpecialCaptures/pieces => pieces/_SpecialCaptures}/capture_push.svg (100%)
 delete mode 100644 variants/Avalam/pieces/.gitignore

diff --git a/base_rules.js b/base_rules.js
index a8dad15..85666e2 100644
--- a/base_rules.js
+++ b/base_rules.js
@@ -2320,7 +2320,7 @@ export default class ChessRules {
 
   tryChangeTurn(move) {
     if (this.isLastMove(move)) {
-      this.turn = (this.turn == 'w' ? 'b' : 'w');
+      this.turn = C.GetOppTurn(this.turn);
       this.movesCount++;
       this.subTurn = 1;
     }
@@ -2406,7 +2406,8 @@ export default class ChessRules {
 
   playVisual(move, r) {
     move.vanish.forEach(v => {
-      this.g_pieces[v.x][v.y].remove();
+      if (this.g_pieces[v.x][v.y]) //can be null (e.g. Apocalypse)
+        this.g_pieces[v.x][v.y].remove();
       this.g_pieces[v.x][v.y] = null;
     });
     let chessboard =
@@ -2475,6 +2476,10 @@ export default class ChessRules {
 
   animateMoving(start, end, drag, segments, cb) {
     let initPiece = this.getDomPiece(start.x, start.y);
+    if (!initPiece) { //TODO: shouldn't occur!
+      cb();
+      return;
+    }
     // NOTE: cloning often not required, but light enough, and simpler
     let movingPiece = initPiece.cloneNode();
     initPiece.style.opacity = "0";
diff --git a/variants/Alapo/pieces/black_CIRCLE.svg b/pieces/Alapo/black_CIRCLE.svg
similarity index 100%
rename from variants/Alapo/pieces/black_CIRCLE.svg
rename to pieces/Alapo/black_CIRCLE.svg
diff --git a/variants/Alapo/pieces/black_SQUARE.svg b/pieces/Alapo/black_SQUARE.svg
similarity index 100%
rename from variants/Alapo/pieces/black_SQUARE.svg
rename to pieces/Alapo/black_SQUARE.svg
diff --git a/variants/Alapo/pieces/black_TRIANGLE.svg b/pieces/Alapo/black_TRIANGLE.svg
similarity index 100%
rename from variants/Alapo/pieces/black_TRIANGLE.svg
rename to pieces/Alapo/black_TRIANGLE.svg
diff --git a/variants/Alapo/pieces/black_TRIANGLE_inv.svg b/pieces/Alapo/black_TRIANGLE_inv.svg
similarity index 100%
rename from variants/Alapo/pieces/black_TRIANGLE_inv.svg
rename to pieces/Alapo/black_TRIANGLE_inv.svg
diff --git a/variants/Alapo/pieces/black_circle.svg b/pieces/Alapo/black_circle.svg
similarity index 100%
rename from variants/Alapo/pieces/black_circle.svg
rename to pieces/Alapo/black_circle.svg
diff --git a/variants/Alapo/pieces/black_square.svg b/pieces/Alapo/black_square.svg
similarity index 100%
rename from variants/Alapo/pieces/black_square.svg
rename to pieces/Alapo/black_square.svg
diff --git a/variants/Alapo/pieces/black_triangle.svg b/pieces/Alapo/black_triangle.svg
similarity index 100%
rename from variants/Alapo/pieces/black_triangle.svg
rename to pieces/Alapo/black_triangle.svg
diff --git a/variants/Alapo/pieces/black_triangle_inv.svg b/pieces/Alapo/black_triangle_inv.svg
similarity index 100%
rename from variants/Alapo/pieces/black_triangle_inv.svg
rename to pieces/Alapo/black_triangle_inv.svg
diff --git a/variants/Alapo/pieces/white_CIRCLE.svg b/pieces/Alapo/white_CIRCLE.svg
similarity index 100%
rename from variants/Alapo/pieces/white_CIRCLE.svg
rename to pieces/Alapo/white_CIRCLE.svg
diff --git a/variants/Alapo/pieces/white_SQUARE.svg b/pieces/Alapo/white_SQUARE.svg
similarity index 100%
rename from variants/Alapo/pieces/white_SQUARE.svg
rename to pieces/Alapo/white_SQUARE.svg
diff --git a/variants/Alapo/pieces/white_TRIANGLE.svg b/pieces/Alapo/white_TRIANGLE.svg
similarity index 100%
rename from variants/Alapo/pieces/white_TRIANGLE.svg
rename to pieces/Alapo/white_TRIANGLE.svg
diff --git a/variants/Alapo/pieces/white_TRIANGLE_inv.svg b/pieces/Alapo/white_TRIANGLE_inv.svg
similarity index 100%
rename from variants/Alapo/pieces/white_TRIANGLE_inv.svg
rename to pieces/Alapo/white_TRIANGLE_inv.svg
diff --git a/variants/Alapo/pieces/white_circle.svg b/pieces/Alapo/white_circle.svg
similarity index 100%
rename from variants/Alapo/pieces/white_circle.svg
rename to pieces/Alapo/white_circle.svg
diff --git a/variants/Alapo/pieces/white_square.svg b/pieces/Alapo/white_square.svg
similarity index 100%
rename from variants/Alapo/pieces/white_square.svg
rename to pieces/Alapo/white_square.svg
diff --git a/variants/Alapo/pieces/white_triangle.svg b/pieces/Alapo/white_triangle.svg
similarity index 100%
rename from variants/Alapo/pieces/white_triangle.svg
rename to pieces/Alapo/white_triangle.svg
diff --git a/variants/Alapo/pieces/white_triangle_inv.svg b/pieces/Alapo/white_triangle_inv.svg
similarity index 100%
rename from variants/Alapo/pieces/white_triangle_inv.svg
rename to pieces/Alapo/white_triangle_inv.svg
diff --git a/variants/Ambiguous/pieces/red_target.svg b/pieces/Ambiguous/red_target.svg
similarity index 100%
rename from variants/Ambiguous/pieces/red_target.svg
rename to pieces/Ambiguous/red_target.svg
diff --git a/variants/Ambiguous/pieces/yellow_target.svg b/pieces/Ambiguous/yellow_target.svg
similarity index 100%
rename from variants/Ambiguous/pieces/yellow_target.svg
rename to pieces/Ambiguous/yellow_target.svg
diff --git a/variants/Avalam/pieces/generateSVG.py b/pieces/Avalam/generateSVG.py
similarity index 100%
rename from variants/Avalam/pieces/generateSVG.py
rename to pieces/Avalam/generateSVG.py
diff --git a/variants/Balaklava/pieces/CREDITS b/pieces/Balaklava/CREDITS
similarity index 100%
rename from variants/Balaklava/pieces/CREDITS
rename to pieces/Balaklava/CREDITS
diff --git a/variants/Balaklava/pieces/black_mammoth.svg b/pieces/Balaklava/black_mammoth.svg
similarity index 100%
rename from variants/Balaklava/pieces/black_mammoth.svg
rename to pieces/Balaklava/black_mammoth.svg
diff --git a/variants/Balaklava/pieces/white_mammoth.svg b/pieces/Balaklava/white_mammoth.svg
similarity index 100%
rename from variants/Balaklava/pieces/white_mammoth.svg
rename to pieces/Balaklava/white_mammoth.svg
diff --git a/variants/Baroque/pieces/black_immobilizer.svg b/pieces/Baroque/black_immobilizer.svg
similarity index 100%
rename from variants/Baroque/pieces/black_immobilizer.svg
rename to pieces/Baroque/black_immobilizer.svg
diff --git a/variants/Baroque/pieces/white_immobilizer.svg b/pieces/Baroque/white_immobilizer.svg
similarity index 100%
rename from variants/Baroque/pieces/white_immobilizer.svg
rename to pieces/Baroque/white_immobilizer.svg
diff --git a/variants/Benedict/pieces/CREDITS b/pieces/Benedict/CREDITS
similarity index 100%
rename from variants/Benedict/pieces/CREDITS
rename to pieces/Benedict/CREDITS
diff --git a/variants/Benedict/pieces/black_cleopatra.svg b/pieces/Benedict/black_cleopatra.svg
similarity index 100%
rename from variants/Benedict/pieces/black_cleopatra.svg
rename to pieces/Benedict/black_cleopatra.svg
diff --git a/variants/Benedict/pieces/black_cleopatra_TODO.svg b/pieces/Benedict/black_cleopatra_TODO.svg
similarity index 100%
rename from variants/Benedict/pieces/black_cleopatra_TODO.svg
rename to pieces/Benedict/black_cleopatra_TODO.svg
diff --git a/variants/Benedict/pieces/white_cleopatra.svg b/pieces/Benedict/white_cleopatra.svg
similarity index 100%
rename from variants/Benedict/pieces/white_cleopatra.svg
rename to pieces/Benedict/white_cleopatra.svg
diff --git a/variants/Benedict/pieces/white_cleopatra_TODO.svg b/pieces/Benedict/white_cleopatra_TODO.svg
similarity index 100%
rename from variants/Benedict/pieces/white_cleopatra_TODO.svg
rename to pieces/Benedict/white_cleopatra_TODO.svg
diff --git a/variants/Chakart/pieces/CREDITS b/pieces/Chakart/CREDITS
similarity index 100%
rename from variants/Chakart/pieces/CREDITS
rename to pieces/Chakart/CREDITS
diff --git a/variants/Chakart/pieces/banana.svg b/pieces/Chakart/banana.svg
similarity index 100%
rename from variants/Chakart/pieces/banana.svg
rename to pieces/Chakart/banana.svg
diff --git a/variants/Chakart/pieces/bomb.svg b/pieces/Chakart/bomb.svg
similarity index 100%
rename from variants/Chakart/pieces/bomb.svg
rename to pieces/Chakart/bomb.svg
diff --git a/variants/Chakart/pieces/egg.svg b/pieces/Chakart/egg.svg
similarity index 100%
rename from variants/Chakart/pieces/egg.svg
rename to pieces/Chakart/egg.svg
diff --git a/variants/Chakart/pieces/mushroom.svg b/pieces/Chakart/mushroom.svg
similarity index 100%
rename from variants/Chakart/pieces/mushroom.svg
rename to pieces/Chakart/mushroom.svg
diff --git a/variants/Chakart/pieces/shell.svg b/pieces/Chakart/shell.svg
similarity index 100%
rename from variants/Chakart/pieces/shell.svg
rename to pieces/Chakart/shell.svg
diff --git a/variants/Checkered/pieces/cb.svg b/pieces/Checkered/cb.svg
similarity index 100%
rename from variants/Checkered/pieces/cb.svg
rename to pieces/Checkered/cb.svg
diff --git a/variants/Checkered/pieces/cn.svg b/pieces/Checkered/cn.svg
similarity index 100%
rename from variants/Checkered/pieces/cn.svg
rename to pieces/Checkered/cn.svg
diff --git a/variants/Checkered/pieces/cp.svg b/pieces/Checkered/cp.svg
similarity index 100%
rename from variants/Checkered/pieces/cp.svg
rename to pieces/Checkered/cp.svg
diff --git a/variants/Checkered/pieces/cq.svg b/pieces/Checkered/cq.svg
similarity index 100%
rename from variants/Checkered/pieces/cq.svg
rename to pieces/Checkered/cq.svg
diff --git a/variants/Checkered/pieces/cr.svg b/pieces/Checkered/cr.svg
similarity index 100%
rename from variants/Checkered/pieces/cr.svg
rename to pieces/Checkered/cr.svg
diff --git a/variants/Weiqi/pieces/CREDITS b/pieces/Weiqi/CREDITS
similarity index 100%
rename from variants/Weiqi/pieces/CREDITS
rename to pieces/Weiqi/CREDITS
diff --git a/variants/Weiqi/pieces/black_stone.svg b/pieces/Weiqi/black_stone.svg
similarity index 100%
rename from variants/Weiqi/pieces/black_stone.svg
rename to pieces/Weiqi/black_stone.svg
diff --git a/variants/Weiqi/pieces/white_stone.svg b/pieces/Weiqi/white_stone.svg
similarity index 100%
rename from variants/Weiqi/pieces/white_stone.svg
rename to pieces/Weiqi/white_stone.svg
diff --git a/variants/_Antiking/pieces/black_antiking.svg b/pieces/_Antiking/black_antiking.svg
similarity index 100%
rename from variants/_Antiking/pieces/black_antiking.svg
rename to pieces/_Antiking/black_antiking.svg
diff --git a/variants/_Antiking/pieces/white_antiking.svg b/pieces/_Antiking/white_antiking.svg
similarity index 100%
rename from variants/_Antiking/pieces/white_antiking.svg
rename to pieces/_Antiking/white_antiking.svg
diff --git a/variants/_Berolina/pieces/CREDITS b/pieces/_Berolina/CREDITS
similarity index 100%
rename from variants/_Berolina/pieces/CREDITS
rename to pieces/_Berolina/CREDITS
diff --git a/variants/_Berolina/pieces/black_pawn.svg b/pieces/_Berolina/black_pawn.svg
similarity index 100%
rename from variants/_Berolina/pieces/black_pawn.svg
rename to pieces/_Berolina/black_pawn.svg
diff --git a/variants/_Berolina/pieces/white_pawn.svg b/pieces/_Berolina/white_pawn.svg
similarity index 100%
rename from variants/_Berolina/pieces/white_pawn.svg
rename to pieces/_Berolina/white_pawn.svg
diff --git a/variants/_SpecialCaptures/pieces/CREDITS b/pieces/_SpecialCaptures/CREDITS
similarity index 100%
rename from variants/_SpecialCaptures/pieces/CREDITS
rename to pieces/_SpecialCaptures/CREDITS
diff --git a/variants/_SpecialCaptures/pieces/capture_pull.svg b/pieces/_SpecialCaptures/capture_pull.svg
similarity index 100%
rename from variants/_SpecialCaptures/pieces/capture_pull.svg
rename to pieces/_SpecialCaptures/capture_pull.svg
diff --git a/variants/_SpecialCaptures/pieces/capture_push.svg b/pieces/_SpecialCaptures/capture_push.svg
similarity index 100%
rename from variants/_SpecialCaptures/pieces/capture_push.svg
rename to pieces/_SpecialCaptures/capture_push.svg
diff --git a/variants.js b/variants.js
index ef297b6..73af2c7 100644
--- a/variants.js
+++ b/variants.js
@@ -15,8 +15,8 @@ const variants = [
   {name: 'Avalam', desc: 'Build towers'},
   {name: 'Avalanche', desc: 'Pawnfalls'},
   {name: 'Balaklava', desc: 'Meet the Mammoth'},
+  {name: "Balanced", desc: "Balanced chess"},
   {name: 'Bario', desc: 'A quantum story'},
-  {name: "Balanced", desc: "balanced chess"},
   {name: 'Baroque', desc: 'Exotic captures'},
   {name: "Benedict", desc: "Change colors"},
   {name: 'Berolina', desc: 'Pawns move diagonally'},
diff --git a/variants/Alapo/style.css b/variants/Alapo/style.css
index 7a18a55..4fbefb1 100644
--- a/variants/Alapo/style.css
+++ b/variants/Alapo/style.css
@@ -1,49 +1,49 @@
 piece.black.rook {
-  background-image: url('/variants/Alapo/pieces/black_SQUARE.svg');
+  background-image: url('/pieces/Alapo/black_SQUARE.svg');
 }
 piece.black.bishop {
-  background-image: url('/variants/Alapo/pieces/black_TRIANGLE.svg');
+  background-image: url('/pieces/Alapo/black_TRIANGLE.svg');
 }
 piece.black.bishop_inv {
-  background-image: url('/variants/Alapo/pieces/black_TRIANGLE_inv.svg');
+  background-image: url('/pieces/Alapo/black_TRIANGLE_inv.svg');
 }
 piece.black.queen {
-  background-image: url('/variants/Alapo/pieces/black_CIRCLE.svg');
+  background-image: url('/pieces/Alapo/black_CIRCLE.svg');
 }
 piece.black.babyrook {
-  background-image: url('/variants/Alapo/pieces/black_square.svg');
+  background-image: url('/pieces/Alapo/black_square.svg');
 }
 piece.black.babybishop {
-  background-image: url('/variants/Alapo/pieces/black_triangle.svg');
+  background-image: url('/pieces/Alapo/black_triangle.svg');
 }
 piece.black.babybishop_inv {
-  background-image: url('/variants/Alapo/pieces/black_triangle_inv.svg');
+  background-image: url('/pieces/Alapo/black_triangle_inv.svg');
 }
 piece.black.babyqueen {
-  background-image: url('/variants/Alapo/pieces/black_circle.svg');
+  background-image: url('/pieces/Alapo/black_circle.svg');
 }
 
 piece.white.rook {
-  background-image: url('/variants/Alapo/pieces/white_SQUARE.svg');
+  background-image: url('/pieces/Alapo/white_SQUARE.svg');
 }
 piece.white.bishop {
-  background-image: url('/variants/Alapo/pieces/white_TRIANGLE.svg');
+  background-image: url('/pieces/Alapo/white_TRIANGLE.svg');
 }
 piece.white.bishop_inv {
-  background-image: url('/variants/Alapo/pieces/white_TRIANGLE_inv.svg');
+  background-image: url('/pieces/Alapo/white_TRIANGLE_inv.svg');
 }
 piece.white.queen {
-  background-image: url('/variants/Alapo/pieces/white_CIRCLE.svg');
+  background-image: url('/pieces/Alapo/white_CIRCLE.svg');
 }
 piece.white.babyrook {
-  background-image: url('/variants/Alapo/pieces/white_square.svg');
+  background-image: url('/pieces/Alapo/white_square.svg');
 }
 piece.white.babybishop {
-  background-image: url('/variants/Alapo/pieces/white_triangle.svg');
+  background-image: url('/pieces/Alapo/white_triangle.svg');
 }
 piece.white.babybishop_inv {
-  background-image: url('/variants/Alapo/pieces/white_triangle_inv.svg');
+  background-image: url('/pieces/Alapo/white_triangle_inv.svg');
 }
 piece.white.babyqueen {
-  background-image: url('/variants/Alapo/pieces/white_circle.svg');
+  background-image: url('/pieces/Alapo/white_circle.svg');
 }
diff --git a/variants/Atarigo/class.js b/variants/Atarigo/class.js
index 25873aa..1b848c9 100644
--- a/variants/Atarigo/class.js
+++ b/variants/Atarigo/class.js
@@ -1,4 +1,4 @@
-import GoRules from "/variants/Weiqi/class.js";
+import WeiqiRules from "/variants/Weiqi/class.js";
 import Move from "/utils/Move.js";
 import PiPo from "/utils/PiPo.js";
 import {ArrayFun} from "/utils/array.js";
diff --git a/variants/Avalam/class.js b/variants/Avalam/class.js
index aaa2cf3..5fe5ed3 100644
--- a/variants/Avalam/class.js
+++ b/variants/Avalam/class.js
@@ -156,7 +156,7 @@ export default class AvalamRules extends ChessRules {
     if (height == 5)
       return [];
     let moves = [];
-    for (let s of this.pieces()['b'].moves[0].steps) {
+    for (let s of this.pieces(this.turn, x, y)['b'].both[0].steps) {
       const [i, j] = [x + s[0], y + s[1]];
       if (
         this.onBoard(i, j) &&
diff --git a/variants/Avalam/pieces/.gitignore b/variants/Avalam/pieces/.gitignore
deleted file mode 100644
index 756b22f..0000000
--- a/variants/Avalam/pieces/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.svg
diff --git a/variants/Avalam/style.css b/variants/Avalam/style.css
index ed6279c..04463d1 100644
--- a/variants/Avalam/style.css
+++ b/variants/Avalam/style.css
@@ -1,33 +1,33 @@
 piece.white.stack {
-  background-image: url('/variants/Avalam/pieces/white_stack.svg');
+  background-image: url('/pieces/Avalam/white_stack.svg');
 }
 piece.white.stack2 {
-  background-image: url('/variants/Avalam/pieces/white_stack2.svg');
+  background-image: url('/pieces/Avalam/white_stack2.svg');
 }
 piece.white.stack3 {
-  background-image: url('/variants/Avalam/pieces/white_stack3.svg');
+  background-image: url('/pieces/Avalam/white_stack3.svg');
 }
 piece.white.stack4 {
-  background-image: url('/variants/Avalam/pieces/white_stack4.svg');
+  background-image: url('/pieces/Avalam/white_stack4.svg');
 }
 piece.white.stack5 {
-  background-image: url('/variants/Avalam/pieces/white_stack5.svg');
+  background-image: url('/pieces/Avalam/white_stack5.svg');
 }
 
 piece.black.stack {
-  background-image: url('/variants/Avalam/pieces/black_stack.svg');
+  background-image: url('/pieces/Avalam/black_stack.svg');
 }
 piece.black.stack2 {
-  background-image: url('/variants/Avalam/pieces/black_stack2.svg');
+  background-image: url('/pieces/Avalam/black_stack2.svg');
 }
 piece.black.stack3 {
-  background-image: url('/variants/Avalam/pieces/black_stack3.svg');
+  background-image: url('/pieces/Avalam/black_stack3.svg');
 }
 piece.black.stack4 {
-  background-image: url('/variants/Avalam/pieces/black_stack4.svg');
+  background-image: url('/pieces/Avalam/black_stack4.svg');
 }
 piece.black.stack5 {
-  background-image: url('/variants/Avalam/pieces/black_stack5.svg');
+  background-image: url('/pieces/Avalam/black_stack5.svg');
 }
 
 .board-sq {
diff --git a/variants/Avalanche/class.js b/variants/Avalanche/class.js
index dbbe9d5..ee80550 100644
--- a/variants/Avalanche/class.js
+++ b/variants/Avalanche/class.js
@@ -7,6 +7,14 @@ export default class AvalancheRules extends ChessRules {
   static get Options() {
     return {
       select: C.Options.select,
+      input: [
+        {
+          label: "Balanced",
+          variable: "balanced",
+          type: "checkbox",
+          defaut: false
+        }
+      ],
       styles: [
         "atomic",
         "cannibal",
@@ -116,35 +124,46 @@ export default class AvalancheRules extends ChessRules {
     return false;
   }
 
-  postPlay(move) {
+  tryChangeTurn(move) {
     const color = this.turn;
     const oppCol = C.GetOppTurn(color);
-    this.promotion = (
-      this.subTurn == 2 &&
-      move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) &&
-      move.vanish[0].p == 'p'
-    );
-    if (this.subTurn == 0) {
-      this.subTurn++;
-      if (!this.atLeastOneMove(color)) {
-        move.result = "1/2"; //avoid re-computation
-        this.turn = oppCol;
+    const incrementTurn = () => {
+      if (this.options["balanced"] && this.movesCount == 0) {
+        // No pawn push on move 1:
+        return true;
       }
-    }
-    else if (this.subTurn == 2) {
-      this.turn = oppCol;
-      this.subTurn = this.promotion ? 0 : 1;
-    }
-    else { //subTurn == 1, usual case
+      this.promotion = (
+        this.subTurn == 2 &&
+        move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) &&
+        move.vanish[0].p == 'p'
+      );
+      if (this.subTurn == 0) {
+        this.subTurn++;
+        if (!this.atLeastOneMove(color)) {
+          move.result = "1/2"; //avoid re-computation
+          return true;
+        }
+        return false;
+      }
+      if (this.subTurn == 2) {
+        this.subTurn = (this.promotion ? 0 : 1);
+        return true;
+      }
+      // subTurn == 1, usual case
       const kingCapture = this.searchKingPos(oppCol).length == 0;
       if (kingCapture)
         move.result = (color == 'w' ? "1-0" : "0-1");
-      if (!kingCapture && this.atLeastOnePawnPush(oppCol))
-        this.subTurn++;
-      else {
-        this.turn = oppCol;
-        this.subTurn = this.promotion ? 0 : 1;
+      if (kingCapture || !this.atLeastOnePawnPush(oppCol)) {
+        this.subTurn = (this.promotion ? 0 : 1);
+        return true;
       }
+      // A pawn push is possible: usual case
+      this.subTurn++;
+      return false;
+    };
+    if (incrementTurn()) {
+      this.turn = oppCol;
+      this.movesCount++;
     }
   }
 
diff --git a/variants/Avalanche/rules.html b/variants/Avalanche/rules.html
index a25d2cf..b8bb255 100644
--- a/variants/Avalanche/rules.html
+++ b/variants/Avalanche/rules.html
@@ -1,6 +1,7 @@
 <p>
   After each normal move, push an opponent pawn one square forward.
   If the pawn promotes, its owner will select into which piece on next turn.
+  In balanced Avalanche, white has no pawn push at the first move.
 </p>
 
 <p>The goal is either to checkmate or to capture the enemy king.</p>
diff --git a/variants/Balaklava/class.js b/variants/Balaklava/class.js
index 0e7b72f..1ee2dd7 100644
--- a/variants/Balaklava/class.js
+++ b/variants/Balaklava/class.js
@@ -13,7 +13,7 @@ export default class BalaklavaRules extends ChessRules {
 
   pieces(color, x, y) {
     let res = super.pieces(color, x, y);
-    const knightSpec = res['n'];
+    const knightSpecMoves = res['n'].both;
     delete res['n'];
     res['m'] = {
       "class": "mammoth",
@@ -28,7 +28,11 @@ export default class BalaklavaRules extends ChessRules {
         }
       ]
     };
-    ['p', 'r', 'b', 'm', 'q'].forEach(p => res[p].moves = knightSpec.moves);
+    ['p', 'r', 'b', 'm', 'q'].forEach(p => {
+      if (!res[p].moves)
+        res[p].moves = [];
+      Array.prototype.push.apply(res[p].moves, knightSpecMoves);
+    });
     return res;
   }
 
@@ -43,7 +47,7 @@ export default class BalaklavaRules extends ChessRules {
     return {
       fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
            s.w.join("").toUpperCase(),
-      o: {}
+      o: {flags: s.flags}
     };
   }
 
diff --git a/variants/Balaklava/style.css b/variants/Balaklava/style.css
index c876806..f44a5b6 100644
--- a/variants/Balaklava/style.css
+++ b/variants/Balaklava/style.css
@@ -1,8 +1,8 @@
 @import url("/base_pieces.css");
 
 piece.white.mammoth {
-  background-image: url('/variants/Balaklava/pieces/white_mammoth.svg');
+  background-image: url('/pieces/Balaklava/white_mammoth.svg');
 }
 piece.black.mammoth {
-  background-image: url('/variants/Balaklava/pieces/black_mammoth.svg');
+  background-image: url('/pieces/Balaklava/black_mammoth.svg');
 }
diff --git a/variants/Baroque/class.js b/variants/Baroque/class.js
index 6434e05..84331a2 100644
--- a/variants/Baroque/class.js
+++ b/variants/Baroque/class.js
@@ -1,4 +1,4 @@
-import AbstractSpecialCaptureRules from "/variants/_SpecialCaptures.js";
+import AbstractSpecialCaptureRules from "/variants/_SpecialCaptures/class.js";
 import {FenUtil} from "/utils/setupPieces.js";
 import {Random} from "/utils/alea.js";
 
@@ -100,7 +100,7 @@ export default class BaroqueRules extends AbstractSpecialCaptureRules {
     const piece = this.getPiece(x, y);
     const color = this.getColor(x, y);
     const oppCol = C.GetOppTurn(color);
-    const adjacentSteps = this.pieces()['k'].moves[0].steps;
+    const adjacentSteps = this.pieces()['k'].both[0].steps;
     for (let step of adjacentSteps) {
       const [i, j] = [x + step[0], this.getY(y + step[1])];
       if (
diff --git a/variants/Baroque/style.css b/variants/Baroque/style.css
index 12550dc..d35931f 100644
--- a/variants/Baroque/style.css
+++ b/variants/Baroque/style.css
@@ -2,8 +2,8 @@
 @import url("/variants/_SpecialCaptures/style.css");
 
 piece.white.immobilizer {
-  background-image: url('/variants/Baroque/pieces/white_immobilizer.svg');
+  background-image: url('/pieces/Baroque/white_immobilizer.svg');
 }
 piece.black.immobilizer {
-  background-image: url('/variants/Baroque/pieces/black_immobilizer.svg');
+  background-image: url('/pieces/Baroque/black_immobilizer.svg');
 }
diff --git a/variants/Benedict/style.css b/variants/Benedict/style.css
index 31e16b6..1cb0afd 100644
--- a/variants/Benedict/style.css
+++ b/variants/Benedict/style.css
@@ -1,8 +1,8 @@
 @import url("/base_pieces.css");
 
 piece.black.cleopatra {
-  background-image: url('/variants/Benedict/pieces/black_cleopatra.svg');
+  background-image: url('/pieces/Benedict/black_cleopatra.svg');
 }
 piece.white.cleopatra {
-  background-image: url('/variants/Benedict/pieces/white_cleopatra.svg');
+  background-image: url('/pieces/Benedict/white_cleopatra.svg');
 }
diff --git a/variants/Chakart/style.css b/variants/Chakart/style.css
index 819fe51..6f45bed 100644
--- a/variants/Chakart/style.css
+++ b/variants/Chakart/style.css
@@ -1,19 +1,19 @@
 @import url("/base_pieces.css");
 
 piece.egg {
-  background-image: url('/variants/Chakart/pieces/egg.svg');
+  background-image: url('/pieces/Chakart/egg.svg');
 }
 
 piece.mushroom {
-  background-image: url('/variants/Chakart/pieces/mushroom.svg');
+  background-image: url('/pieces/Chakart/mushroom.svg');
 }
 
 piece.banana {
-  background-image: url('/variants/Chakart/pieces/banana.svg');
+  background-image: url('/pieces/Chakart/banana.svg');
 }
 
 piece.bomb {
-  background-image: url('/variants/Chakart/pieces/bomb.svg');
+  background-image: url('/pieces/Chakart/bomb.svg');
 }
 
 piece.white.invisible {
@@ -29,7 +29,7 @@ piece.immobilized {
 }
 
 piece.remote-capture {
-  background-image: url('/variants/Chakart/pieces/shell.svg');
+  background-image: url('/pieces/Chakart/shell.svg');
 }
 
 piece.white.mystery {
diff --git a/variants/Checkered/style.css b/variants/Checkered/style.css
index c103c25..89dad8d 100644
--- a/variants/Checkered/style.css
+++ b/variants/Checkered/style.css
@@ -1,19 +1,19 @@
 @import url("/base_pieces.css");
 
 piece.checkered.pawn {
-  background-image: url('/variants/Checkered/pieces/cp.svg');
+  background-image: url('/pieces/Checkered/cp.svg');
 }
 piece.checkered.rook {
-  background-image: url('/variants/Checkered/pieces/cr.svg');
+  background-image: url('/pieces/Checkered/cr.svg');
 }
 piece.checkered.knight {
-  background-image: url('/variants/Checkered/pieces/cn.svg');
+  background-image: url('/pieces/Checkered/cn.svg');
 }
 piece.checkered.bishop {
-  background-image: url('/variants/Checkered/pieces/cb.svg');
+  background-image: url('/pieces/Checkered/cb.svg');
 }
 piece.checkered.queen {
-  background-image: url('/variants/Checkered/pieces/cq.svg');
+  background-image: url('/pieces/Checkered/cq.svg');
 }
 
 div.info-text {
diff --git a/variants/Weiqi/style.css b/variants/Weiqi/style.css
index 54b9a40..85e5712 100644
--- a/variants/Weiqi/style.css
+++ b/variants/Weiqi/style.css
@@ -3,10 +3,10 @@
 }
 
 piece.white.stone {
-  background-image: url('/variants/Weiqi/pieces/black_stone.svg');
+  background-image: url('/pieces/Weiqi/black_stone.svg');
 }
 piece.black.stone, piece.white.stone.one-color {
-  background-image: url('/variants/Weiqi/pieces/white_stone.svg');
+  background-image: url('/pieces/Weiqi/white_stone.svg');
 }
 
 button.pass-btn {
diff --git a/variants/_Antiking/style.css b/variants/_Antiking/style.css
index cdbab55..6614062 100644
--- a/variants/_Antiking/style.css
+++ b/variants/_Antiking/style.css
@@ -1,8 +1,8 @@
 @import url("/base_pieces.css");
 
 piece.black.antiking {
-  background-image: url('/variants/_Antiking/pieces/black_antiking.svg');
+  background-image: url('/pieces/_Antiking/black_antiking.svg');
 }
 piece.white.antiking {
-  background-image: url('/variants/_Antiking/pieces/white_antiking.svg');
+  background-image: url('/pieces/_Antiking/white_antiking.svg');
 }
diff --git a/variants/_Berolina/style.css b/variants/_Berolina/style.css
index 4daa2c8..8a148c4 100644
--- a/variants/_Berolina/style.css
+++ b/variants/_Berolina/style.css
@@ -1,6 +1,6 @@
 piece.black.pawn {
-  background-image: url('/variants/_Berolina/pieces/black_pawn.svg');
+  background-image: url('/pieces/_Berolina/black_pawn.svg');
 }
 piece.white.pawn {
-  background-image: url('/variants/_Berolina/pieces/white_pawn.svg');
+  background-image: url('/pieces/_Berolina/white_pawn.svg');
 }
diff --git a/variants/_SpecialCaptures/class.js b/variants/_SpecialCaptures/class.js
index e6a0db1..0c2a300 100644
--- a/variants/_SpecialCaptures/class.js
+++ b/variants/_SpecialCaptures/class.js
@@ -112,7 +112,7 @@ export default class AbstractSpecialCaptureRules extends ChessRules {
         [i, j] = [i + step[0], this.getY(j + step[1])];
         while (this.onBoard(i, j) && this.board[i][j] == "") {
           let mv = this.getBasicMove([x, y], [i, j]);
-          Array.prorotype.push.apply(mv.vanish, vanished);
+          Array.prototype.push.apply(mv.vanish, vanished);
           moves.push(mv);
           [i, j] = [i + step[0], this.getY(j + step[1])];
         }
@@ -133,7 +133,7 @@ export default class AbstractSpecialCaptureRules extends ChessRules {
   getChameleonCaptures(moves, pushPullType, onlyOneJump) {
     const [x, y] = [moves[0].start.x, moves[0].start.y];
     moves = moves.concat(
-      this.getKnightCaptures([x, y], "asChameleon", onlyOneJump));
+      this.getLeaperCaptures([x, y], "asChameleon", onlyOneJump));
     // No "king capture" because king cannot remain under check
     this.addPincerCaptures(moves, "asChameleon");
     this.addCoordinatorCaptures(moves, "asChameleon");
@@ -177,8 +177,8 @@ export default class AbstractSpecialCaptureRules extends ChessRules {
     moves.forEach(m => {
       const [ex, ey] = [m.end.x, m.end.y];
       const step = [
-        ex != x ? (ex - x) / Math.abs(ex - x) : 0,
-        ey != y ? (ey - y) / Math.abs(ey - y) : 0
+        ex != sx ? (ex - sx) / Math.abs(ex - sx) : 0,
+        ey != sy ? (ey - sy) / Math.abs(ey - sy) : 0
       ];
       let vanishPull, vanishPush;
       if (type != "pull") {
@@ -194,7 +194,7 @@ export default class AbstractSpecialCaptureRules extends ChessRules {
         }
       }
       if (capturingPullDir[step[0] + "." + step[1]]) {
-        const [bi, bj] = [x - step[0], this.getY(y - step[1])];
+        const [bi, bj] = [sx - step[0], this.getY(sy - step[1])];
         vanishPull =
           new PiPo({x: bi, y: bj, p: this.getPiece(bi, bj), c: oppCol});
       }
diff --git a/variants/_SpecialCaptures/style.css b/variants/_SpecialCaptures/style.css
index 3360267..2a8c527 100644
--- a/variants/_SpecialCaptures/style.css
+++ b/variants/_SpecialCaptures/style.css
@@ -1,6 +1,6 @@
 .piece.white.push-action {
-  background-image: url('/variants/_SpecialCaptures/pieces/capture_push.svg');
+  background-image: url('/pieces/_SpecialCaptures/capture_push.svg');
 }
 .piece.white.pull-action {
-  background-image: url('/variants/_SpecialCaptures/pieces/capture_pull.svg');
+  background-image: url('/pieces/_SpecialCaptures/capture_pull.svg');
 }
-- 
2.44.0