Add Euro-Shogi
authorH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 20 Feb 2018 15:37:22 +0000 (16:37 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Tue, 20 Feb 2018 16:25:50 +0000 (17:25 +0100)
Adding the new variant Euro-Shogi required one new piece type, as the Knight
there also has a sideway step. This 'Euro-Knight' is added to the Shogi
pieces as an extra piece, so that the promo-codes and piece moves of Shogi
can be used. Only the IDs need to be different, as the N now stands for
Euro-Knight. The variant is added both under the name 'euroshogi' as
engine-defined variant, and 8x8+5_shogi.

dropper.c

index 93e3a7a..2cd7c92 100644 (file)
--- a/dropper.c
+++ b/dropper.c
@@ -232,12 +232,12 @@ InitCaptureCodes(signed char *codes)
             0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
     Wa:    SP OC LH SC SO CM BD FC FG VS VW SW FF RR CE Tr
            GB PO HH FF CE VS VW RF SW RB BE GS TF Tr    CK
-    Shogi:  P  N  B  R  L  S  R
-           +P +N  H  D +L +S                             K
+    Shogi:  P  L  S  G  B  R  N EN
+           +P +L +S  G DH DK +N+EN                       K
     Tori:   S Ph Cr Ql Qr Fa
             G             Ea                            Px
-    Chess:  P  N  B  R  A  C  Q
-           Q~ N~ B~ R~ A~ C~                             K
+    Chess:  P  N  B  R  Q
+           Q~ N~ B~ R~                                   K
  */
 
 unsigned char handSlot[97], rawBulk[98];
@@ -286,6 +286,8 @@ signed char steps[] = {
     -22,10, 21,1, 23,10, 0,0,  // bQr=209
     22,10, 21,1, 23,1, 1,1, -1,1, -22,10, 0,0,   // wRF=213
     -22,10, -21,1, -23,1, 1,1, -1,1, 22,10, 0,0, // bRF=220
+    1,1, -1,1, 43,1, 45,1, 0,0,                  // wEN=227
+    1,1, -1,1,-43,1,-45,1, 0,0,                  // wEN=232
 };
 
 // first direction in 'steps' table for the various piece types
@@ -294,7 +296,7 @@ signed char steps[] = {
 
 int
 chessValues[] = { 100, 285, 290, 375, 600, -1, 700, 310, 315, 450, -1, 150, 320, 305, 400, 600, -1 },
-shogiValues[]   = { 30, 150, 240, 270, 390, 450, 180, -1, 330, 288, 276, 270, 465, 540, 282, -1,  60, 270, 300, 330, 495, 570, 285, -1 },
+shogiValues[]   = { 30, 150, 240, 270, 390, 450, 180, 200, -1, 330, 288, 276, 270, 465, 540, 282, 279, -1,  60, 270, 300, 330, 495, 570, 285, 295, -1 },
 miniValues[]    = { 60, 110, 195, 237, 243, 330,      -1, 297, 245, 240, 237, 375, 420,      -1, 120, 200, 243, 252, 315, 390, -1 },
 judkinValues[]  = { 50, 115, 240, 270, 325, 390, 180, -1, 330, 245, 276, 270, 420, 480, 282, -1,  60, 220, 300, 330, 450, 510, 285, -1 },
 toriValues[]  = { 60, 100, 150, 150, 237, 300, -1, 90, 0, 0, 0, 0, 0, 500, -1, 65, 150, 200, 200, 300, 400, -1 },
@@ -304,17 +306,19 @@ waValues[]  = { 30, 210, 210, 180, 210, 210, 210, 240, 270, 160, 175, 270, 300,
 
 unsigned char
 chessDirs[] = { 40, 49, 4, 35, 26, 13, 255, 13, 4, 35, 26, 255, 40, 53, 4, 35, 26, 13, 255, 13, 4, 35, 26, 255 }, // K,P,N,B,R,Q / Q~,N~,B~,R~
-shogiDirs[] = { 40, 69, 97, 87, 57, 35, 26, 186, 255, 57, 57, 57, 57, 31, 22, 57, 255,   // K,P,S,G,B,R,L,N / +P,+S,-,DH,DK,+N,+L
-               40, 62, 94, 43, 64, 35, 26, 10, 255, 64, 64, 64, 64, 31, 22, 64, 255 },
+shogiDirs[] = { 40, 69, 97, 87, 57, 35, 26, 186, 227, 255, 57, 57, 57, 57, 31, 22, 57, 57, 255,   // K,P,L,S,G,B,R,N / +P,+L,+S,-,DH,DK,+N
+               40, 62, 94, 43, 64, 35, 26, 10, 232, 255, 64, 64, 64, 64, 31, 22, 64, 57, 255 },
 toriDirs[]  = { 40, 69, 189, 197, 201, 42, 79, 255, 112, 0, 0, 0, 0, 168, 255,   // Ph, S, Pt, Ql, Qr, Cr, Fa / G - - - - Ea
                 40, 62, 193, 205, 209, 42, 71, 255, 108, 0, 0, 0, 0, 177, 255 },
 waDirs[] = { 40, 69, 97, 67, 67, 74, 59, 59, 73, 87, 57, 96, 116, 121, 135, 99, 150, 255, // CK,SP,SC,SO,FC,CM,FG,BD,VS,VW,OC,LH,SW,RR,FF,Tr,CE 
                  57, 40,135,150,213, 87,116, 57, 79, 40,  8,  26,  99, 141, 255,          //    GB,FF,CE,RF,VS,SW,VW,RB,BE,PO,HH,GS,Tr,TF
              40, 62, 94, 60, 60, 82, 66, 66, 81, 43, 64, 93, 116, 128,  34, 99, 159, 255,
-                 64, 40, 34,159,220, 43,116, 64, 71, 40,  8,  26,  99, 141, 255 },
+                 64, 40, 34,159,220, 43,116, 64, 71, 40,  8,  26,  99, 141, 255 };
 
+char
 chessIDs[] = "PNBRQ",
 shogiIDs[] = "PLSGBRN",
+euroIDs[]  = "PLSGBR?N",
 toriIDs[]  = "SPLRCF",
 waIDs[]    = "POULCMGDVWHSRFXE",
 
@@ -324,7 +328,7 @@ toriFEN[]  = "rpckcpl/3f3/sssssss/2s1S2/SSSSSSS/3F3/LPCKCPR w",
 waFEN[]    = "hmlcvkwgudo/1e3s3f1/ppprpppxppp/3p3p3/11/11/11/3P3P3/PPPXPPPRPPP/1F3S3E1/ODUGWKVCLMH w",
 miniFEN[]  = "rbsgk/4p/5/P4/KGSBR w",
 judkinFEN[]= "rbnsgk/5p/6/6/P5/KGSNBR w",
-euroFEN[]  = "r w",
+euroFEN[]  = "1nbgkgn1/1r4b1/pppppppp/8/8/PPPPPPPP/1B4R1/1NGKGBN1 w",
 
 // promotion codes for unpromoted pieces. Will be ANDed with Z_WHITE or Z_BLACK to fill promoCode[] table
 
@@ -336,17 +340,19 @@ euroFEN[]  = "r w",
 #define Z_DOUBLE 0x80   /* where Pawns have double step */
 
 chessProms[16] = { Z_MUST },
-shogiProms[16] = { Z_MUST, Z_2ND, COLOR, 0, Z_MUST, Z_MUST, Z_2ND },
+shogiProms[16] = { Z_MUST, Z_2ND, COLOR, 0, Z_MUST, Z_MUST, Z_2ND, Z_2ND },
 toriProms[16]  = { Z_MUST, 0, 0, 0, 0, Z_MUST },
 waProms[16]    = { Z_MUST, Z_2ND, Z_MUST, Z_MUST, Z_MUST, COLOR, COLOR, Z_MUST, Z_MUST, Z_MUST, COLOR, Z_MUST, COLOR, Z_MUST };
 
-int lances[] = { 1, 3, 0103, 0103, 3, 3, 1 }; // bitmap indicating piece types with drop restriction (LSB = Pawn) in various variants
+int lances[] = { 1, 3, 0103, 0103, 1, 1, 3, 3, 1 }; // bitmap indicating piece types with drop restriction (LSB = Pawn) in various variants
 
 char *betza[] = { // piece defs for sending to GUI
   NULL, // suppresses setup command
   "",
   "",
   NULL,
+  ",N& fNsW,+P& WfF,+N WfF",
+  NULL,
   ",P& fW,L& fWbF,U& fWbF,C& fFsW,G& fFvW,M& fFvW,D& fFbsW,V& FfW,W& WfF,O& fR,H& fRbW2,S& sRvW,F& BfW,E& vRfF3bFsW,R& fRFbW,X& FAvWvD"
   ",+P& WfF,+L& vRfF3bFsW,+U& BfW,+C& vRfFsW,+G& sRvW,+M& FfW,+D& WfF,+V& FfsW,+W& K,+O& K,+H& vN,+S& R,+F& BvRsW,+R& FAvWvD",
   NULL,
@@ -358,6 +364,8 @@ char *ptc[] = { // XBoard 4.9 piece-to-char table
   "P.BR.S...G.+.++.+Kp.br.s...g.+.++.+k",
   "PNBR.S...G.++++.+Kpnbr.s...g.++++.+k",
   NULL,
+  "PNBR.....G.++++Kpnbr.....g.++++k",
+  NULL,
   "P..^S^FV..^LW^OH.F.^R.E....R...D.GOL^M..^H.M.C.^CU.^W../.......^V.^P.^U..^DS.^GXK"
   "p..^s^fv..^lw^oh.f.^r.e....r...d.gol^m..^h.m.c.^cu.^w../.......^v.^p.^u..^ds.^gxk",
    NULL,
@@ -369,6 +377,8 @@ char *pstType[] = {
   "307716 777718",
   "3077160 7777187",
   "3077160 7777187",
+  "30771607 77771877",
+  "30771607 77771877",
   "3055676777060100 77100787777801",
   "3055676777060100 77100787777801",
   "770076 100001"
@@ -387,12 +397,14 @@ VariantDesc variants[] = {
   {  5,  5,  5, 1, "minishogi\n",   shogiIDs, miniFEN,   shogiDirs, shogiProms, shogiCodes, miniValues },
   {  6,  6,  6, 2, "judkinshogi\n", shogiIDs, judkinFEN, shogiDirs, shogiProms, shogiCodes, judkinValues },
   {  9,  9,  7, 3, "shogi\n",       shogiIDs, shogiFEN,  shogiDirs, shogiProms, shogiCodes, shogiValues },
+  {  8,  8,  5, 3, "euroshogi\n",   euroIDs,  euroFEN,   shogiDirs, shogiProms, shogiCodes, shogiValues }, 
+  {  8,  8,  5, 3, "8x8+5_shogi\n", euroIDs,  euroFEN,   shogiDirs, shogiProms, shogiCodes, shogiValues }, 
   { 11, 11, 16, 3, "crazywa\n",     waIDs,    waFEN,     waDirs,    waProms,    shogiCodes, waValues    }, 
   { 11, 11, 16, 3, "11x17+16_chu\n",waIDs,    waFEN,     waDirs,    waProms,    shogiCodes, waValues    }, 
   {  7,  7,  6, 2, "torishogi\n",   toriIDs,  toriFEN,   toriDirs,  toriProms,  toriCodes,  toriValues  },
 };
 
-#define TORI_NR 6 /* must correspond to index of torishogi (which must be last) in table above! */
+#define TORI_NR 8 /* must correspond to index of torishogi (which must be last) in table above! */
 #define KNIGHTLESS 4 /* first variant without a Knight (except mini-, which has no 2-rank zone) */
 
 // info per piece type. sometimes indexed by negated holdings count instead of piece
@@ -468,8 +480,8 @@ GameInit (char *name)
     nrFiles = variants[v].files;
     nrRanks = variants[v].ranks;
     zone    = variants[v].zone;
-    maxDrop = variants[v].hand - 1;
     pieces  = variants[v].pieces;
+    maxDrop = variants[v].hand - (pieces != euroIDs); // in Euro-Shogi the normal Shogi Knight is present as dummy (unused) piece
     moves   = variants[v].dirs;
     startPos= variants[v].fen;
     codes   = variants[v].proms;
@@ -478,7 +490,7 @@ GameInit (char *name)
     perpLoses = v; // this works for now, as only zh allows perpetuals
 
     if((p = betza[v])) { // configure GUI for this variant
-       printf("setup (%s) %dx%d+%d_%s %s 0 1", ptc[v], nrFiles, nrRanks, maxDrop+1, (v == 4 ? "chu" : "shogi"), startPos);
+       printf("setup (%s) %dx%d+%d_%s %s 0 1", ptc[v], nrFiles, nrRanks, maxDrop+1, (pieces == waIDs ? "chu" : "shogi"), startPos);
        while(*p) { if(*p == ',') printf("\npiece "); else printf("%c", *p); p++; }
        printf("\n");
     }