}
     switch (this.getPiece(sq[0], sq[1])) {
       case V.PAWN: return this.getPotentialPawnMoves(sq);
+      case V.HEN: return this.getPotentialHenMoves(sq);
       case V.ELEPHANT: return this.getPotentialElephantMoves(sq);
       case V.GIRAFFE: return this.getPotentialGiraffeMoves(sq);
       case V.KING: return super.getPotentialKingMoves(sq);
     }
   }
 
+  getPotentialHenMoves([x, y]) {
+    const c = this.turn;
+    const forward = (c == 'w' ? -1 : 1);
+    const steps = V.steps[V.ROOK].concat([[forward, 1], [forward, -1]]);
+    return super.getSlideNJumpMoves(sq, steps, "oneStep");
+  }
+
   getPotentialElephantMoves(sq) {
     return super.getSlideNJumpMoves(sq, V.steps[V.BISHOP], "oneStep");
   }
 
--- /dev/null
+import { ChessRules } from "@/base_rules";
+
+// Pawns relayed by one square at a time (but with relaying pioece movements)
+// diff from https://www.chessvariants.com/rules/relay-chess ==> new name
+export class RelayupRules extends ChessRules {
+
+  static get PawnSpecs() {
+    return Object.assign(
+      {},
+      ChessRules.PawnSpecs,
+      { twoSquares: false }
+    );
+  }
+
+  static get HasFlags() {
+    return false;
+  }
+
+  static get HasEnpassant() {
+    return false;
+  }
+
+  getPotentialMovesFrom([x, y]) {
+    let moves = super.getPotentialMovesFrom([x, y]);
+
+    // Expand possible moves if guarded by friendly pieces:
+    // --> Pawns cannot be promoted through a relaying move (thus 8th rank forbidden)
+    // TODO
+
+    return moves;
+  }
+
+  getNotation(move) {
+    // Translate final and initial square
+    const initSquare = V.CoordsToSquare(move.start);
+    const finalSquare = V.CoordsToSquare(move.end);
+    const piece = this.getPiece(move.start.x, move.start.y);
+
+    // Since pieces and pawns could move like knight,
+    // indicate start and end squares
+    let notation =
+      piece.toUpperCase() +
+      initSquare +
+      (move.vanish.length > move.appear.length ? "x" : "") +
+      finalSquare
+
+    if (
+      piece == V.PAWN &&
+      move.appear.length > 0 &&
+      move.appear[0].p != V.PAWN
+    ) {
+      // Promotion
+      notation += "=" + move.appear[0].p.toUpperCase();
+    }
+
+    return notation;
+  }
+
+};