Fix counterstike against promoting Kirin
authorH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 7 Oct 2025 19:44:30 +0000 (21:44 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Wed, 8 Oct 2025 08:47:19 +0000 (10:47 +0200)
The ban on capturing Lion by non-Lion nonly applies to a Lion elsewhere,
never to recapturing a Kirin that captured a Lion and promoted in the process.
This exemption is now implemented by passing the capture square in
promoSuppress for Ky x Ln+, and testing that on a subsequent other x Ln.
This is harmless, as +Ky cannot promote anyway.

hachu.c

diff --git a/hachu.c b/hachu.c
index 430af97..6ab5442 100644 (file)
--- a/hachu.c
+++ b/hachu.c
@@ -10,7 +10,7 @@
 // promotions by pieces with Lion power stepping in & out the zone in same turn\r
 // promotion on capture\r
 \r
-#define VERSION "0.21"\r
+#define VERSION "0.21d"\r
 \r
 //define PATH level==0 || path[0] == 0x82906b &&  (level==1 || path[1] == 0x8790d9 && (level == 2 || path[2] == 0x8598ca && (level == 3 /*|| path[3] == 0x3e865 && (level == 4 || path[4] == 0x4b865 && (level == 5))*/)))\r
 #define PATH 0\r
@@ -377,6 +377,7 @@ PieceDesc makaPieces[] = {
   {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y\r
   {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U\r
   {"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K\r
+\r
   {"TK", "", 1300, { K,K,K,K,K,K,K,K }, 0, 6}, // Teaching King +I'\r
   {"BS", "", 1500, { S,S,S,S,S,S,S,S }, 0, 7}, // Budhist Spirit +J'\r
   {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N'\r
@@ -2311,9 +2312,12 @@ MapFromScratch(attacks); // for as long as incremental update does not work.
          if(dist[tb.from-tb.to] != 1 && attacks[2*tb.to + stm] && p[tb.epVictim[0]].value <= 50)\r
            score = -INF;                           // our Lion is indeed made vulnerable and can be recaptured\r
        } else {                                    // other x Ln\r
-         if(promoSuppress & PROMOTE) {             // non-Lion captures Lion after opponent did same\r
+         if(promoSuppress & PROMOTE &&             // previous move was also other x Lion\r
+            (promoSuppress & SQUARE) != tb.to) {    // but not made by a promoting Kirin\r
            if(!okazaki || attacks[2*tb.to + stm]) score = -INF;\r
          }\r
+          if(p[board[tb.to]].value == LVAL)         // the capturer promoted to Lion (and must have been a Kirin)\r
+            defer = tb.to;                          // exempt it from the counter-strike rule\r
          defer |= PROMOTE;                         // if we started, flag  he cannot do it in reply\r
        }\r
         if(score == -INF) {\r
@@ -2541,7 +2545,10 @@ MakeMove2 (int stm, MOVE move)
   FireSet(&undoInfo);\r
   sup0 = sup1; sup1 = sup2;\r
   sup2 = MakeMove(move, &undoInfo);\r
-  if(chuFlag && p[undoInfo.victim].value == LVAL && p[undoInfo.piece].value != LVAL) sup2 |= PROMOTE;\r
+  if(chuFlag && p[undoInfo.victim].value == LVAL && p[undoInfo.piece].value != LVAL) {\r
+    if(p[board[undoInfo.to]].value == LVAL) sup2 = undoInfo.to;\r
+    sup2 |= PROMOTE;\r
+  }\r
   rootEval = -rootEval - undoInfo.booty;\r
   for(i=0; i<200; i++) repStack[i] = repStack[i+1], checkStack[i] = checkStack[i+1];\r
 \r