From 3f02c0b84e29979405064a927952a21bd2427045 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 27 Apr 2016 21:41:45 +0200 Subject: [PATCH 01/16] Make resistant to empty lines An empty line (emitted by XBoard due to a bug) made HaChu repeat the previous command. Now the GetLine routine keeps reading until it gets a non-empty line. --- hachu.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hachu.c b/hachu.c index 7c672d4..bb26721 100644 --- a/hachu.c +++ b/hachu.c @@ -2792,8 +2792,10 @@ printf("# setup done");fflush(stdout); int i, c; while(1) { // wait for input, and read it until we have collected a complete line - for(i = 0; (inBuf[i] = c = getchar()) != '\n'; i++) if(c == EOF || i>7997) exit(0); - inBuf[i+1] = 0; + do { + for(i = 0; (inBuf[i] = c = getchar()) != '\n'; i++) if(c == EOF || i>7997) exit(0); + inBuf[i+1] = 0; + } while(!i); // ignore empty lines // extract the first word sscanf(inBuf, "%s", command); -- 1.7.0.4 From 5f5b735b63d617cfd573cff651f59187df23ae84 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Thu, 28 Apr 2016 21:31:27 +0200 Subject: [PATCH 02/16] Let Setup accept nubers for stretches of empty squares The routine for setting up the start position is mare more FEN-reader-like. --- hachu.c | 44 ++++++++++++++++++++++++-------------------- 1 files changed, 24 insertions(+), 20 deletions(-) diff --git a/hachu.c b/hachu.c index bb26721..ae5a8d5 100644 --- a/hachu.c +++ b/hachu.c @@ -470,26 +470,26 @@ PieceDesc wolfPieces[] = { { NULL } // sentinel }; -char chuArray[] = "L:FLCSGK:DEGSC:FLL/:RV.B.:BT:KN:PH:BT.B.:RV/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/PPPPPPPPPPPP/...:GB....:GB..." - "/............/............/" - "...:gb....:gb.../pppppppppppp/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/:rv.b.:bt:ph:kn:bt.b.:rv/l:flcsg:dekgsc:fll"; -char daiArray[] = "LN:STICSGKGSCI:STNL/:RV.:CS.:FL.:BT:DE:BT.:FL.:CS.:RV/.:VO.:AB.:EW:KN:LN:PH:EW.:AB.:VO./R:FD:SM:VMB:DH:DK:FK:DK:DHB:VM:SM:FDR" - "/PPPPPPPPPPPPPPP/....:GB.....:GB..../.............../.............../.............../....:gb.....:gb..../ppppppppppppppp/" - "r:fd:sm:vmb:dh:dk:fk:dk:dhb:vm:sm:fdr/.:vo.:ab.:ew:ph:ln:kn:ew.:ab.:vo./:rv.:cs.:fl.:bt:de:bt.:fl.:cs.:rv/ln:sticsgkgsci:stnl"; -char tenArray[] = "LN:FLICSGK:DEGSCI:FLNL/:RV.:CS:CS.:BT:KN:LN:FK:PH:BT.:CS:CS.:RV/:SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/" - ":SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/PPPPPPPPPPPPPPPP/....D......D..../" - "................/................/................/................/" - "....d......d..../pppppppppppppppp/:sm:vmr:hf:se:bg:rg:vg:gg:rg:bg:se:hfr:vm:sm/" - ":ss:vsb:dh:dk:wb:fi:fe:lh:fi:wb:dk:dhb:vs:ss/:rv.:cs:cs.:bt:ph:fk:ln:kn:bt.:cs:cs.:rv/ln:flicsg:dekgsci:flnl"; -char shoArray[] = "LNSGKGSNL/.B..:DE..R./PPPPPPPPP/........./........./........./ppppppppp/.r..:de..b./lnsgkgsnl"; -char waArray[] = ":PH:DKCG:EWK:VML:KN:SM:DH/.:FL...S...:DE./PPP:BTPPPRPPP/...P...P..." - "/.........../.........../..........." - "/...p...p.../ppprppp:btppp/.:de...s...:fl./:dh:sm:knl:vmk:ewgc:dk:ph"; -char chessArray[] = "RNB:FKKBNR/PPPPPPPP/......../......../......../......../pppppppp/rnb:fkkbnr"; -char lionArray[] = "R:LNB:FKKBNR/PPPPPPPP/......../......../......../......../pppppppp/r:lnb:fkkbnr"; -char shatArray[]= "RNBK:FKBNR/PPPPPPPP/......../......../......../......../pppppppp/rnbk:fkbnr"; -char thaiArray[]= "RNSK:SMSNR/......../PPPPPPPP/......../......../pppppppp/......../rns:smksnr"; -char wolfArray[]= "RNB:EWKBNR/PPPPPPPP/......../......../......../......../pppppppp/rnb:ewkbnr"; +char chuArray[] = "L:FLCSGK:DEGSC:FLL/:RV1B1:BT:KN:PH:BT1B1:RV/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/PPPPPPPPPPPP/3:GB4:GB3" + "/12/12/" + "3:gb4:gb3/pppppppppppp/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/:rv1b1:bt:ph:kn:bt1b1:rv/l:flcsg:dekgsc:fll"; +char daiArray[] = "LN:STICSGKGSCI:STNL/:RV1:CS1:FL1:BT:DE:BT1:FL1:CS1:RV/1:VO1:AB1:EW:KN:LN:PH:EW1:AB1:VO1/R:FD:SM:VMB:DH:DK:FK:DK:DHB:VM:SM:FDR" + "/PPPPPPPPPPPPPPP/4:GB5:GB4/15/15/15/4:gb5:gb4/ppppppppppppppp/" + "r:fd:sm:vmb:dh:dk:fk:dk:dhb:vm:sm:fdr/1:vo1:ab1:ew:ph:ln:kn:ew1:ab1:vo1/:rv1:cs1:fl1:bt:de:bt1:fl1:cs1:rv/ln:sticsgkgsci:stnl"; +char tenArray[] = "LN:FLICSGK:DEGSCI:FLNL/:RV1:CS:CS1:BT:KN:LN:FK:PH:BT1:CS:CS1:RV/:SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/" + ":SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/PPPPPPPPPPPPPPPP/4D6D4/" + "16/16/16/16/" + "4d6d4/pppppppppppppppp/:sm:vmr:hf:se:bg:rg:vg:gg:rg:bg:se:hfr:vm:sm/" + ":ss:vsb:dh:dk:wb:fi:fe:lh:fi:wb:dk:dhb:vs:ss/:rv1:cs:cs1:bt:ph:fk:ln:kn:bt1:cs:cs1:rv/ln:flicsg:dekgsci:flnl"; +char shoArray[] = "LNSGKGSNL/1B2:DE2R1/PPPPPPPPP/9/9/9/ppppppppp/1r2:de2b1/lnsgkgsnl"; +char waArray[] = ":PH:DKCG:EWK:VML:KN:SM:DH/1:FL3S3:DE1/PPP:BTPPPRPPP/3P3P3" + "/11/11/11" + "/3p3p3/ppprppp:btppp/1:de3s3:fl1/:dh:sm:knl:vmk:ewgc:dk:ph"; +char chessArray[] = "RNB:FKKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnb:fkkbnr"; +char lionArray[] = "R:LNB:FKKBNR/PPPPPPPP/8/8/8/8/pppppppp/r:lnb:fkkbnr"; +char shatArray[]= "RNBK:FKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbk:fkbnr"; +char thaiArray[]= "RNSK:SMSNR/8/PPPPPPPP/8/8/pppppppp/8/rns:smksnr"; +char wolfArray[]= "RNB:EWKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnb:ewkbnr"; typedef struct { int boardWidth, boardFiles, boardRanks, zoneDepth, varNr; // board sizes @@ -881,6 +881,10 @@ SetUp (char *array, int var) c = name[0] = *array++; if(!c) goto eos; if(c == '.') continue; + if(c > '0' && c <= '9') { + c -= '0'; if(*array >= '0' && *array <= '9') c = 10*c + *array++ - '0'; + j += c - 1; continue; + } if(c == '/') break; name[1] = name[2] = 0; if(c == ':') name[0] = *array++, name[1] = *array++; -- 1.7.0.4 From da5de4076c01b3b194dd25a115f02819c54d3e86 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Thu, 28 Apr 2016 21:57:17 +0200 Subject: [PATCH 03/16] Invert storage of initial positions The initial positions are now stored high-rank to low-rank, rather than starting with rank 0, and the Setup routine scans the board accordingly. This to make Setup more like a FEN reader. The setboard command is broken by this. --- hachu.c | 38 +++++++++++++++++++------------------- 1 files changed, 19 insertions(+), 19 deletions(-) diff --git a/hachu.c b/hachu.c index ae5a8d5..98b776e 100644 --- a/hachu.c +++ b/hachu.c @@ -470,26 +470,26 @@ PieceDesc wolfPieces[] = { { NULL } // sentinel }; -char chuArray[] = "L:FLCSGK:DEGSC:FLL/:RV1B1:BT:KN:PH:BT1B1:RV/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/PPPPPPPPPPPP/3:GB4:GB3" +char chuArray[] = "l:flcsg:dekgsc:fll/:rv1b1:bt:ph:kn:bt1b1:rv/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/pppppppppppp/3:gb4:gb3" "/12/12/" - "3:gb4:gb3/pppppppppppp/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/:rv1b1:bt:ph:kn:bt1b1:rv/l:flcsg:dekgsc:fll"; -char daiArray[] = "LN:STICSGKGSCI:STNL/:RV1:CS1:FL1:BT:DE:BT1:FL1:CS1:RV/1:VO1:AB1:EW:KN:LN:PH:EW1:AB1:VO1/R:FD:SM:VMB:DH:DK:FK:DK:DHB:VM:SM:FDR" - "/PPPPPPPPPPPPPPP/4:GB5:GB4/15/15/15/4:gb5:gb4/ppppppppppppppp/" - "r:fd:sm:vmb:dh:dk:fk:dk:dhb:vm:sm:fdr/1:vo1:ab1:ew:ph:ln:kn:ew1:ab1:vo1/:rv1:cs1:fl1:bt:de:bt1:fl1:cs1:rv/ln:sticsgkgsci:stnl"; -char tenArray[] = "LN:FLICSGK:DEGSCI:FLNL/:RV1:CS:CS1:BT:KN:LN:FK:PH:BT1:CS:CS1:RV/:SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/" - ":SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/PPPPPPPPPPPPPPPP/4D6D4/" + "3:GB4:GB3/PPPPPPPPPPPP/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/:RV1B1:BT:KN:PH:BT1B1:RV/L:FLCSGK:DEGSC:FLL"; +char daiArray[] = "ln:sticsgkgsci:stnl/:rv1:cs1:fl1:bt:de:bt1:fl1:cs1:rv/1:vo1:ab1:ew:ph:ln:kn:ew1:ab1:vo1/r:fd:sm:vmb:dh:dk:fk:dk:dhb:vm:sm:fdr/" + "ppppppppppppppp/4:gb5:gb4/15/15/15/4:GB5:GB4/PPPPPPPPPPPPPPP/" + "R:FD:SM:VMB:DH:DK:FK:DK:DHB:VM:SM:FDR/1:VO1:AB1:EW:KN:LN:PH:EW1:AB1:VO1/:RV1:CS1:FL1:BT:DE:BT1:FL1:CS1:RV/LN:STICSGKGSCI:STNL"; +char tenArray[] = "ln:flicsg:dekgsci:flnl/:rv1:cs:cs1:bt:ph:fk:ln:kn:bt1:cs:cs1:rv/:ss:vsb:dh:dk:wb:fi:fe:lh:fi:wb:dk:dhb:vs:ss/" + ":sm:vmr:hf:se:bg:rg:vg:gg:rg:bg:se:hfr:vm:sm/pppppppppppppppp/4d6d4/" "16/16/16/16/" - "4d6d4/pppppppppppppppp/:sm:vmr:hf:se:bg:rg:vg:gg:rg:bg:se:hfr:vm:sm/" - ":ss:vsb:dh:dk:wb:fi:fe:lh:fi:wb:dk:dhb:vs:ss/:rv1:cs:cs1:bt:ph:fk:ln:kn:bt1:cs:cs1:rv/ln:flicsg:dekgsci:flnl"; -char shoArray[] = "LNSGKGSNL/1B2:DE2R1/PPPPPPPPP/9/9/9/ppppppppp/1r2:de2b1/lnsgkgsnl"; -char waArray[] = ":PH:DKCG:EWK:VML:KN:SM:DH/1:FL3S3:DE1/PPP:BTPPPRPPP/3P3P3" - "/11/11/11" - "/3p3p3/ppprppp:btppp/1:de3s3:fl1/:dh:sm:knl:vmk:ewgc:dk:ph"; -char chessArray[] = "RNB:FKKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnb:fkkbnr"; -char lionArray[] = "R:LNB:FKKBNR/PPPPPPPP/8/8/8/8/pppppppp/r:lnb:fkkbnr"; -char shatArray[]= "RNBK:FKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbk:fkbnr"; -char thaiArray[]= "RNSK:SMSNR/8/PPPPPPPP/8/8/pppppppp/8/rns:smksnr"; -char wolfArray[]= "RNB:EWKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnb:ewkbnr"; + "4D6D4/PPPPPPPPPPPPPPPP/:SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/" + ":SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/:RV1:CS:CS1:BT:KN:LN:FK:PH:BT1:CS:CS1:RV/LN:FLICSGK:DEGSCI:FLNL"; +char shoArray[] = "lnsgkgsnl/1r2:de2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2:DE2R1/LNSGKGSNL"; +char waArray[] = ":dh:sm:knl:vmk:ewgc:dk:ph/1:de3s3:fl1/ppprppp:btppp/3p3p3" + "/11/11/11/" + "3P3P3/PPP:BTPPPRPPP/1:FL3S3:DE1/:PH:DKCG:EWK:VML:KN:SM:DH"; +char chessArray[] = "rnb:fkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB:FKKBNR"; +char lionArray[] = "r:lnb:fkkbnr/pppppppp/8/8/8/8/PPPPPPPP/R:LNB:FKKBNR"; +char shatArray[]= "rnbk:fkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBK:FKBNR"; +char thaiArray[]= "rns:smksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSK:SMSNR"; +char wolfArray[]= "rnb:ewkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB:EWKBNR"; typedef struct { int boardWidth, boardFiles, boardRanks, zoneDepth, varNr; // board sizes @@ -873,7 +873,7 @@ SetUp (char *array, int var) PieceDesc *p1, *p2; last[WHITE] = 1; last[BLACK] = 0; royal[WHITE] = royal[BLACK] = 0; - for(i=0; ; i++) { + for(i=BH-1; ; i--) { //printf("next rank: %s\n", array); for(j = BW*i; ; j++) { int pflag=0; -- 1.7.0.4 From 19fc5120d78955064a134be3abf658cd62e97e96 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 3 May 2016 12:21:48 +0200 Subject: [PATCH 04/16] Add translation tables for dressed-letter piece IDs Tables for translating the dressed-letter IDs of XBoard 4.9 are added, on a per-variant basis. The names of the pieces in the description tables are adapted to this in some places. --- hachu.c | 243 ++++++++++++++++++++++++++++++++++----------------------------- 1 files changed, 132 insertions(+), 111 deletions(-) diff --git a/hachu.c b/hachu.c index 98b776e..341fa4a 100644 --- a/hachu.c +++ b/hachu.c @@ -247,81 +247,81 @@ PieceDesc daiPieces[] = { {"AB", "G", 60, { 1,0,1,0,1,0,1,0 }, 1 }, // Angry Boar {"I", "G", 80, { 1,1,0,0,0,0,0,1 }, 2 }, // Iron {"N", "G", 60, { N,0,0,0,0,0,0,N }, 0 }, // Knight - {"ST", "G", 50, { 0,1,0,0,0,0,0,1 }, 0 }, // Stone + {"SG", "G", 50, { 0,1,0,0,0,0,0,1 }, 0 }, // Stone { NULL } // sentinel }; PieceDesc waPieces[] = { {"TE", "", 720, { X,X,1,X,X,X,1,X }, 4 }, // Tenacious Falcon {"GS", "", 500, { X,0,X,0,X,0,X,0 }, 4 }, // Gliding Swallow (R) - {"DE", "", 430, { X,3,1,1,X,1,1,3 }, 3 }, // Cloud Eagle + {"CE", "", 430, { X,3,1,1,X,1,1,3 }, 3 }, // Cloud Eagle {"K", "", 410, { 1,1,1,1,1,1,1,1 }, 2 }, // Crane King (K) - {"BT", "", 390, { I,I,0,I,I,I,0,I }, 4 }, // Treacherous Fox - {"FL", "TE", 380, { 1,X,0,X,0,X,0,X }, 4 }, // Flying Falcon - {"FS", "", 290, { X,1,1,0,X,0,1,1 }, 3 }, // Raiding Falcon - {"S", "GS", 260, { 1,0,X,0,1,0,X,0 }, 6 }, // Swallow's Wing (SM) + {"TF", "", 390, { I,I,0,I,I,I,0,I }, 4 }, // Treacherous Fox + {"FF", "TE", 380, { 1,X,0,X,0,X,0,X }, 4 }, // Flying Falcon + {"RF", "", 290, { X,1,1,0,X,0,1,1 }, 3 }, // Raiding Falcon + {"SW", "GS", 260, { 1,0,X,0,1,0,X,0 }, 6 }, // Swallow's Wing (SM) {"PO", "", 260, { 1,1,1,1,1,1,1,1 }, 2 }, // Plodding Ox (K) - {"R", "BT", 260, { X,1,0,1,1,1,0,1 }, 2 }, // Running Rabit - {"B", "", 240, { 1,1,1,1,0,1,1,1 }, 2 }, // Roaming Boar + {"RR", "TF", 260, { X,1,0,1,1,1,0,1 }, 2 }, // Running Rabit + {"RB", "", 240, { 1,1,1,1,0,1,1,1 }, 2 }, // Roaming Boar {"HH", "", 220, { N,0,0,N,N,0,0,N }, 1 }, // Heavenly Horse - {"EW", "PO", 220, { 1,1,1,0,1,0,1,1 }, 2 }, // Violent Wolf (G) - {"VM", "B", 200, { 1,1,0,1,0,1,0,1 }, 2 }, // Violent Stag (S) - {"G", "S", 190, { 1,1,0,0,1,0,0,1 }, 2 }, // Flying Goose (C) - {"SM", "VM", 175, { 1,1,0,0,1,0,0,1 }, 2 }, // Climbing Monkey (C) - {"DH", "HH", 170, { X,0,0,0,2,0,0,0 }, 1 }, // Liberated Horse - {"DK", "EW", 150, { 0,1,1,0,1,0,1,1 }, 2 }, // Blind Dog - {"PH", "PO", 150, { X,0,0,0,0,0,0,0 }, 1 }, // Oxcart (L) - {"L", "FS", 130, { 0,1,1,0,0,0,1,1 }, 2 }, // Flying Cock - {"KN", "DE", 115, { 1,0,0,1,0,1,0,0 }, 2 }, // Swooping Owl - {"C", "FL", 105, { 1,0,0,1,0,1,0,0 }, 2 }, // Strutting Crow - {"P", "EW", 80, { 1,0,0,0,0,0,0,0 }, 2 }, // Sparrow Pawn (P) + {"VW", "PO", 220, { 1,1,1,0,1,0,1,1 }, 2 }, // Violent Wolf (G) + {"VS", "RB", 200, { 1,1,0,1,0,1,0,1 }, 2 }, // Violent Stag (S) + {"FG", "SW" 190, { 1,1,0,0,1,0,0,1 }, 2 }, // Flying Goose (C) + {"CM", "VS", 175, { 1,1,0,0,1,0,0,1 }, 2 }, // Climbing Monkey (C) + {"LH", "HH", 170, { X,0,0,0,2,0,0,0 }, 1 }, // Liberated Horse + {"BD", "VW", 150, { 0,1,1,0,1,0,1,1 }, 2 }, // Blind Dog + {"OC", "PO", 150, { X,0,0,0,0,0,0,0 }, 1 }, // Oxcart (L) + {"FC", "RF", 130, { 0,1,1,0,0,0,1,1 }, 2 }, // Flying Cock + {"SO", "CE", 115, { 1,0,0,1,0,1,0,0 }, 2 }, // Swooping Owl + {"SC", "FF", 105, { 1,0,0,1,0,1,0,0 }, 2 }, // Strutting Crow + {"P", "GB", 80, { 1,0,0,0,0,0,0,0 }, 2 }, // Sparrow Pawn (P) { NULL } // sentinel }; PieceDesc ddPieces[] = { - {"LO", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin - {"OK", "LO", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite - {"PS", "HM", 10, { J,0,1,J,0,J,1,0 } }, // Poisonous Snake - {"GE", "", 10, { 3,3,5,5,3,5,5,3 } }, // Great Elephant - {"WS", "LD", 10, { 1,1,2,0,1,0,2,1 } }, // Western Barbarian - {"EA", "LN", 10, { 2,1,1,0,2,0,1,1 } }, // Eastern Barbarian - {"NO", "FE", 10, { 0,2,1,1,0,1,1,2 } }, // Northern Barbarian - {"SO", "WE", 10, { 0,1,1,2,0,2,1,1 } }, // Southern Barbarian - {"FE", "", 10, { 2,X,2,2,2,2,2,X } }, // Fragrant Elephant - {"WE", "", 10, { 2,2,2,X,2,X,2,2 } }, // White Elephant - {"FT", "", 10, { X,X,5,0,X,0,5,X } }, // Free Dream-Eater - {"FR", "", 10, { 5,X,X,0,5,0,X,X } }, // Free Demon - {"WB", "FT", 10, { 2,X,X,X,2,X,X,X } }, // Water Buffalo - {"RB", "FR", 10, { X,X,X,X,0,X,X,X } }, // Rushing Bird - {"SB", "", 10, { X,X,2,2,2,2,2,X } }, // Standard Bearer - - {"FH", "FK", 10, { 1,2,1,0,1,0,1,2 } }, // Flying Horse - {"NK", "SB", 10, { 1,1,1,1,1,1,1,1 } }, // Neighbor King + {"LO", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin G! + {"OK", "LO", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite K' + {"PS", "HM", 10, { J,0,1,J,0,J,1,0 } }, // Poisonous Snake S' + {"GE", "", 10, { 3,3,5,5,3,5,5,3 } }, // Great Elephant +W! + {"WS", "LD", 10, { 1,1,2,0,1,0,2,1 } }, // Western Barbarian W' + {"EA", "LN", 10, { 2,1,1,0,2,0,1,1 } }, // Eastern Barbarian E' + {"NO", "FE", 10, { 0,2,1,1,0,1,1,2 } }, // Northern Barbarian N' + {"SO", "WE", 10, { 0,1,1,2,0,2,1,1 } }, // Southern Barbarian S' + {"FE", "", 10, { 2,X,2,2,2,2,2,X } }, // Fragrant Elephant +N' + {"WE", "", 10, { 2,2,2,X,2,X,2,2 } }, // White Elephant +S' + {"FT", "", 10, { X,X,5,0,X,0,5,X } }, // Free Dream-Eater +W + {"FR", "", 10, { 5,X,X,0,5,0,X,X } }, // Free Demon +U + {"WB", "FT", 10, { 2,X,X,X,2,X,X,X } }, // Water Buffalo W + {"RU", "FR", 10, { X,X,X,X,0,X,X,X } }, // Rushing Bird U + {"SB", "", 10, { X,X,2,2,2,2,2,X } }, // Standard Bearer +N + + {"FH", "FK", 10, { 1,2,1,0,1,0,1,2 } }, // Flying Horse H' + {"NK", "SB", 10, { 1,1,1,1,1,1,1,1 } }, // Neighbor King N {"BM", "MW", 10, { 0,1,1,1,0,1,1,1 } }, // Blind Monkey {"DO", "", 10, { 2,X,2,X,2,X,2,X } }, // Dove - {"EB", "DO", 10, { 2,0,2,0,0,0,2,0 } }, // Enchanted Badger - {"EF", "SD", 10, { 0,2,0,0,2,0,0,2 } }, // Enchanted Fox - {"RA", "", 10, { X,0,X,1,X,1,X,0 } }, // Racing Chariot - {"SQ", "", 10, { X,1,X,0,X,0,X,1 } }, // Square Mover + {"EB", "DO", 10, { 2,0,2,0,0,0,2,0 } }, // Enchanted Badger B' + {"EF", "SD", 10, { 0,2,0,0,2,0,0,2 } }, // Enchanted Fox X' + {"RA", "", 10, { X,0,X,1,X,1,X,0 } }, // Racing Chariot A + {"SQ", "", 10, { X,1,X,0,X,0,X,1 } }, // Square Mover Q' {"PR", "SQ", 10, { 1,1,2,1,0,1,2,1 } }, // Prancing Stag - {"WT", "", 10, { X,1,2,0,X,0,2,X } }, // White Tiger - {"BD", "", 10, { 2,X,X,0,2,0,X,1 } }, // Blue Dragon - {"HD", "", 10, { X,0,0,0,1,0,0,0 } }, // Howling Dog - {"VB", "", 10, { 0,2,1,0,0,0,1,2 } }, // Violent Bear - {"SA", "", 10, { 2,1,0,0,2,0,0,1 } }, // Savage Tiger - {"W", "", 10, { 0,2,0,0,0,0,0,2 } }, // Wood - {"CS", "DH", 70, { 0,1,0,1,0,1,0,1 } }, // cat sword - {"FD", "DK", 150, { 0,2,0,2,0,2,0,2 } }, // flying dragon - {"KN", "GD", 150, { J,1,J,1,J,1,J,1 } }, // kirin - {"PH", "GB", 150, { 1,J,1,J,1,J,1,J } }, // phoenix - {"LN", "FF", 1000, { L,L,L,L,L,L,L,L } }, // lion - {"LD", "GE", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog - {"AB", "", 10, { 1,0,1,0,1,0,1,0 } }, // Angry Boar - {"B", "", 10, { 0,X,0,X,0,X,0,X } }, // Bishop - {"C", "", 10, { 1,1,0,0,1,0,0,1 } }, // Copper - {"DH", "", 10, { 1,X,1,X,1,X,1,X } }, // Dragon Horse - {"DK", "", 10, { X,1,X,1,X,1,X,1 } }, // Dragon King - {"FK", "", 10, { } }, // + {"WT", "", 10, { X,1,2,0,X,0,2,X } }, // White Tiger T! + {"BD", "", 10, { 2,X,X,0,2,0,X,1 } }, // Blue Dragon D! + {"HD", "", 10, { X,0,0,0,1,0,0,0 } }, // Howling Dog D' + {"VB", "", 10, { 0,2,1,0,0,0,1,2 } }, // Violent Bear V + {"ST", "", 10, { 2,1,0,0,2,0,0,1 } }, // Savage Tiger T' + {"W", "", 10, { 0,2,0,0,0,0,0,2 } }, // Wood General V' + {"CS", "DH", 70, { 0,1,0,1,0,1,0,1 } }, // Cat Sword C' + {"FD", "DK", 150, { 0,2,0,2,0,2,0,2 } }, // Flying Dragon F' + {"KN", "GD", 150, { J,1,J,1,J,1,J,1 } }, // Kirin O + {"PH", "GB", 150, { 1,J,1,J,1,J,1,J } }, // Phoenix X + {"LN", "FF", 1000, { L,L,L,L,L,L,L,L } }, // lion L! + {"LD", "GE", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! + {"AB", "", 10, { 1,0,1,0,1,0,1,0 } }, // Angry Boar A' + {"B", "", 10, { 0,X,0,X,0,X,0,X } }, // Bishop B + {"C", "", 10, { 1,1,0,0,1,0,0,1 } }, // Copper C + {"DH", "", 10, { 1,X,1,X,1,X,1,X } }, // Dragon Horse H + {"DK", "", 10, { X,1,X,1,X,1,X,1 } }, // Dragon King D + {"FK", "", 10, { } }, // Free King Q {"EW", "", 10, { 1,1,1,0,0,0,1,1 } }, // Evil Wolf {"FL", "", 10, { } }, // {"", "", 10, { } }, // @@ -331,38 +331,41 @@ PieceDesc ddPieces[] = { { NULL } // sentinel }; +char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BT..VMEWPH...." // L + "ABBBCS FDGB DVDS OM OR STT VOWR " // L' + " CP HM LN LD "; // L! PieceDesc makaPieces[] = { - {"DV", "", 10, { 0,1,0,1,0,0,1,1 } }, // Deva - {"DS", "", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit - {"T", "", 10, { 0,1,0,0,1,0,0,1 } }, // Tile - {"CS", "", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent - {"RD", "", 10, { 1,0,1,1,1,1,1,0 } }, // Reclining Dragon - {"CC", "", 10, { 0,1,1,0,1,0,1,1 } }, // Chinese Cock - {"OM", "", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey - {"BB", "", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear - {"OR", "", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat - {"LD", "WS", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog - {"WR", "", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler - {"GG", "", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods - {"BD", "", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil - {"SD", "", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil - {"DY", "", 10, { J,0,1,0,J,0,1,0 } }, // Donkey - {"CP", "", 10, { 0,H,0,2,0,2,0,H } }, // Capricorn - {"HM", "", 10, { H,0,H,0,H,0,H,0 } }, // Hook Mover - {"SF", "", 10, { 0,1,X,1,0,1,0,1 } }, // Side Flier - {"LC", "", 10, { X,0,0,X,1,0,0,X } }, // Left Chariot - {"RC", "", 10, { X,X,0,0,1,X,0,0 } }, // Right Chariot - {"FG", "", 10, { X,X,X,0,X,0,X,X } }, // Free Gold - {"FS", "", 10, { X,X,0,X,0,X,0,X } }, // Free Silver - {"FC", "", 10, { X,X,0,0,X,0,0,X } }, // Free Copper - {"FI", "", 10, { X,X,0,0,0,0,0,X } }, // Free Iron - {"FT", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile - {"FN", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone - {"FTg", "", 10, { 0,X,X,X,X,X,X,X } }, // Free Tiger - {"FLp", "", 10, { X,X,0,X,X,X,0,X } }, // Free Leopard (Free Boar?) - {"FSp", "", 10, { X,0,0,X,X,X,0,0 } }, // Free Serpent (Whale?) - {"FrD", "", 10, { X,0,X,X,X,X,X,0 } }, // Free Dragon - {"FC", "", 10, { 0,X,0,X,0,X,0,X } }, // Free Cat (Bishop?) + {"DV", "TK", 10, { 0,1,0,1,0,0,1,1 } }, // Deva + {"DS", "BS", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit + {"T", "fT", 10, { 0,1,0,0,1,0,0,1 } }, // Tile General + {"CS", "fS", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent + {"RD", "fD", 10, { 1,0,1,1,1,1,1,0 } }, // Reclining Dragon + {"CC", "WS", 10, { 0,1,1,0,1,0,1,1 } }, // Chinese Cock + {"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey + {"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear + {"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat + {"LD", "WS", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! + {"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler + {"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods + {"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil + {"SD", "G", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil + {"DY", "G", 10, { J,0,1,0,J,0,1,0 } }, // Donkey + {"CA", "G", 10, { 0,H,0,2,0,2,0,H } }, // Capricorn C! + {"HM", "G", 10, { H,0,H,0,H,0,H,0 } }, // Hook Mover H! + {"SF", "G", 10, { 0,1,X,1,0,1,0,1 } }, // Side Flier + {"LC", "G", 10, { X,0,0,X,1,0,0,X } }, // Left Chariot L! + {"RC", "G", 10, { X,X,0,0,1,X,0,0 } }, // Right Chariot R! + {"fG", "", 10, { X,X,X,0,X,0,X,X } }, // Free Gold + {"fS", "", 10, { X,X,0,X,0,X,0,X } }, // Free Silver + {"WH", "", 10, { X,X,0,0,X,0,0,X } }, // Free Copper + {"fI", "", 10, { X,X,0,0,0,0,0,X } }, // Free Iron + {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile + {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone + {"fT", "", 10, { 0,X,X,X,X,X,X,X } }, // Free Tiger + {"fL", "", 10, { X,X,0,X,X,X,0,X } }, // Free Leopard (Free Boar?) + {"WL", "", 10, { X,0,0,X,X,X,0,0 } }, // Free Serpent (Whale?) + {"fD", "", 10, { X,0,X,X,X,X,X,0 } }, // Free Dragon + {"B", "", 10, { 0,X,0,X,0,X,0,X } }, // Free Cat (Bishop?) {"EM", "", 10, { } }, // Emperor {"TK", "", 10, { } }, // Teaching King {"BS", "", 10, { } }, // Budhist Spirit @@ -371,9 +374,9 @@ PieceDesc makaPieces[] = { {"FF", "", 10, { } }, // Furious Fiend {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon {"GB", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird - {"FrW", "", 10, { } }, // Free Wolf - {"FrB", "", 10, { } }, // Free Bear - {"BT", "", 10, { X,0,0,X,0,X,0,0 } }, // Bat + {"fW", "", 10, { } }, // Free Wolf + {"fB", "", 10, { } }, // Free Bear + {"BA", "", 10, { X,0,0,X,0,X,0,0 } }, // Bat {"", "", 10, { } }, // { NULL } // sentinel }; @@ -420,48 +423,48 @@ PieceDesc taikyokuPieces[] = { }; PieceDesc chessPieces[] = { - {"FK", "", 950, { X,X,X,X,X,X,X,X } }, + {"Q", "", 950, { X,X,X,X,X,X,X,X } }, {"R", "", 500, { X,0,X,0,X,0,X,0 } }, {"B", "", 320, { 0,X,0,X,0,X,0,X } }, {"N", "", 300, { N,N,N,N,N,N,N,N } }, {"K", "", 280, { 1,1,1,1,1,1,1,1 } }, - {"P", "FK", 80, { M,C,0,0,0,0,0,C } }, + {"P", "Q", 80, { M,C,0,0,0,0,0,C } }, { NULL } // sentinel }; PieceDesc lionPieces[] = { - {"LN","", LVAL, { L,L,L,L,L,L,L,L } }, - {"FK", "", 600, { X,X,X,X,X,X,X,X } }, + {"L", "", LVAL, { L,L,L,L,L,L,L,L } }, + {"Q", "", 600, { X,X,X,X,X,X,X,X } }, {"R", "", 300, { X,0,X,0,X,0,X,0 } }, {"K", "", 280, { 1,1,1,1,1,1,1,1 } }, {"B", "", 190, { 0,X,0,X,0,X,0,X } }, {"N", "", 180, { N,N,N,N,N,N,N,N } }, - {"P", "FK", 50, { M,C,0,0,0,0,0,C } }, + {"P", "Q", 50, { M,C,0,0,0,0,0,C } }, { NULL } // sentinel }; PieceDesc shatranjPieces[] = { - {"FK", "", 150, { 0,1,0,1,0,1,0,1 } }, + {"F", "", 150, { 0,1,0,1,0,1,0,1 } }, {"R", "", 500, { X,0,X,0,X,0,X,0 } }, - {"B", "", 90, { 0,J,0,J,0,J,0,J } }, + {"E", "", 90, { 0,J,0,J,0,J,0,J } }, {"N", "", 300, { N,N,N,N,N,N,N,N } }, {"K", "", 280, { 1,1,1,1,1,1,1,1 } }, - {"P", "FK", 80, { M,C,0,0,0,0,0,C } }, + {"P", "F", 80, { M,C,0,0,0,0,0,C } }, { NULL } // sentinel }; PieceDesc makrukPieces[] = { - {"SM","", 150, { 0,1,0,1,0,1,0,1 } }, + {"M", "", 150, { 0,1,0,1,0,1,0,1 } }, {"R", "", 500, { X,0,X,0,X,0,X,0 } }, {"S", "", 200, { 1,1,0,1,0,1,0,1 } }, // silver {"N", "", 300, { N,N,N,N,N,N,N,N } }, {"K", "", 280, { 1,1,1,1,1,1,1,1 } }, - {"P", "SM", 80, { M,C,0,0,0,0,0,C } }, + {"P", "M", 80, { M,C,0,0,0,0,0,C } }, { NULL } // sentinel }; PieceDesc wolfPieces[] = { - {"EW","EW",1050,{ W,W,W,W,W,W,W,W }, 6, 5 }, // kludge to get extra Werewolves + {"W", "W",1050,{ W,W,W,W,W,W,W,W }, 6, 5 }, // kludge to get extra Werewolves {"R", "", 500, { X,0,X,0,X,0,X,0 }, 3 }, {"B", "", 320, { 0,X,0,X,0,X,0,X }, 1 }, {"N", "", 300, { N,N,N,N,N,N,N,N }, 1 }, @@ -482,14 +485,32 @@ char tenArray[] = "ln:flicsg:dekgsci:flnl/:rv1:cs:cs1:bt:ph:fk:ln:kn:bt1:cs:cs1: "4D6D4/PPPPPPPPPPPPPPPP/:SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/" ":SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/:RV1:CS:CS1:BT:KN:LN:FK:PH:BT1:CS:CS1:RV/LN:FLICSGK:DEGSCI:FLNL"; char shoArray[] = "lnsgkgsnl/1r2:de2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2:DE2R1/LNSGKGSNL"; -char waArray[] = ":dh:sm:knl:vmk:ewgc:dk:ph/1:de3s3:fl1/ppprppp:btppp/3p3p3" +char waArray[] = ":lh:cm:so:fc:vsk:vw:fg:sc:bd:oc/1:ce3:sw3:ff1/ppp:rrppp:tfppp/3p3p3" "/11/11/11/" - "3P3P3/PPP:BTPPPRPPP/1:FL3S3:DE1/:PH:DKCG:EWK:VML:KN:SM:DH"; -char chessArray[] = "rnb:fkkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB:FKKBNR"; -char lionArray[] = "r:lnb:fkkbnr/pppppppp/8/8/8/8/PPPPPPPP/R:LNB:FKKBNR"; -char shatArray[]= "rnbk:fkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBK:FKBNR"; -char thaiArray[]= "rns:smksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSK:SMSNR"; -char wolfArray[]= "rnb:ewkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB:EWKBNR"; + "3P3P3/PPP:TFPPP:RRPPP/1:FF3:SW3:CE1/:OC:BD:SC:FG:VWK:VS:FC:SO:CM:LH"; +char chessArray[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"; +char lionArray[] = "rlbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RLBQKBNR"; +char shatArray[]= "rnekfenr/pppppppp/8/8/8/8/PPPPPPPP/RNEKFENR"; +char thaiArray[]= "rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR"; +char wolfArray[]= "rnbwkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBWKBNR"; + +// translation tables for single-(dressed-)letter IDs to multi-letter names, per variant +// A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z. +char chuIDs[] = "RVB C DKDEFLG DHGB..K L SMLNKYP FKR S BT..VM..PH...."; +char daiIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BTSGVMEWPH...." // L + "AB CS FD GB VO " // L' + " LN "; // L! +char tenIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BT..VM..PH...." // L + ".. ..D .. SS VS " // L' + " BGCSFISEHFGGLH LN FERG VGWB "; // L! +char waIDs[] = "....FCBDCEFFFGLH....K SOBM..OCP ..RRSW..SCVSVWTF...."; +char chessIDs[] = "A B ....E F ........K L M N ..P Q R S ......W ......"; // covers all chess-like variants +char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BTSG..EWPHT .." // L (also for Macadamia) + "ABBBCSBDE FDGG DVDS LCBMCCORGB RCSD WRVODY " // L' + " CARD HM LN CO VMLD "; // L! +char dadaIDs[] = "RVB C DKEFFLG DHI ..K L SMNKKYP FKR S ..SGVBEWPH...." // L (also for Cashew) + "ABEBCSHDEBFDPRFHLGRGOKLCOMNBORPS RCSBST W WBVO " // L' + "RAWB BD GOHM LN SQ WTRUVMLD "; // L! typedef struct { int boardWidth, boardFiles, boardRanks, zoneDepth, varNr; // board sizes -- 1.7.0.4 From bb7d13f947c5c7459b41d011806e2d9fae4b0594 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 3 May 2016 14:45:26 +0200 Subject: [PATCH 05/16] Change Setup routine to read (dressed) 1-letter piece IDs The Setup routine now processes the XBoard FEN format, and the start- position strings are changed accordingly. --- hachu.c | 95 +++++++++++++++++++++++++++++++-------------------------------- 1 files changed, 47 insertions(+), 48 deletions(-) diff --git a/hachu.c b/hachu.c index 341fa4a..44a6de2 100644 --- a/hachu.c +++ b/hachu.c @@ -160,7 +160,7 @@ typedef struct { char fireMask; } UndoInfo; -char *array, fenArray[4000], startPos[4000], *reason, checkStack[300]; +char *array, *IDs, fenArray[4000], startPos[4000], *reason, checkStack[300]; int bWidth, bHeight, bsize, zone, currentVariant, chuFlag, tenFlag, chessFlag, repDraws, stalemate; int tsume, pvCuts, allowRep, entryProm, okazaki, pVal; int stm, xstm, hashKeyH=1, hashKeyL=1, framePtr, msp, nonCapts, rootEval, filling, promoDelta; @@ -266,7 +266,7 @@ PieceDesc waPieces[] = { {"HH", "", 220, { N,0,0,N,N,0,0,N }, 1 }, // Heavenly Horse {"VW", "PO", 220, { 1,1,1,0,1,0,1,1 }, 2 }, // Violent Wolf (G) {"VS", "RB", 200, { 1,1,0,1,0,1,0,1 }, 2 }, // Violent Stag (S) - {"FG", "SW" 190, { 1,1,0,0,1,0,0,1 }, 2 }, // Flying Goose (C) + {"FG", "SW", 190, { 1,1,0,0,1,0,0,1 }, 2 }, // Flying Goose (C) {"CM", "VS", 175, { 1,1,0,0,1,0,0,1 }, 2 }, // Climbing Monkey (C) {"LH", "HH", 170, { X,0,0,0,2,0,0,0 }, 1 }, // Liberated Horse {"BD", "VW", 150, { 0,1,1,0,1,0,1,1 }, 2 }, // Blind Dog @@ -274,7 +274,7 @@ PieceDesc waPieces[] = { {"FC", "RF", 130, { 0,1,1,0,0,0,1,1 }, 2 }, // Flying Cock {"SO", "CE", 115, { 1,0,0,1,0,1,0,0 }, 2 }, // Swooping Owl {"SC", "FF", 105, { 1,0,0,1,0,1,0,0 }, 2 }, // Strutting Crow - {"P", "GB", 80, { 1,0,0,0,0,0,0,0 }, 2 }, // Sparrow Pawn (P) + {"P", "VW", 80, { 1,0,0,0,0,0,0,0 }, 2 }, // Sparrow Pawn (P) { NULL } // sentinel }; @@ -331,9 +331,6 @@ PieceDesc ddPieces[] = { { NULL } // sentinel }; -char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BT..VMEWPH...." // L - "ABBBCS FDGB DVDS OM OR STT VOWR " // L' - " CP HM LN LD "; // L! PieceDesc makaPieces[] = { {"DV", "TK", 10, { 0,1,0,1,0,0,1,1 } }, // Deva {"DS", "BS", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit @@ -444,12 +441,12 @@ PieceDesc lionPieces[] = { }; PieceDesc shatranjPieces[] = { - {"F", "", 150, { 0,1,0,1,0,1,0,1 } }, + {"Q", "", 150, { 0,1,0,1,0,1,0,1 } }, {"R", "", 500, { X,0,X,0,X,0,X,0 } }, - {"E", "", 90, { 0,J,0,J,0,J,0,J } }, + {"B", "", 90, { 0,J,0,J,0,J,0,J } }, {"N", "", 300, { N,N,N,N,N,N,N,N } }, {"K", "", 280, { 1,1,1,1,1,1,1,1 } }, - {"P", "F", 80, { M,C,0,0,0,0,0,C } }, + {"P", "Q", 80, { M,C,0,0,0,0,0,C } }, { NULL } // sentinel }; @@ -473,42 +470,40 @@ PieceDesc wolfPieces[] = { { NULL } // sentinel }; -char chuArray[] = "l:flcsg:dekgsc:fll/:rv1b1:bt:ph:kn:bt1b1:rv/:sm:vmr:dh:dk:fk:ln:dk:dhr:vm:sm/pppppppppppp/3:gb4:gb3" +char chuArray[] = "lfcsgekgscfl/a1b1txot1b1a/mvrhdqndhrvm/pppppppppppp/3i4i3" "/12/12/" - "3:GB4:GB3/PPPPPPPPPPPP/:SM:VMR:DH:DK:LN:FK:DK:DHR:VM:SM/:RV1B1:BT:KN:PH:BT1B1:RV/L:FLCSGK:DEGSC:FLL"; -char daiArray[] = "ln:sticsgkgsci:stnl/:rv1:cs1:fl1:bt:de:bt1:fl1:cs1:rv/1:vo1:ab1:ew:ph:ln:kn:ew1:ab1:vo1/r:fd:sm:vmb:dh:dk:fk:dk:dhb:vm:sm:fdr/" - "ppppppppppppppp/4:gb5:gb4/15/15/15/4:GB5:GB4/PPPPPPPPPPPPPPP/" - "R:FD:SM:VMB:DH:DK:FK:DK:DHB:VM:SM:FDR/1:VO1:AB1:EW:KN:LN:PH:EW1:AB1:VO1/:RV1:CS1:FL1:BT:DE:BT1:FL1:CS1:RV/LN:STICSGKGSCI:STNL"; -char tenArray[] = "ln:flicsg:dekgsci:flnl/:rv1:cs:cs1:bt:ph:fk:ln:kn:bt1:cs:cs1:rv/:ss:vsb:dh:dk:wb:fi:fe:lh:fi:wb:dk:dhb:vs:ss/" - ":sm:vmr:hf:se:bg:rg:vg:gg:rg:bg:se:hfr:vm:sm/pppppppppppppppp/4d6d4/" + "3I4I3/PPPPPPPPPPPP/MVRHDNQDHRVM/A1B1TOXT1B1A/LFCSGKEGSCFL"; +char daiArray[] = "lnuicsgkgsciunl/a1c'1f1tet1f1c'1a/1x'1a'1wxl!ow1a'1x'1/rf'mvbhdqdhbvmf'r/" + "ppppppppppppppp/4p'5p'4/15/15/15/4P'5P'4/PPPPPPPPPPPPPPP/" + "RF'MVBHDQDHBVMF'R/1X'1A'1WOL!XW1A'1X'1/A1C'1F1TET1F1C'1A/LNUICSGKGSCIUNL"; +char tenArray[] = "lnficsgekgscifnl/a1c!c!1txql!ot1c!c!1a/s'v'bhdw!d!q!h!d!w!dhbv's'/" + "mvrf!e!b!r!v!q!r!b!e!f!rvm/pppppppppppppppp/4d6d4/" "16/16/16/16/" - "4D6D4/PPPPPPPPPPPPPPPP/:SM:VMR:HF:SE:BG:RG:GG:VG:RG:BG:SE:HFR:VM:SM/" - ":SS:VSB:DH:DK:WB:FI:LH:FE:FI:WB:DK:DHB:VS:SS/:RV1:CS:CS1:BT:KN:LN:FK:PH:BT1:CS:CS1:RV/LN:FLICSGK:DEGSCI:FLNL"; -char shoArray[] = "lnsgkgsnl/1r2:de2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2:DE2R1/LNSGKGSNL"; -char waArray[] = ":lh:cm:so:fc:vsk:vw:fg:sc:bd:oc/1:ce3:sw3:ff1/ppp:rrppp:tfppp/3p3p3" - "/11/11/11/" - "3P3P3/PPP:TFPPP:RRPPP/1:FF3:SW3:CE1/:OC:BD:SC:FG:VWK:VS:FC:SO:CM:LH"; + "4D6D4/PPPPPPPPPPPPPPPP/MVRF!E!B!R!Q!V!R!B!E!F!RVM/" + "S'V'BHDW!D!H!Q'D!W!DHBV'S'/A1C!C!TOL!QXT1C!C!1A/LNFICSGKEGSCIFNL"; +char shoArray[] = "lnsgkgsnl/1r2e2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2E2R1/LNSGKGSNL"; +char waArray[] = "hmlcvkwgudo/1e3s3f1/ppprpppxppp/3p3p3/11/11/11/3P3P3/PPPXPPPRPPP/1F3S3E1/ODUGWKVCLMH"; char chessArray[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"; char lionArray[] = "rlbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RLBQKBNR"; -char shatArray[]= "rnekfenr/pppppppp/8/8/8/8/PPPPPPPP/RNEKFENR"; -char thaiArray[]= "rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR"; -char wolfArray[]= "rnbwkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBWKBNR"; +char shatArray[] = "rnbkqbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBKQBNR"; +char thaiArray[] = "rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR"; +char wolfArray[] = "rnbwkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBWKBNR"; // translation tables for single-(dressed-)letter IDs to multi-letter names, per variant // A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z. -char chuIDs[] = "RVB C DKDEFLG DHGB..K L SMLNKYP FKR S BT..VM..PH...."; -char daiIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BTSGVMEWPH...." // L +char chuIDs[] = "RVB C DKDEFLG DHGB..K L SMLNKNP FKR S BT..VM..PH...."; +char daiIDs[] = "RVB C DKDEFLG DHI ..K L SMN KNP FKR S BTSGVMEWPH...." // L "AB CS FD GB VO " // L' " LN "; // L! -char tenIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BT..VM..PH...." // L - ".. ..D .. SS VS " // L' - " BGCSFISEHFGGLH LN FERG VGWB "; // L! -char waIDs[] = "....FCBDCEFFFGLH....K SOBM..OCP ..RRSW..SCVSVWTF...."; +char tenIDs[] = "RVB C DKDEFLG DHI ..K L SMN KNP FKR S BT..VM..PH...." // L + ".. ..D .. FE SS VS " // L' + " BGCSFISEHF LH LN GGRG VGWB "; // L! +char waIDs[] = "....FCBDCEFFFGLH....K SOCM..OCP ..RRSW..SCVSVWTF...."; char chessIDs[] = "A B ....E F ........K L M N ..P Q R S ......W ......"; // covers all chess-like variants -char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KYP FKR S BTSG..EWPHT .." // L (also for Macadamia) +char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KNP FKR S BTSG..EWPHT .." // L (also for Macadamia) "ABBBCSBDE FDGG DVDS LCBMCCORGB RCSD WRVODY " // L' " CARD HM LN CO VMLD "; // L! -char dadaIDs[] = "RVB C DKEFFLG DHI ..K L SMNKKYP FKR S ..SGVBEWPH...." // L (also for Cashew) +char dadaIDs[] = "RVB C DKEFFLG DHI ..K L SMNKKNP FKR S ..SGVBEWPH...." // L (also for Cashew) "ABEBCSHDEBFDPRFHLGRGOKLCOMNBORPS RCSBST W WBVO " // L' "RAWB BD GOHM LN SQ WTRUVMLD "; // L! @@ -516,6 +511,7 @@ typedef struct { int boardWidth, boardFiles, boardRanks, zoneDepth, varNr; // board sizes char *name; // WinBoard name char *array; // initial position + char *IDs; } VariantDesc; typedef enum { V_CHESS, V_SHO, V_CHU, V_DAI, V_DADA, V_MAKA, V_TAI, V_KYOKU, V_TENJIKU, V_SHATRANJ, V_MAKRUK, V_LION, V_WA, V_WOLF } Variant; @@ -523,17 +519,17 @@ typedef enum { V_CHESS, V_SHO, V_CHU, V_DAI, V_DADA, V_MAKA, V_TAI, V_KYOKU, V_T #define SAME (-1) VariantDesc variants[] = { - { 24, 12, 12, 4, V_CHU, "chu", chuArray }, // Chu - { 16, 8, 8, 1, V_CHESS, "nocastle", chessArray }, // FIDE - { 18, 9, 9, 3, V_SHO, "9x9+0_shogi", shoArray }, // Sho - { 18, 9, 9, 3, V_SHO, "sho", shoArray }, // Sho duplicat - { 30, 15, 15, 5, V_DAI, "dai", daiArray }, // Dai - { 32, 16, 16, 5, V_TENJIKU, "tenjiku", tenArray }, // Tenjiku - { 16, 8, 8, 1, V_SHATRANJ,"shatranj",shatArray}, // Shatranj - { 16, 8, 8, 3, V_MAKRUK, "makruk", thaiArray}, // Makruk - { 16, 8, 8, 1, V_LION, "lion", lionArray}, // Mighty Lion - { 22, 11, 11, 3, V_WA, "wa-shogi",waArray}, // Wa - { 16, 8, 8, 1, V_WOLF, "werewolf",wolfArray}, // Wa + { 24, 12, 12, 4, V_CHU, "chu", chuArray, chuIDs }, // Chu + { 16, 8, 8, 1, V_CHESS, "nocastle", chessArray,chessIDs }, // FIDE + { 18, 9, 9, 3, V_SHO, "9x9+0_shogi", shoArray, chuIDs }, // Sho + { 18, 9, 9, 3, V_SHO, "sho", shoArray, chuIDs }, // Sho duplicat + { 30, 15, 15, 5, V_DAI, "dai", daiArray, daiIDs }, // Dai + { 32, 16, 16, 5, V_TENJIKU, "tenjiku", tenArray, tenIDs }, // Tenjiku + { 16, 8, 8, 1, V_SHATRANJ,"shatranj",shatArray, chessIDs}, // Shatranj + { 16, 8, 8, 3, V_MAKRUK, "makruk", thaiArray, chessIDs}, // Makruk + { 16, 8, 8, 1, V_LION, "lion", lionArray, chessIDs}, // Mighty Lion + { 22, 11, 11, 3, V_WA, "wa-shogi", waArray, waIDs}, // Wa + { 16, 8, 8, 1, V_WOLF, "werewolf",wolfArray, chessIDs}, // Wa { 0, 0, 0, 0, 0 }, // sentinel { 34, 17, 17, 0, V_DADA, "dada", chuArray }, // Dai Dai @@ -908,12 +904,14 @@ SetUp (char *array, int var) } if(c == '/') break; name[1] = name[2] = 0; - if(c == ':') name[0] = *array++, name[1] = *array++; - if(name[0] >= 'a') { + if(c >= 'a') { color = BLACK; - name[0] += 'A' - 'a'; - if(name[1]) name[1] += 'A' - 'a'; + c += 'A' - 'a'; } else color = WHITE; + if(*array == '\'') c += 26, array++; else + if(*array == '!') c += 52, array++; + name[0] = IDs[2*(c - 'A')]; + name[1] = IDs[2*(c - 'A') + 1]; if(name[1] == ' ') name[1] = 0; if(!strcmp(name, "CP") || pflag && !strcmp(name, "DE")) prince |= color+1; // remember if we added Crown Prince p1 = LookUp(name, var); if(!p1) printf("tellusererror Unknown piece '%s' in setup\n", name), exit(-1); @@ -1006,6 +1004,7 @@ Init (int var) bHeight = variants[var].boardRanks; zone = variants[var].zoneDepth; array = variants[var].array; + IDs = variants[var].IDs; } bsize = bWidth*bHeight; chuFlag = (currentVariant == V_CHU || currentVariant == V_LION); -- 1.7.0.4 From 352eb6489d6e32a7d7b7038075c7b01683719416 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 3 May 2016 15:24:34 +0200 Subject: [PATCH 06/16] Restore functionalyty of setboard command The conversion of FEN to internal position representation that had to take place when setting up a position through the 'setboard' command has now been removed, as the Setup routine can handle the FEN directly (complete with ID dressing). --- hachu.c | 49 +++++-------------------------------------------- 1 files changed, 5 insertions(+), 44 deletions(-) diff --git a/hachu.c b/hachu.c index 44a6de2..28bec4b 100644 --- a/hachu.c +++ b/hachu.c @@ -2475,61 +2475,22 @@ UnMake2 (MOVE move) sup2 = sup1; sup1 = sup0; } -char fenNames[] = "RV....DKDEFL..DHGB......SMLNKN..FK....BT..VMEWPH..LN"; // pairs of char -char fenPromo[] = "WLDHSMSECPB R HFDE....WHFB..LNG ..DKVMFS..FO..FK...."; // pairs of char - -char * -Convert (char *fen) -{ - char *p = fenArray, *q, *rows[36], tmp[4000]; - int n=0; - printf("# convert FEN '%s'\n", fen); - q = strchr(fen, ' '); if(q) *q = 0; q = fen; - do { rows[n++] = q; q = strchr(q, '/'); if(!q) break; *q++ = 0; } while(1); - *tmp = 0; - while(--n >= 0) { strcat(tmp, rows[n]); if(n) strcat(tmp, "/"); } - fen = tmp; - printf("# flipped FEN '%s'\n", fen); - while(*fen) { - if(*fen == ' ') { *p = 0; break; } - if(n=atoi(fen)) fen++; // digits read - if(n > 9) fen++; // double digit - while(n-- > 0) *p++ = '.'; // expand to empty squares - if(currentVariant == V_LION && (*fen == 'L' || *fen == 'l')) *fen += 'Z' - 'L'; // L in Mighty-Lion Chess changed in Z for Lion - if(isalpha(*fen)) { - char *table = fenNames; - n = *fen > 'Z' ? 'a' - 'A' : 0; - if((currentVariant == V_CHESS || currentVariant == V_SHATRANJ || currentVariant == V_LION || currentVariant == V_WOLF || - currentVariant == V_MAKRUK || currentVariant == V_SHO) && *fen - n == 'N' // In Chess N is Knight, not Lion - || table[2* (*fen - 'A' - n)] == '.') *p++ = *fen; else { - *p++ = ':'; - *p++ = table[2* (*fen - 'A' - n)] + n; - *p++ = table[2* (*fen - 'A' - n)+1] + n; - } - } else *p++ = *fen; - if(!*fen) break; - fen++; - } - *p = '\0'; - printf("# converted FEN '%s'\n", fenArray); - return fenArray; -} - int Setup2 (char *fen) { + char *p; int stm = WHITE; + static char startFEN[4000]; if(fen) { char *q = strchr(fen, '\n'); if(q) *q = 0; if(q = strchr(fen, ' ')) stm = (q[1] == 'b' ? BLACK : WHITE); // fen contains color field - if(strchr(fen, '.') || strchr(fen, ':')) array = fen; else array = Convert(fen); - } + } else fen = array; rootEval = promoDelta = filling = cnt50 = moveNr = 0; - SetUp(array, currentVariant); - strcpy(startPos, array); + SetUp(fen, currentVariant); sup0 = sup1 = sup2 = ABSENT; hashKeyH = hashKeyL = 87620895*currentVariant + !!fen; + for(p=startPos; *p++ = *fen++; ) {} // remember last start position for undo return stm; } -- 1.7.0.4 From f30bd184a7f34faa34b14684ddb32555429ebcbf Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 3 May 2016 21:34:27 +0200 Subject: [PATCH 07/16] Add Teaching-King moves, and complete (Maka) Dai Dai piece lists A new move type slide + LD is implemented, with code K. --- hachu.c | 185 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 117 insertions(+), 68 deletions(-) diff --git a/hachu.c b/hachu.c index 28bec4b..147eda7 100644 --- a/hachu.c +++ b/hachu.c @@ -179,13 +179,14 @@ Move retMove, moveStack[20000], path[100], repStack[300], pv[1000], repeatMove[3 #define I -3 /* jump + step */ #define D -4 /* linear double move */ #define T -5 /* linear triple move */ -#define L -6 /* true Lion move */ -#define W -7 /* Werewolf move */ -#define F -8 /* Lion + 3-step */ -#define S -9 /* Lion + range */ -#define H -10 /* hook move */ -#define C -11 /* capture only */ -#define M -12 /* non-capture only */ +#define K -6 /* triple + range */ +#define L -7 /* true Lion move */ +#define W -8 /* Werewolf move */ +#define F -9 /* Lion + 3-step */ +#define S -10 /* Lion + range */ +#define H -11 /* hook move */ +#define C -12 /* capture only */ +#define M -13 /* non-capture only */ #define LVAL 1000 /* piece value of Lion. Used in chu for recognizing it to implement Lion-trade rules */ #define FVAL 5000 /* piece value of Fire Demon. Used in code for recognizing moves with it and do burns */ @@ -279,8 +280,8 @@ PieceDesc waPieces[] = { }; PieceDesc ddPieces[] = { - {"LO", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin G! - {"OK", "LO", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite K' + {"LG", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin G! + {"OK", "LG", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite K' {"PS", "HM", 10, { J,0,1,J,0,J,1,0 } }, // Poisonous Snake S' {"GE", "", 10, { 3,3,5,5,3,5,5,3 } }, // Great Elephant +W! {"WS", "LD", 10, { 1,1,2,0,1,0,2,1 } }, // Western Barbarian W' @@ -294,11 +295,10 @@ PieceDesc ddPieces[] = { {"WB", "FT", 10, { 2,X,X,X,2,X,X,X } }, // Water Buffalo W {"RU", "FR", 10, { X,X,X,X,0,X,X,X } }, // Rushing Bird U {"SB", "", 10, { X,X,2,2,2,2,2,X } }, // Standard Bearer +N - {"FH", "FK", 10, { 1,2,1,0,1,0,1,2 } }, // Flying Horse H' {"NK", "SB", 10, { 1,1,1,1,1,1,1,1 } }, // Neighbor King N {"BM", "MW", 10, { 0,1,1,1,0,1,1,1 } }, // Blind Monkey - {"DO", "", 10, { 2,X,2,X,2,X,2,X } }, // Dove + {"DO", "", 10, { 2,5,2,5,2,5,2,5 } }, // Dove {"EB", "DO", 10, { 2,0,2,0,0,0,2,0 } }, // Enchanted Badger B' {"EF", "SD", 10, { 0,2,0,0,2,0,0,2 } }, // Enchanted Fox X' {"RA", "", 10, { X,0,X,1,X,1,X,0 } }, // Racing Chariot A @@ -312,68 +312,101 @@ PieceDesc ddPieces[] = { {"W", "", 10, { 0,2,0,0,0,0,0,2 } }, // Wood General V' {"CS", "DH", 70, { 0,1,0,1,0,1,0,1 } }, // Cat Sword C' {"FD", "DK", 150, { 0,2,0,2,0,2,0,2 } }, // Flying Dragon F' - {"KN", "GD", 150, { J,1,J,1,J,1,J,1 } }, // Kirin O - {"PH", "GB", 150, { 1,J,1,J,1,J,1,J } }, // Phoenix X - {"LN", "FF", 1000, { L,L,L,L,L,L,L,L } }, // lion L! {"LD", "GE", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! - {"AB", "", 10, { 1,0,1,0,1,0,1,0 } }, // Angry Boar A' - {"B", "", 10, { 0,X,0,X,0,X,0,X } }, // Bishop B - {"C", "", 10, { 1,1,0,0,1,0,0,1 } }, // Copper C - {"DH", "", 10, { 1,X,1,X,1,X,1,X } }, // Dragon Horse H - {"DK", "", 10, { X,1,X,1,X,1,X,1 } }, // Dragon King D - {"FK", "", 10, { } }, // Free King Q - {"EW", "", 10, { 1,1,1,0,0,0,1,1 } }, // Evil Wolf - {"FL", "", 10, { } }, // - {"", "", 10, { } }, // - {"", "", 10, { } }, // + {"AB", "", 10, { 1,0,1,0,1,0,1,0 } }, // Angry Boar A' + {"EW", "", 10, { 1,1,1,0,0,0,1,1 } }, // Evil Wolf + {"SD", "", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil + {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon + {"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird + // Chu pieces (but with different promotion) + {"LN", "FF",LVAL, { L,L,L,L,L,L,L,L }, 4 }, // lion + {"FK", "", 600, { X,X,X,X,X,X,X,X }, 4 }, // free king + {"DK", "", 400, { X,1,X,1,X,1,X,1 }, 4 }, // dragon king + {"DH", "", 350, { 1,X,1,X,1,X,1,X }, 4 }, // dragon horse + {"R", "", 300, { X,0,X,0,X,0,X,0 }, 4 }, // rook + {"K", "", 280, { 1,1,1,1,1,1,1,1 }, 2, 4 }, // king + {"B", "", 250, { 0,X,0,X,0,X,0,X }, 2 }, // bishop + {"VM", "", 200, { X,0,1,0,X,0,1,0 }, 2 }, // vertical mover + {"SM", "", 200, { 1,0,X,0,1,0,X,0 }, 6 }, // side mover + {"G", "", 151, { 1,1,1,0,1,0,1,1 }, 2 }, // gold + {"FL", "", 150, { 1,1,0,1,1,1,0,1 }, 2 }, // ferocious leopard + {"KN", "GD", 154, { J,1,J,1,J,1,J,1 }, 2 }, // kirin + {"PH", "GO", 153, { 1,J,1,J,1,J,1,J }, 2 }, // phoenix + {"RV", "", 150, { X,0,0,0,X,0,0,0 }, 1 }, // reverse chariot + {"L", "", 150, { X,0,0,0,0,0,0,0 }, 1 }, // lance + {"S", "", 100, { 1,1,0,1,0,1,0,1 }, 2 }, // silver + {"C", "", 100, { 1,1,0,0,1,0,0,1 }, 2 }, // copper + {"P", "", 40, { 1,0,0,0,0,0,0,0 }, 2 }, // pawn {"", "", 10, { } }, // {"", "", 10, { } }, // { NULL } // sentinel }; PieceDesc makaPieces[] = { - {"DV", "TK", 10, { 0,1,0,1,0,0,1,1 } }, // Deva - {"DS", "BS", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit - {"T", "fT", 10, { 0,1,0,0,1,0,0,1 } }, // Tile General - {"CS", "fS", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent - {"RD", "fD", 10, { 1,0,1,1,1,1,1,0 } }, // Reclining Dragon - {"CC", "WS", 10, { 0,1,1,0,1,0,1,1 } }, // Chinese Cock - {"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey - {"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear - {"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat + {"DV", "TK", 10, { 0,1,0,1,0,0,1,1 } }, // Deva I' + {"DS", "BS", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit J' + {"T", "fT", 10, { 0,1,0,0,1,0,0,1 } }, // Tile General Y + {"CS", "fS", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent S! + {"RD", "fD", 10, { 1,0,1,1,1,1,1,0 } }, // Reclining Dragon D! + {"CC", "WS", 10, { 0,1,1,0,1,0,1,1 } }, // Chinese Cock N' + {"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey M' + {"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear B' + {"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat O' {"LD", "WS", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! - {"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler - {"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods - {"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil - {"SD", "G", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil - {"DY", "G", 10, { J,0,1,0,J,0,1,0 } }, // Donkey + {"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler W' + {"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods G' + {"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil D' + {"SD", "G", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil S' + {"DY", "G", 10, { J,0,1,0,J,0,1,0 } }, // Donkey Y' {"CA", "G", 10, { 0,H,0,2,0,2,0,H } }, // Capricorn C! {"HM", "G", 10, { H,0,H,0,H,0,H,0 } }, // Hook Mover H! - {"SF", "G", 10, { 0,1,X,1,0,1,0,1 } }, // Side Flier - {"LC", "G", 10, { X,0,0,X,1,0,0,X } }, // Left Chariot L! - {"RC", "G", 10, { X,X,0,0,1,X,0,0 } }, // Right Chariot R! - {"fG", "", 10, { X,X,X,0,X,0,X,X } }, // Free Gold - {"fS", "", 10, { X,X,0,X,0,X,0,X } }, // Free Silver - {"WH", "", 10, { X,X,0,0,X,0,0,X } }, // Free Copper - {"fI", "", 10, { X,X,0,0,0,0,0,X } }, // Free Iron - {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile - {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone - {"fT", "", 10, { 0,X,X,X,X,X,X,X } }, // Free Tiger - {"fL", "", 10, { X,X,0,X,X,X,0,X } }, // Free Leopard (Free Boar?) - {"WL", "", 10, { X,0,0,X,X,X,0,0 } }, // Free Serpent (Whale?) - {"fD", "", 10, { X,0,X,X,X,X,X,0 } }, // Free Dragon - {"B", "", 10, { 0,X,0,X,0,X,0,X } }, // Free Cat (Bishop?) - {"EM", "", 10, { } }, // Emperor - {"TK", "", 10, { } }, // Teaching King - {"BS", "", 10, { } }, // Budhist Spirit - {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork - {"MW", "", 10, { 1,X,0,X,X,X,0,X } }, // Mountain Witch - {"FF", "", 10, { } }, // Furious Fiend - {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon - {"GB", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird - {"fW", "", 10, { } }, // Free Wolf - {"fB", "", 10, { } }, // Free Bear - {"BA", "", 10, { X,0,0,X,0,X,0,0 } }, // Bat + {"SF", "G", 10, { 0,1,X,1,0,1,0,1 } }, // Side Flier F! + {"LC", "G", 10, { X,0,0,X,1,0,0,X } }, // Left Chariot L' + {"RC", "G", 10, { X,X,0,0,1,X,0,0 } }, // Right Chariot R' + {"fT", "", 10, { 0,X,X,X,X,X,X,X } }, // Free Tiger +T + {"fD", "", 10, { X,0,X,X,X,X,X,0 } }, // Free Dragon +D! + {"fG", "", 10, { X,X,X,0,X,0,X,X } }, // Free Gold +G + {"fS", "", 10, { X,X,0,X,0,X,0,X } }, // Free Silver +S + {"fI", "", 10, { X,X,0,0,0,0,0,X } }, // Free Iron +I + {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y + {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U + {"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K + {"TK", "", 10, { K,K,K,K,K,K,K,K } }, // Teaching King +I' + {"BS", "", 10, { S,S,S,S,S,S,S,S } }, // Budhist Spirit +J' + {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N' + {"MW", "", 10, { 1,X,0,X,X,X,0,X } }, // Mountain Witch +M' + {"FF", "", 10, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L! + {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon +W! + {"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird +X + {"fW", "", 10, { X,X,X,0,0,0,X,X } }, // Free Wolf +W + {"BA", "", 10, { X,0,0,X,0,X,0,0 } }, // Bat +O' + // Chu pieces (but with different promotion) + {"LN", "FF",LVAL, { L,L,L,L,L,L,L,L }, 4 }, // lion + {"FK", "", 600, { X,X,X,X,X,X,X,X }, 4 }, // free king + {"FO", "", 400, { X,X,0,X,X,X,0,X }, 4 }, // flying ox (free leopard) + {"FB", "", 400, { 0,X,X,X,0,X,X,X }, 4 }, // free boar + {"DK", "", 400, { X,1,X,1,X,1,X,1 }, 4 }, // dragon king + {"DH", "", 350, { 1,X,1,X,1,X,1,X }, 4 }, // dragon horse + {"WH", "", 350, { X,X,0,0,X,0,0,X }, 3 }, // white horse (free copper) + {"R", "G", 300, { X,0,X,0,X,0,X,0 }, 4 }, // rook + {"WL", "", 250, { X,0,0,X,X,X,0,0 }, 4 }, // whale (free serpent) + {"K", "EM", 280, { 1,1,1,1,1,1,1,1 }, 2, 4 }, // king + {"CP", "", 270, { 1,1,1,1,1,1,1,1 }, 2, 4 }, // king + {"B", "G", 250, { 0,X,0,X,0,X,0,X }, 2 }, // bishop + {"VM", "G", 200, { X,0,1,0,X,0,1,0 }, 2 }, // vertical mover + {"SM", "G", 200, { 1,0,X,0,1,0,X,0 }, 6 }, // side mover + {"DE", "CP", 201, { 1,1,1,1,0,1,1,1 }, 2 }, // drunk elephant + {"BT", "fT", 152, { 0,1,1,1,1,1,1,1 }, 2 }, // blind tiger + {"G", "fG", 151, { 1,1,1,0,1,0,1,1 }, 2 }, // gold + {"FL", "FO", 150, { 1,1,0,1,1,1,0,1 }, 2 }, // ferocious leopard + {"KN", "GD", 154, { J,1,J,1,J,1,J,1 }, 2 }, // kirin + {"PH", "GB", 153, { 1,J,1,J,1,J,1,J }, 2 }, // phoenix + {"RV", "G", 150, { X,0,0,0,X,0,0,0 }, 1 }, // reverse chariot + {"L", "G", 150, { X,0,0,0,0,0,0,0 }, 1 }, // lance + {"S", "fS", 100, { 1,1,0,1,0,1,0,1 }, 2 }, // silver + {"C", "WH", 100, { 1,1,0,0,1,0,0,1 }, 2 }, // copper + {"GB", "RV", 50, { 1,0,0,0,1,0,0,0 }, 1 }, // go between + {"P", "G", 40, { 1,0,0,0,0,0,0,0 }, 2 }, // pawn {"", "", 10, { } }, // { NULL } // sentinel }; @@ -504,8 +537,8 @@ char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KNP FKR S BTSG..EWPHT .." // L ( "ABBBCSBDE FDGG DVDS LCBMCCORGB RCSD WRVODY " // L' " CARD HM LN CO VMLD "; // L! char dadaIDs[] = "RVB C DKEFFLG DHI ..K L SMNKKNP FKR S ..SGVBEWPH...." // L (also for Cashew) - "ABEBCSHDEBFDPRFHLGRGOKLCOMNBORPS RCSBST W WBVO " // L' - "RAWB BD GOHM LN SQ WTRUVMLD "; // L! + "ABEBCSHDEAFDPRFHLGRGOKLCOMNOORPS RCSOST W WSVO " // L' + "RAWB BD LGHM LN SQ WTRUVMLD "; // L! typedef struct { int boardWidth, boardFiles, boardRanks, zoneDepth, varNr; // board sizes @@ -1239,7 +1272,7 @@ GenNonCapts (int promoSuppress) for(j=0; j<8; j++) { int y, v = kStep[j], r = p[i].range[j]; if(r < 0) { // jumping piece, special treatment - if(r == N) { // pure Knightm do off-ray jump + if(r == N) { // pure Knight, do off-ray jump NewNonCapture(x, x + nStep[j], pFlag); } else if(r >= S) { // in any case, do a jump of 2 @@ -1251,6 +1284,10 @@ GenNonCapts (int promoSuppress) v = nStep[j]; if(r != W) NewNonCapture(x, x + v, pFlag); } else if(r == T) NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step + else if(r == K) { + occup |= NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step + if(!occup) for(y=x+3*v; !NewNonCapture(x, y+=v, pFlag); ); // TK moves + } } else if(r == I) NewNonCapture(x, x + v, pFlag); // also do step } else if(r == M) { // FIDE Pawn; check double-move @@ -1294,9 +1331,20 @@ MapOneColor (int start, int last, int *map) if(board[x + v] != EMPTY && board[x + v] != EDGE) map[2*(x + v) + start] += one[j]; if(r < I) { - if(r == T) { // Lion Dog, also jump of 3 + if(r == T || r == K) { // Lion Dog, also jump of 3 if(board[x + 3*v] != EMPTY && board[x + 3*v] != EDGE) map[2*(x + 3*v) + start] += one[j]; + if(r == K) { // also range (Teaching King) + int y = x, n = 0; + while(1) { + if(board[y+=v] == EDGE) break; + if(board[y] != EMPTY) { + if(n > 2) map[2*y + start] += one[j]; // outside Lion range + break; + } + n++; + } + } } else if(r <= L) { // true Lion, also Knight jump if(r < L) { // Lion plus (limited) range @@ -1634,6 +1682,7 @@ GenCapts (int sqr, int victimValue) } break; case T: // Lion-Dog move (awful!) + case K: if(d > 3) break; NewCapture(x, sqr + victimValue - SORTKEY(attacker), p[attacker].promoFlag); att -= one[i]; @@ -1697,7 +1746,7 @@ GenCapts (int sqr, int victimValue) //printf("mask[%d] = %o\n", i, att); if((att & attackMask[i]) == 0) break; } - // more attacks to come; san for next stop + // more attacks to come; scan for next stop if(jcapt < p[board[x]].qval) jcapt = p[board[x]].qval; // raise barrier for range jumpers further upstream while(board[x+=v] == EMPTY); // this should never run off-board, if the attack map is not corrupted } while(1); -- 1.7.0.4 From 6c18dc25501fb7d59d24a52137afc11fa876d863 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 3 May 2016 22:49:31 +0200 Subject: [PATCH 08/16] Add variants Cashew and Macadamia Shogi The variants cashew-shogi and macadamia-shogi are announced and recognized, and the start position is known internally and sent as setup command to the GUI. Piece commands are sent to the GUI. --- hachu.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 59 insertions(+), 14 deletions(-) diff --git a/hachu.c b/hachu.c index 147eda7..34bd893 100644 --- a/hachu.c +++ b/hachu.c @@ -280,14 +280,16 @@ PieceDesc waPieces[] = { }; PieceDesc ddPieces[] = { - {"LG", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin G! - {"OK", "LG", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite K' + {"HM", "", 10, { H,0,H,0,H,0,H,0 } }, // Hook Mover H! + {"LO", "", 10, { 1,H,1,H,1,H,1,H } }, // Long-Nosed Goblin G! + {"OK", "LO", 10, { 2,1,2,0,2,0,2,1 } }, // Old Kite K' {"PS", "HM", 10, { J,0,1,J,0,J,1,0 } }, // Poisonous Snake S' + {"FF", "", 10, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L! {"GE", "", 10, { 3,3,5,5,3,5,5,3 } }, // Great Elephant +W! - {"WS", "LD", 10, { 1,1,2,0,1,0,2,1 } }, // Western Barbarian W' - {"EA", "LN", 10, { 2,1,1,0,2,0,1,1 } }, // Eastern Barbarian E' - {"NO", "FE", 10, { 0,2,1,1,0,1,1,2 } }, // Northern Barbarian N' - {"SO", "WE", 10, { 0,1,1,2,0,2,1,1 } }, // Southern Barbarian S' + {"We", "LD", 10, { 1,1,2,0,1,0,2,1 } }, // Western Barbarian W' + {"Ea", "LN", 10, { 2,1,1,0,2,0,1,1 } }, // Eastern Barbarian E' + {"No", "FE", 10, { 0,2,1,1,0,1,1,2 } }, // Northern Barbarian N' + {"So", "WE", 10, { 0,1,1,2,0,2,1,1 } }, // Southern Barbarian S' {"FE", "", 10, { 2,X,2,2,2,2,2,X } }, // Fragrant Elephant +N' {"WE", "", 10, { 2,2,2,X,2,X,2,2 } }, // White Elephant +S' {"FT", "", 10, { X,X,5,0,X,0,5,X } }, // Free Dream-Eater +W @@ -297,6 +299,8 @@ PieceDesc ddPieces[] = { {"SB", "", 10, { X,X,2,2,2,2,2,X } }, // Standard Bearer +N {"FH", "FK", 10, { 1,2,1,0,1,0,1,2 } }, // Flying Horse H' {"NK", "SB", 10, { 1,1,1,1,1,1,1,1 } }, // Neighbor King N + {"RG", "", 10, { 1,1,0,1,1,1,1,1 } }, // Right General R' + {"LG", "", 10, { 1,1,1,1,1,1,0,1 } }, // Left General L' {"BM", "MW", 10, { 0,1,1,1,0,1,1,1 } }, // Blind Monkey {"DO", "", 10, { 2,5,2,5,2,5,2,5 } }, // Dove {"EB", "DO", 10, { 2,0,2,0,0,0,2,0 } }, // Enchanted Badger B' @@ -318,6 +322,8 @@ PieceDesc ddPieces[] = { {"SD", "", 10, { 5,2,5,2,5,2,5,2 } }, // She-Devil {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon {"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird + {"LC", "", 10, { X,0,0,X,1,0,0,X } }, // Left Chariot L' + {"RC", "", 10, { X,X,0,0,1,X,0,0 } }, // Right Chariot R' // Chu pieces (but with different promotion) {"LN", "FF",LVAL, { L,L,L,L,L,L,L,L }, 4 }, // lion {"FK", "", 600, { X,X,X,X,X,X,X,X }, 4 }, // free king @@ -346,13 +352,13 @@ PieceDesc makaPieces[] = { {"DV", "TK", 10, { 0,1,0,1,0,0,1,1 } }, // Deva I' {"DS", "BS", 10, { 0,1,1,0,0,1,0,1 } }, // Dark Spirit J' {"T", "fT", 10, { 0,1,0,0,1,0,0,1 } }, // Tile General Y - {"CS", "fS", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent S! + {"CO", "fS", 10, { 1,0,0,1,1,1,0,0 } }, // Coiled Serpent S! {"RD", "fD", 10, { 1,0,1,1,1,1,1,0 } }, // Reclining Dragon D! {"CC", "WS", 10, { 0,1,1,0,1,0,1,1 } }, // Chinese Cock N' {"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey M' {"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear B' {"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat O' - {"LD", "WS", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! + {"LD", "G", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! {"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler W' {"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods G' {"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil D' @@ -380,6 +386,17 @@ PieceDesc makaPieces[] = { {"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird +X {"fW", "", 10, { X,X,X,0,0,0,X,X } }, // Free Wolf +W {"BA", "", 10, { X,0,0,X,0,X,0,0 } }, // Bat +O' + {"FD", "G", 150, { 0,2,0,2,0,2,0,2 }, 2 }, // Flying Dragon + // Dai pieces with different promotion + {"FD", "G", 150, { 0,2,0,2,0,2,0,2 }, 2 }, // Flying Dragon + {"VO", "G", 200, { 2,0,2,0,2,0,2,0 }, 2 }, // Violent Ox + {"EW", "fW", 80, { 1,1,1,0,0,0,1,1 }, 2 }, // Evil Wolf + {"CS", "B", 70, { 0,1,0,1,0,1,0,1 }, 1 }, // Cat Sword + {"AB", "FB", 60, { 1,0,1,0,1,0,1,0 }, 1 }, // Angry Boar + {"T", "fY", 80, { 0,1,0,0,1,0,0,1 }, 2 }, // Tile + {"I", "fI", 80, { 1,1,0,0,0,0,0,1 }, 2 }, // Iron + {"N", "G", 60, { N,0,0,0,0,0,0,N }, 0 }, // Knight + {"SG", "fU", 50, { 0,1,0,0,0,0,0,1 }, 0 }, // Stone // Chu pieces (but with different promotion) {"LN", "FF",LVAL, { L,L,L,L,L,L,L,L }, 4 }, // lion {"FK", "", 600, { X,X,X,X,X,X,X,X }, 4 }, // free king @@ -514,6 +531,10 @@ char tenArray[] = "lnficsgekgscifnl/a1c!c!1txql!ot1c!c!1a/s'v'bhdw!d!q!h!d!w!dhb "16/16/16/16/" "4D6D4/PPPPPPPPPPPPPPPP/MVRF!E!B!R!Q!V!R!B!E!F!RVM/" "S'V'BHDW!D!H!Q'D!W!DHBV'S'/A1C!C!TOL!QXT1C!C!1A/LNFICSGKEGSCIFNL"; +char cashewArray[]= "lh!f'dh'j'ki'qc'hg!l/t!p'w!+oogngx+xl!k'd!/r've'fst'+nt'sfw'vl'/ppppppppppppp/3d'5d'3/13/" + "13/13/3D'5D'3/PPPPPPPPPPPPP/L'VW'FST'+NT'SFE'VR'/D!K'L!+XXGNGO+OW!P'T!/LG!HC'QI'KJ'H'DF'H!L"; +char macadArray[] = "lxcsgi'kj'gscol/1f'1w!1tet1l!1f'1/rr'g'bdh!qc!dbw'l'r/ppppppppppppp/3p'5p'3/13/" + "13/13/3P'5P'3/PPPPPPPPPPPPP/RL'W'BDC!QH!DBG'R'R/1F'1L!1TET1W!1F'1/LOCSGI'KJ'GSCXL"; char shoArray[] = "lnsgkgsnl/1r2e2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2E2R1/LNSGKGSNL"; char waArray[] = "hmlcvkwgudo/1e3s3f1/ppprpppxppp/3p3p3/11/11/11/3P3P3/PPPXPPPRPPP/1F3S3E1/ODUGWKVCLMH"; char chessArray[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"; @@ -537,7 +558,7 @@ char makaIDs[] = "RVB C DKDEFLG DHI ..K L SMN KNP FKR S BTSG..EWPHT .." // L ( "ABBBCSBDE FDGG DVDS LCBMCCORGB RCSD WRVODY " // L' " CARD HM LN CO VMLD "; // L! char dadaIDs[] = "RVB C DKEFFLG DHI ..K L SMNKKNP FKR S ..SGVBEWPH...." // L (also for Cashew) - "ABEBCSHDEAFDPRFHLGRGOKLCOMNOORPS RCSOST W WSVO " // L' + "ABEBCSHDEaFDPRFHLGRGOKLCOMNoORPS RCSoST W WeVO " // L' "RAWB BD LGHM LN SQ WTRUVMLD "; // L! typedef struct { @@ -547,7 +568,8 @@ typedef struct { char *IDs; } VariantDesc; -typedef enum { V_CHESS, V_SHO, V_CHU, V_DAI, V_DADA, V_MAKA, V_TAI, V_KYOKU, V_TENJIKU, V_SHATRANJ, V_MAKRUK, V_LION, V_WA, V_WOLF } Variant; +typedef enum { V_CHESS, V_SHO, V_CHU, V_DAI, V_DADA, V_MAKA, V_TAI, V_KYOKU, V_TENJIKU, + V_CASHEW, V_MACAD, V_SHATRANJ, V_MAKRUK, V_LION, V_WA, V_WOLF } Variant; #define SAME (-1) @@ -562,7 +584,9 @@ VariantDesc variants[] = { { 16, 8, 8, 3, V_MAKRUK, "makruk", thaiArray, chessIDs}, // Makruk { 16, 8, 8, 1, V_LION, "lion", lionArray, chessIDs}, // Mighty Lion { 22, 11, 11, 3, V_WA, "wa-shogi", waArray, waIDs}, // Wa - { 16, 8, 8, 1, V_WOLF, "werewolf",wolfArray, chessIDs}, // Wa + { 16, 8, 8, 1, V_WOLF, "werewolf",wolfArray, chessIDs}, // Werewolf Chess + { 26, 13, 13,13, V_CASHEW, "cashew-shogi", cashewArray, dadaIDs }, // Cashew + { 26, 13, 13,13, V_MACAD, "macadamia-shogi", macadArray, makaIDs }, // Macadamia { 0, 0, 0, 0, 0 }, // sentinel { 34, 17, 17, 0, V_DADA, "dada", chuArray }, // Dai Dai @@ -760,6 +784,10 @@ LookUp (char *name, int var) return ListLookUp(name, waPieces); case V_WOLF: // Werewolf return ListLookUp(name, wolfPieces); + case V_CASHEW: // Cashew + return ListLookUp(name, ddPieces); + case V_MACAD: // Cashew + return ListLookUp(name, makaPieces); } return NULL; } @@ -918,8 +946,8 @@ AddPiece (int stm, PieceDesc *list) void SetUp (char *array, int var) { - int i, j, n, m, color; - char c, name[3], prince = 0; + int i, j, n, m, color, c; + char name[3], prince = 0; PieceDesc *p1, *p2; last[WHITE] = 1; last[BLACK] = 0; royal[WHITE] = royal[BLACK] = 0; @@ -947,7 +975,7 @@ SetUp (char *array, int var) name[1] = IDs[2*(c - 'A') + 1]; if(name[1] == ' ') name[1] = 0; if(!strcmp(name, "CP") || pflag && !strcmp(name, "DE")) prince |= color+1; // remember if we added Crown Prince p1 = LookUp(name, var); - if(!p1) printf("tellusererror Unknown piece '%s' in setup\n", name), exit(-1); + if(!p1) printf("tellusererror Unknown piece '%s' in setup (%d)\n", name, c), exit(-1); if(pflag && p1->promoted) p1 = LookUp(p1->promoted, var); // use promoted piece instead n = AddPiece(color, p1); p[n].pos = j; @@ -3055,6 +3083,23 @@ pboard(board); "piece +P& WfF\npiece +O& K\npiece +H& vN\npiece +U& BfW\npiece +L& vRfF3bFsW\npiece +M& FfW\npiece +G& sRvW\npiece +C& vRsWfF\n" "piece D& sbWfF\npiece V& FfW\npiece W& WfF\npiece S& sRvW\npiece R& FfRbW\npiece F& BfW\npiece X& FvWAvD\n" "piece +D& WfF\npiece +V& FfsW\npiece +W& K\npiece +S& R\npiece +R& FvWAvD\npiece +F& BvRsW\npiece E& vRfF3bFsW\n"); + if(currentVariant == V_MACAD) + printf("setup (P.*B*RQSEXOG....D^J'..*LP'.L!J'...*W!...*F'...^C.C.^L!.^P'^K.T*L'.*C!*H!^I'.^E...*R'^P^T*W'*G'^G^SI'^X^OK" + "p.*b*rqsexog....d^j'..*lp'.l!j'...*w!...*f'...^c.c.^l!.^p'^k.t*l'.*c!*h!^i'.^e...*r'^p^t*w'*g'^g^si'^x^ok) 13x13+0_chu %s w 0 1\n" + "piece P& fW\npiece S& FfW\npiece E& FfsW\npiece X& WA\npiece O& FD\npiece G& WfF\npiece D& RF\npiece +J'& QNADcaKmabK\n" + "piece L& fR\npiece P'& vW\npiece L!& KNADcaKmabK\npiece J'& blfFrW\npiece H!& RmasR\npiece W!& KADcavKmcpafmcpavK\n" + "piece C!& BmasB\npiece F'& F2\npiece +C& vRfB\npiece C& vWfF\npiece +L!& K3NADcaKmabK\npiece +P'& vR\npiece T& FbsW\n" + "piece L'& lfrbBfRbW\npiece +I'& QADcavKmcpafmcpavK\npiece +E& K\npiece R'& rflbBfRbW\npiece +P& WfF\npiece +T& BbsR\n" + "piece W'& F3sW\npiece G'& W3fF\npiece +G& RfB\npiece +S& BfR\npiece I'& rbfFlW\npiece +X& F3vRsW\npiece +O& F3sRvW\n", macadArray); + if(currentVariant == V_CASHEW) + printf("setup (P.^K'^P'QS^W!XOGND'.HDT!...P'.L!E'.^W'K'W!..LF'V^E'J'H'...^L!^N..FT'L'C'G!H!D!I'.^H'..R'..^C'^F'..W'^X^OK" + "p.^k'^p'qs^w!xognd'.hdt!...p'.l!e'.^w'k'w!..lf'v^e'j'h'...^l!^n..ft'l'c'g!h!d!i'.^h'..r'..^c'^f'..w'^x^ok) 13x13+0_chu %s w 0 1\n" + "piece P& fW\npiece S& FfW\npiece W'& fFvWsW2\npiece E'& fFsWvW2\npiece X& WA\npiece O& FD\npiece G& WfF\npiece H& BW\n" + "piece +C'& BW\npiece D& RF\npiece +F'& RF\npiece L& fR\npiece D'& fRbW\npiece L!& KNADcaKmabK\npiece +E'& KNADcaKmabK\n" + "piece J'& FvlW\npiece H!& RmasR\npiece +W'& KADcavKmcpafmcpavK\npiece G!& WBmasB\npiece F'& F2\npiece +L!& K3NADcaKmabK\n" + "piece T!& vRsW2flBfrF\npiece T'& fFvW2\npiece L'& lfrbBfRbW\npiece N& K\npiece R'& rflbBfRbW\npiece I'& FvrW\n" + "piece +X& F3vRsW2\npiece +O& F3sRvW2\npiece H'& WfF2\npiece +H'& Q\npiece C'& F\npiece D!& sRvW2frBflF\npiece P'& sWfDbA\n" + "piece K'& W2fF\npiece +K'& WBmasB\npiece +P'& RmasR\npiece +N& fRfBbF2bsW2\npiece F& FvW\npiece V& fF2sW\n", cashewArray); repStack[199] = hashKeyH, checkStack[199] = 0; continue; } -- 1.7.0.4 From 9c3c68f6996b747685ed0b5f7611c61ed47de3bd Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 4 May 2016 14:25:55 +0200 Subject: [PATCH 09/16] Make promote on entry default The option that decides whether non-captures can only promote when entering the zone, rather than also after waiting one turn after deferral, is now set by default. This because it seems to have been the historic rule. --- hachu.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hachu.c b/hachu.c index 34bd893..72d9972 100644 --- a/hachu.c +++ b/hachu.c @@ -162,7 +162,7 @@ typedef struct { char *array, *IDs, fenArray[4000], startPos[4000], *reason, checkStack[300]; int bWidth, bHeight, bsize, zone, currentVariant, chuFlag, tenFlag, chessFlag, repDraws, stalemate; -int tsume, pvCuts, allowRep, entryProm, okazaki, pVal; +int tsume, pvCuts, allowRep, entryProm=1, okazaki, pVal; int stm, xstm, hashKeyH=1, hashKeyL=1, framePtr, msp, nonCapts, rootEval, filling, promoDelta; int retMSP, retFirst, retDep, pvPtr, level, cnt50, mobilityScore; int ll, lr, ul, ur; // corner squares @@ -2989,12 +2989,12 @@ pboard(board); printf("%s%s", (i ? "," : "feature variants=\""), variants[i].name); printf("\"\n"); printf("feature ping=1 setboard=1 colors=0 usermove=1 memory=1 debug=1 sigint=0 sigterm=0\n"); printf("feature myname=\"HaChu " VERSION "\" highlight=1\n"); - printf("feature option=\"Full analysis PV -check 1\"\n"); // example of an engine-defined option - printf("feature option=\"Allow repeats -check 0\"\n"); - printf("feature option=\"Promote on entry -check 0\"\n"); - printf("feature option=\"Okazaki rule -check 0\"\n"); - printf("feature option=\"Resign -check 0\"\n"); // - printf("feature option=\"Contempt -spin 0 -200 200\"\n"); // and another one + printf("feature option=\"Full analysis PV -check %d\"\n", noCut); // example of an engine-defined option + printf("feature option=\"Allow repeats -check %d\"\n", allowRep); + printf("feature option=\"Promote on entry -check %d\"\n", entryProm); + printf("feature option=\"Okazaki rule -check %d\"\n", okazaki); + printf("feature option=\"Resign -check %d\"\n", resign); // + printf("feature option=\"Contempt -spin %d -200 200\"\n", contemptFactor); // and another one printf("feature option=\"Tsume -combo no /// Sente mates /// Gote mates\"\n"); printf("feature done=1\n"); continue; -- 1.7.0.4 From c2107013effb407356cd8a1c38308d04dde131b0 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Fri, 6 May 2016 17:52:28 +0200 Subject: [PATCH 10/16] Implement Teaching King move A new special-move code K is added, to indicate Lion-Dog move plus infinite-range sliding. The code for generating captures, non-captures and creating the attack map was streamlined a little; in particular range captures on special moves are now table-driven. --- hachu.c | 79 +++++++++++++++++++++++++++++++++++--------------------------- 1 files changed, 45 insertions(+), 34 deletions(-) diff --git a/hachu.c b/hachu.c index 72d9972..ec25a6b 100644 --- a/hachu.c +++ b/hachu.c @@ -12,7 +12,7 @@ #define VERSION "0.21" -//define PATH level==0 || path[0] == 0x590cb && (level==1 || path[1] == 0x4c0c9 && (level == 2 || path[2] == 0x8598ca && (level == 3 /*|| path[3] == 0x3e865 && (level == 4 || path[4] == 0x4b865 && (level == 5))*/))) +//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))*/))) #define PATH 0 #define HASH @@ -177,9 +177,9 @@ Move retMove, moveStack[20000], path[100], repStack[300], pv[1000], repeatMove[3 #define N -1 /* Knight */ #define J -2 /* jump */ #define I -3 /* jump + step */ -#define D -4 /* linear double move */ +#define K -4 /* triple + range */ #define T -5 /* linear triple move */ -#define K -6 /* triple + range */ +#define D -6 /* linear double move */ #define L -7 /* true Lion move */ #define W -8 /* Werewolf move */ #define F -9 /* Lion + 3-step */ @@ -358,7 +358,7 @@ PieceDesc makaPieces[] = { {"OM", "MW", 10, { 0,1,0,1,1,1,0,1 } }, // Old Monkey M' {"BB", "fB", 10, { 0,1,0,1,X,1,0,1 } }, // Blind Bear B' {"OR", "BA", 10, { 0,2,0,0,2,0,0,2 } }, // Old Rat O' - {"LD", "G", 10, { T,T,T,T,T,T,T,T } }, // Lion Dog W! + {"LD", "G", 800, { T,T,T,T,T,T,T,T } }, // Lion Dog W! {"WR", "G", 10, { 0,3,1,3,0,3,1,3 } }, // Wrestler W' {"GG", "G", 10, { 3,1,3,0,3,0,3,1 } }, // Guardian of the Gods G' {"BD", "G", 10, { 0,3,1,0,1,0,1,3 } }, // Budhist Devil D' @@ -377,11 +377,11 @@ PieceDesc makaPieces[] = { {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U {"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K - {"TK", "", 10, { K,K,K,K,K,K,K,K } }, // Teaching King +I' - {"BS", "", 10, { S,S,S,S,S,S,S,S } }, // Budhist Spirit +J' + {"TK", "", 1300, { K,K,K,K,K,K,K,K }, 0, 6}, // Teaching King +I' + {"BS", "", 1500, { S,S,S,S,S,S,S,S }, 0, 7}, // Budhist Spirit +J' {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N' {"MW", "", 10, { 1,X,0,X,X,X,0,X } }, // Mountain Witch +M' - {"FF", "", 10, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L! + {"FF", "", 1150, { F,F,F,F,F,F,F,F } }, // Furious Fiend +L! {"GD", "", 10, { 2,3,X,3,2,3,X,3 } }, // Great Dragon +W! {"GO", "", 10, { X,3,2,3,X,3,2,3 } }, // Golden Bird +X {"fW", "", 10, { X,X,X,0,0,0,X,X } }, // Free Wolf +W @@ -984,6 +984,10 @@ SetUp (char *array, int var) p2 = LookUp(p1->promoted, var); m = AddPiece(color, p2); if(m <= n) n += 2; + if(p2->ranking > 5) { // contageous + AddPiece(color, p2); + if(m <= n) n += 2; + } p[n].promo = m; p[n].promoFlag = IsUpwardCompatible(p2->range, p1->range) * DONT_DEFER + CAN_PROMOTE; if(Forward(p1->range)) p[n].promoFlag |= LAST_RANK; // Pieces that only move forward can't defer on last rank @@ -1311,10 +1315,9 @@ GenNonCapts (int promoSuppress) if(!occup & r < L) for(y=x+2*v; !NewNonCapture(x, y+=v, pFlag) && r == S; ); // BS and FF moves v = nStep[j]; if(r != W) NewNonCapture(x, x + v, pFlag); - } else if(r == T) NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step - else if(r == K) { + } else if(r >= T) { // T or K occup |= NewNonCapture(x, x+3*v, pFlag); // Lion Dog, also triple step - if(!occup) for(y=x+3*v; !NewNonCapture(x, y+=v, pFlag); ); // TK moves + if(!occup && r == K) for(y=x+3*v; !NewNonCapture(x, y+=v, pFlag); ); // Teaching King distant moves } } else if(r == I) NewNonCapture(x, x + v, pFlag); // also do step } else @@ -1355,18 +1358,18 @@ MapOneColor (int start, int last, int *map) if(r >= S) { // in any case, do a jump of 2 if(board[x + 2*v] != EMPTY && board[x + 2*v] != EDGE) map[2*(x + 2*v) + start] += one[j], mob += (board[x + 2*v] ^ start) & 1; - if(r < J) { // Lion power, also single step + if(r < J) { // more than plain jump if(board[x + v] != EMPTY && board[x + v] != EDGE) - map[2*(x + v) + start] += one[j]; - if(r < I) { - if(r == T || r == K) { // Lion Dog, also jump of 3 + map[2*(x + v) + start] += one[j]; // single step (completes D and I) + if(r < I) { // Lion power + if(r >= T) { // Lion Dog, also do a jump of 3 if(board[x + 3*v] != EMPTY && board[x + 3*v] != EDGE) map[2*(x + 3*v) + start] += one[j]; - if(r == K) { // also range (Teaching King) + if(r == K) { // Teaching King also range move int y = x, n = 0; while(1) { if(board[y+=v] == EDGE) break; - if(board[y] != EMPTY) { + if(board[y] != EMPTY) { if(n > 2) map[2*y + start] += one[j]; // outside Lion range break; } @@ -1554,9 +1557,9 @@ MakeMove(Move m, UndoInfo *u) u->victim = board[u->to]; p[u->victim].pos = ABSENT; - if(p[u->victim].ranking == 5 && p[u->piece].ranking < 4) { // contageous piece captured by non-royal + if(p[u->victim].ranking >= 5 && p[u->piece].ranking < 4) { // contageous piece captured by non-royal u->booty -= p[u->new].value; - u->new = u->piece & 1 | 2; // promote to it + u->new = u->piece & 1 | (u->victim - 2 & ~3) + 2; // promote to it (assumes they head the list in pairs) if(p[u->new].pos != ABSENT) u->new += 2; p[u->piece].pos = ABSENT; u->booty += p[u->new].value; @@ -1639,9 +1642,11 @@ GenCapts (int sqr, int victimValue) while( board[x+=v] == EMPTY ); // scan towards source until we encounter a 'stop' //printf("stop @ %c%d (dir %d)\n",x%BW+'a',x/BW,i); if((board[x] & TYPE) == stm) { // stop is ours + static int minRange[20] = { 3, 0, 0, 0, 2, 2, 2 }; // K, T, D, L, W, F, S + static int maxRange[20] = { 36, 0, 0, 0, 3, 3, 36 }; // K, T, D, L, W, F, S int attacker = board[x], d = dist[x-sqr], r = p[attacker].range[i]; //printf("attacker %d, range %d, dist %d\n", attacker, r, d); - if(r >= d || r < L && (d > 3 && r == S || d == 3 && r >= S)) { // it has a plain move in our direction that hits us + if(r >= d || r <= K && d <= maxRange[K-r] && d > minRange[K-r]) { // it has a plain move in our direction that hits us NewCapture(x, sqr + victimValue - SORTKEY(attacker), p[attacker].promoFlag); att -= one[i]; if(!(att & attackMask[i])) continue; // no more; next direction @@ -1649,7 +1654,7 @@ GenCapts (int sqr, int victimValue) while(board[x+=v] == EMPTY);// one attack accounted for, but more to come, so skip to next stop } } - // we get here when we are on a piece that dous not attack us through a (limited) ranging move, + // we get here when we are on a piece that does not attack us through a (limited) ranging move, // it can be our own or an enemy with not (enough) range, or which is blocked do { //printf("scan %x-%x (%d) dir=%d d=%d r=%d att=%o jcapt=%d qval=%d\n", sqr, x, board[x], i, dist[x-sqr], p[board[x]].range[i], att, jcapt, p[board[x]].qval); @@ -2123,7 +2128,7 @@ if(PATH)printf("new iter %d\n", iterDep); bestScore = curEval; resDep = QSdepth; if(bestScore > alpha) { alpha = bestScore; -if(PATH)printf("stand pat %d\n", bestScore); +if(PATH)printf("stand pat %d (beta=%d)\n", bestScore, beta); if(bestScore >= beta) goto cutoff; } } @@ -2131,14 +2136,18 @@ if(PATH)printf("stand pat %d\n", bestScore); if(flag && depth>= 0) printf("phase=%d: first/curr/last = %d / %d / %d\n", phase, firstMove, curMove, msp);fflush(stdout); // MOVE SOURCE if(curMove >= msp) { // we ran out of moves; generate some new -if(PATH)printf("new moves, phase=%d\n", phase); +if(PATH)printf("new moves, phase=%d\n", phase),fflush(stdout); switch(phase) { case 0: // null move #ifdef NULLMOVE if(depth > QSdepth && curEval >= beta && !inCheck && filling > 10) { int nullDep = depth - 3; stm ^= WHITE; +path[level++] = 0; +if(PATH) printf("%d:%d null move\n", level, depth),fflush(stdout); score = -Search(-beta, 1-beta, -difEval, nullDep= beta) { msp = oldMSP; retDep += 3; pvPtr = myPV; return score + (score < curEval); } // else depth += lmr, lmr = 0; @@ -2160,7 +2169,7 @@ if(PATH)printf("new moves, phase=%d\n", phase); nextVictim = xstm; autoFail = (depth == 0); phase = 3; case 3: // generate captures -if(PATH) printf("%d:%2d:%2d next victim %d/%d\n",level,depth,iterDep,curMove,msp); +if(PATH) printf("%d:%2d:%2d next victim %d/%d\n",level,depth,iterDep,curMove,msp),fflush(stdout); while(nextVictim < last[xstm]) { // more victims exist int group, to = p[nextVictim += 2].pos; // take next if(to == ABSENT) continue; // ignore if absent @@ -2171,18 +2180,18 @@ if(PATH) printf("%d:%2d:%2d next victim %d/%d\n",level,depth,iterDep,curMove,msp if(bestScore < 2*group + curEval + 30) bestScore = 2*group + curEval + 30; goto cutoff; } -if(PATH) printf("%d:%2d:%2d group=%d, to=%c%d\n",level,depth,iterDep,group,to%BW+'a',to/BW+ONE); +if(PATH) printf("%d:%2d:%2d group=%d, to=%c%d\n",level,depth,iterDep,group,to%BW+'a',to/BW+ONE),fflush(stdout); GenCapts(to, 0); -if(PATH) printf("%d:%2d:%2d first=%d msp=%d\n",level,depth,iterDep,firstMove,msp); +if(PATH) printf("%d:%2d:%2d first=%d msp=%d\n",level,depth,iterDep,firstMove,msp),fflush(stdout); while(nextVictim < last[xstm] && p[nextVictim+2].value == group) { // more victims of same value exist to = p[nextVictim += 2].pos; // take next if(to == ABSENT) continue; // ignore if absent if(!attacks[2*to + stm]) continue; // skip if not attacked -if(PATH) printf("%d:%2d:%2d p=%d, to=%c%d\n",level,depth,iterDep,nextVictim,to%BW+'a',to/BW+ONE); +if(PATH) printf("%d:%2d:%2d p=%d, to=%c%d\n",level,depth,iterDep,nextVictim,to%BW+'a',to/BW+ONE),fflush(stdout); GenCapts(to, 0); -if(PATH) printf("%d:%2d:%2d msp=%d\n",level,depth,iterDep,msp); +if(PATH) printf("%d:%2d:%2d msp=%d\n",level,depth,iterDep,msp),fflush(stdout); } -if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", nextVictim, msp, group, threshold); +if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", nextVictim, msp, group, threshold),fflush(stdout); goto extractMove; // in auto-fail phase, only search if they might auto-fail-hi } if(PATH) printf("# autofail=%d\n", autoFail); @@ -2420,8 +2429,8 @@ pplist() { int i, j; for(i=0; i<182; i++) { - printf("%3d. %3d %3d %4d %02x %d %d %x %3d %4d ", i, p[i].value, p[i].promo, p[i].pos, p[i].promoFlag&255, p[i].mobWeight, p[i].qval, p[i].bulk, p[i].promoGain, p[i].pst); - for(j=0; j<8; j++) printf(" %2d", p[i].range[j]); + printf("%3d. %4d %3d %4d %02x %d %2d %x %3d %4d ", i, p[i].value, p[i].promo, p[i].pos, p[i].promoFlag&255, p[i].mobWeight, p[i].qval, p[i].bulk, p[i].promoGain, p[i].pst); + for(j=0; j<8; j++) printf(" %3d", p[i].range[j]); if(i<2 || i>11) printf("\n"); else printf(" %02x %d\n", fireFlags[i-2]&255, p[i].ranking); } printf("last: %d / %d\nroyal %d / %d\n", last[WHITE], last[BLACK], royal[WHITE], royal[BLACK]); @@ -2644,7 +2653,7 @@ MapFromScratch(attacks); for(i=listStart; i> SQLEN & SQUARE; if(to >= SPECIAL) continue; - if(p[board[to]].ranking == 5 && p[board[from]].ranking < 4) moveStack[i] |= PROMOTE; + if(p[board[to]].ranking >= 5 && p[board[from]].ranking < 4) moveStack[i] |= PROMOTE; } } @@ -2950,12 +2959,14 @@ pboard(board); PrintResult(stm, score); } else { MOVE f, pMove = move; + static char *pName[] = { "w", "z", "j" }; if((move & SQUARE) >= SPECIAL && p[board[f = move>>SQLEN & SQUARE]].value == pVal) { // e.p. capture pMove = move & ~SQUARE | f + toList[(move & SQUARE) - SPECIAL]; // print as a single move } stm = MakeMove2(stm, move); // assumes MakeMove returns new side to move gameMove[moveNr++] = move; // remember game - printf("move %s%s\n", MoveToText(pMove, 1), p[undoInfo.victim].ranking == 5 && p[undoInfo.piece].ranking < 4 ? "w" : ""); + i = p[undoInfo.victim].ranking; + printf("move %s%s\n", MoveToText(pMove, 1), i == 5 && p[undoInfo.piece].ranking < 4 ? pName[i-5] : ""); listEnd = 0; continue; // go check if we should ponder } @@ -3084,8 +3095,8 @@ pboard(board); "piece D& sbWfF\npiece V& FfW\npiece W& WfF\npiece S& sRvW\npiece R& FfRbW\npiece F& BfW\npiece X& FvWAvD\n" "piece +D& WfF\npiece +V& FfsW\npiece +W& K\npiece +S& R\npiece +R& FvWAvD\npiece +F& BvRsW\npiece E& vRfF3bFsW\n"); if(currentVariant == V_MACAD) - printf("setup (P.*B*RQSEXOG....D^J'..*LP'.L!J'...*W!...*F'...^C.C.^L!.^P'^K.T*L'.*C!*H!^I'.^E...*R'^P^T*W'*G'^G^SI'^X^OK" - "p.*b*rqsexog....d^j'..*lp'.l!j'...*w!...*f'...^c.c.^l!.^p'^k.t*l'.*c!*h!^i'.^e...*r'^p^t*w'*g'^g^si'^x^ok) 13x13+0_chu %s w 0 1\n" + printf("setup (P.*B*RQSEXOG....D^J'..*LP'.L!J'=J...*W!...*F'...^C.C.^L!.^P'^K.T*L'.*C!*H!^I'=Z.^E...*R'^P^T*W'*G'^G^SI'^X^OK" + "p.*b*rqsexog....d^j'..*lp'.l!j'=j...*w!...*f'...^c.c.^l!.^p'^k.t*l'.*c!*h!^i'=z.^e...*r'^p^t*w'*g'^g^si'^x^ok) 13x13+0_chu %s w 0 1\n" "piece P& fW\npiece S& FfW\npiece E& FfsW\npiece X& WA\npiece O& FD\npiece G& WfF\npiece D& RF\npiece +J'& QNADcaKmabK\n" "piece L& fR\npiece P'& vW\npiece L!& KNADcaKmabK\npiece J'& blfFrW\npiece H!& RmasR\npiece W!& KADcavKmcpafmcpavK\n" "piece C!& BmasB\npiece F'& F2\npiece +C& vRfB\npiece C& vWfF\npiece +L!& K3NADcaKmabK\npiece +P'& vR\npiece T& FbsW\n" -- 1.7.0.4 From cc87afb316a92a2c0b26be197017281584aea791 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Fri, 6 May 2016 17:56:46 +0200 Subject: [PATCH 11/16] Fix input of three-leg move The second comma was not read away, with as a result that the third square could not be parsed, and triple-leg move would always be considered illegal. --- hachu.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hachu.c b/hachu.c index ec25a6b..430af97 100644 --- a/hachu.c +++ b/hachu.c @@ -2680,6 +2680,7 @@ ParseMove (char *moveText) } else if(f + 3*kStep[i] == t) { // Lion Dog 1+2 move t2 = SPECIAL + 64 + i; } else if(*moveText == ',') { // 3rd leg follows! + moveText++; if(f + 2*kStep[i] != t) return INVALID; // 3-leg moves must be linear! moveText += ReadSquare(moveText, &e); if(e != t) return INVALID; // must again continue with same piece -- 1.7.0.4 From e5b8f1899abb2cc0f406df1a6f22b5c605c58363 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Tue, 7 Oct 2025 21:44:30 +0200 Subject: [PATCH 12/16] Fix counterstike against promoting Kirin 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 | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/hachu.c b/hachu.c index 430af97..6ab5442 100644 --- a/hachu.c +++ b/hachu.c @@ -10,7 +10,7 @@ // promotions by pieces with Lion power stepping in & out the zone in same turn // promotion on capture -#define VERSION "0.21" +#define VERSION "0.21d" //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))*/))) #define PATH 0 @@ -377,6 +377,7 @@ PieceDesc makaPieces[] = { {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U {"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K + {"TK", "", 1300, { K,K,K,K,K,K,K,K }, 0, 6}, // Teaching King +I' {"BS", "", 1500, { S,S,S,S,S,S,S,S }, 0, 7}, // Budhist Spirit +J' {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N' @@ -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) score = -INF; // our Lion is indeed made vulnerable and can be recaptured } else { // other x Ln - if(promoSuppress & PROMOTE) { // non-Lion captures Lion after opponent did same + if(promoSuppress & PROMOTE && // previous move was also other x Lion + (promoSuppress & SQUARE) != tb.to) { // but not made by a promoting Kirin if(!okazaki || attacks[2*tb.to + stm]) score = -INF; } + if(p[board[tb.to]].value == LVAL) // the capturer promoted to Lion (and must have been a Kirin) + defer = tb.to; // exempt it from the counter-strike rule defer |= PROMOTE; // if we started, flag he cannot do it in reply } if(score == -INF) { @@ -2541,7 +2545,10 @@ MakeMove2 (int stm, MOVE move) FireSet(&undoInfo); sup0 = sup1; sup1 = sup2; sup2 = MakeMove(move, &undoInfo); - if(chuFlag && p[undoInfo.victim].value == LVAL && p[undoInfo.piece].value != LVAL) sup2 |= PROMOTE; + if(chuFlag && p[undoInfo.victim].value == LVAL && p[undoInfo.piece].value != LVAL) { + if(p[board[undoInfo.to]].value == LVAL) sup2 = undoInfo.to; + sup2 |= PROMOTE; + } rootEval = -rootEval - undoInfo.booty; for(i=0; i<200; i++) repStack[i] = repStack[i+1], checkStack[i] = checkStack[i+1]; -- 1.7.0.4 From c7d6baff248a83f032fb7eaeaf634c597726472d Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 8 Oct 2025 10:54:59 +0200 Subject: [PATCH 13/16] Reduce crash risk Some arrays are enlarged to avoid they will overflow at large search depth. --- hachu.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hachu.c b/hachu.c index 6ab5442..ee53b1e 100644 --- a/hachu.c +++ b/hachu.c @@ -168,7 +168,7 @@ int retMSP, retFirst, retDep, pvPtr, level, cnt50, mobilityScore; int ll, lr, ul, ur; // corner squares int nodes, startTime, lastRootMove, lastRootIter, tlim1, tlim2, tlim3, repCnt, comp, abortFlag; Move ponderMove; -Move retMove, moveStack[20000], path[100], repStack[300], pv[1000], repeatMove[300], killer[100][2]; +Move retMove, moveStack[80000], path[200], repStack[400], pv[10000], repeatMove[300], killer[200][2]; int maxDepth; // used by search @@ -3033,7 +3033,7 @@ pboard(board); } continue; } - if(!strcmp(command, "sd")) { sscanf(inBuf, "sd %d", &maxDepth); continue; } + if(!strcmp(command, "sd")) { sscanf(inBuf, "sd %d", &maxDepth); maxDepth &= 63; continue; } if(!strcmp(command, "st")) { sscanf(inBuf, "st %d", &timePerMove); continue; } if(!strcmp(command, "memory")) { SetMemorySize(atoi(inBuf+7)); continue; } -- 1.7.0.4 From e3bcbbf82278c55115d1910cdfa88d00210d9be6 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 8 Oct 2025 22:10:31 +0200 Subject: [PATCH 14/16] Fix FEN reading A space now is recognized as the end of the board part, rather than taken as piece ID. --- hachu.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/hachu.c b/hachu.c index ee53b1e..1aa2acd 100644 --- a/hachu.c +++ b/hachu.c @@ -10,7 +10,7 @@ // promotions by pieces with Lion power stepping in & out the zone in same turn // promotion on capture -#define VERSION "0.21d" +#define VERSION "0.21" //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))*/))) #define PATH 0 @@ -377,7 +377,6 @@ PieceDesc makaPieces[] = { {"fY", "", 10, { 0,X,0,0,X,0,0,X } }, // Free Tile +Y {"fU", "", 10, { 0,X,0,0,0,0,0,X } }, // Free Stone +U {"EM", "", 10, { 0,0,0,0,0,0,0,0 } }, // Emperor +K - {"TK", "", 1300, { K,K,K,K,K,K,K,K }, 0, 6}, // Teaching King +I' {"BS", "", 1500, { S,S,S,S,S,S,S,S }, 0, 7}, // Budhist Spirit +J' {"WS", "", 10, { X,X,0,X,1,X,0,X } }, // Wizard Stork +N' @@ -958,7 +957,7 @@ SetUp (char *array, int var) int pflag=0; if(*array == '+') pflag++, array++; c = name[0] = *array++; - if(!c) goto eos; + if(!c || c == ' ') goto eos; if(c == '.') continue; if(c > '0' && c <= '9') { c -= '0'; if(*array >= '0' && *array <= '9') c = 10*c + *array++ - '0'; -- 1.7.0.4 From 4397f72d920c7f3aafc852d50cd53c3adc8cc544 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 8 Oct 2025 22:14:44 +0200 Subject: [PATCH 15/16] Bump version to 0.22 --- hachu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hachu.c b/hachu.c index 1aa2acd..a244701 100644 --- a/hachu.c +++ b/hachu.c @@ -10,7 +10,7 @@ // promotions by pieces with Lion power stepping in & out the zone in same turn // promotion on capture -#define VERSION "0.21" +#define VERSION "0.22" //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))*/))) #define PATH 0 -- 1.7.0.4 From 195a7bf5f5a9cad6d1908fa3aabc9ca62792e271 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Thu, 9 Oct 2025 16:04:00 +0200 Subject: [PATCH 16/16] Fix last-rank Pawn promotion With "Promote on entry" on, Pawns were not allowed to promote on last rank in Chu Shogi. Undesired side effect of this fix is that Lances now also are allowed to do that (subject to a 1-turn delay). --- hachu.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hachu.c b/hachu.c index a244701..34f61c5 100644 --- a/hachu.c +++ b/hachu.c @@ -1203,8 +1203,9 @@ inline int NewNonCapture (int x, int y, int promoFlags) { if(board[y] != EMPTY) return 1; // edge, capture or own piece -//if(flag) printf("# add %c%d%c%d, pf=%d\n", x%BW+'a',x/BW,y%BW+'a',y/BW, promoFlags); - if( (entryProm ? promoBoard[y] & ~promoBoard[x] & CAN_PROMOTE +//if(flag) +printf("# add %c%d%c%d, pf=%x %x %x\n", x%BW+'a',x/BW+1,y%BW+'a',y/BW+1, promoFlags, promoBoard[x], promoBoard[y]); + if( (entryProm ? promoBoard[y] & (~promoBoard[x] & CAN_PROMOTE | LAST_RANK) : promoBoard[y] | promoBoard[x] ) & promoFlags ){ // piece can promote with this move moveStack[msp++] = moveStack[nonCapts]; // create space for promotion moveStack[nonCapts++] = x<