for (i = g->numHalfMoves-2; i > 0; i -= 2) {
if (g->moveList[i].toFile == f && g->moveList[i].toRank == r) {
- if (g->moveList[i].piecePromotionTo)
- return 1;
+ if (g->moveList[i].piecePromotionTo) {
+ switch(g->moveList[i].moveString[0]) { // [HGM] return original piece type rather than just TRUE
+ case 'P': return PAWN;
+ case 'N': return KNIGHT;
+ case 'B': return BISHOP;
+ case 'R': return ROOK;
+ case 'L': return LANCE;
+ case 'S': return SILVER;
+ default: return GOLD;
+ }
+ }
if (g->moveList[i].fromFile == ALG_DROP)
return 0;
f = g->moveList[i].fromFile;
return;
}
}
+ pp->promote = NOPIECE; // [HGM] this seemed to be uninitialized, which caused spurious promotion in Shogi
if ((len = strlen(command)) > 1) {
if (command[len - 2] == '=') {
printf("promo '%s'\n", command);
case 'g':
pp->promote = MASTODON;
break;
+ // Shogi promotions
+ case '^':
+ case '+':
+ pp->promote = GOLD;
+ break;
+ case '=':
+ pp->promote = NOPIECE;
+ break;
default:
pprintf(p, "Don't understand that move.\n");
return;
if (result == MOVE_OK && (gg->link >= 0 || gg->game_state.holdings) && move.pieceCaptured != NOPIECE) {
/* transfer captured piece to partner */
/* check if piece reverts to a pawn */
- int victim = move.pieceCaptured, partner = gg->link;
+ int victim = move.pieceCaptured, partner = gg->link, demoted;
// [HGM] zh: if not Bughouse, the game_state.holdings field decides what happens
if(gg->link < 0) {
partner = g; // pieces stay with current board
if(gg->game_state.holdings == -1) victim ^= WHITE|BLACK; // flip color
}
- if (was_promoted(&game_globals.garray[g], move.toFile, move.toRank))
- update_holding(partner, colorval(victim) | PAWN); // [HGM] todo: for Shogi we would have to demote differently!
+ if (demoted = was_promoted(&game_globals.garray[g], move.toFile, move.toRank))
+ update_holding(partner, colorval(victim) | demoted); // [HGM] was_promoted now returns original piece type
else
update_holding(partner, victim);
}
static int legal_pawn_move( struct game_state_t *gs, int ff, int fr, int tf, int tr )
{
if (ff == tf) {\r
- if (gs->board[tf][tr] != NOPIECE && !gs->palace) return 0; // [HGM] XQ pawns can capture straight ahead\r
+ if (gs->board[tf][tr] != NOPIECE && !gs->palace && gs->promoType != 3) return 0; // [HGM] XQ and Shogi pawns can capture straight ahead\r
if (gs->onMove == WHITE) {\r
if (tr - fr == 1) return 1;\r
if ((fr <= gs->pawnDblStep) && (tr - fr == 2) && gs->board[ff][fr+1]==NOPIECE) return 1;
}\r
return 0;\r
}\r
- if (ff != tf) { /* Capture ? */
+ if (ff != tf && gs->promoType != 3) { /* Capture ? ([HGM] but not in Shogi) */
if ((ff - tf != 1) && (tf - ff != 1)) return 0;
if (gs->onMove == WHITE) {
if(gs->palace) return (fr >= gs->ranks/2 && fr == tr); // [HGM] XQ promoted pawns\r
int *posf, int *posr, int *numpos)
{
if (gs->onMove == WHITE) {\r
- if (gs->board[onf][onr + 1] == NOPIECE || gs->palace) {\r
+ if (gs->board[onf][onr + 1] == NOPIECE || gs->palace || gs->promoType == 3) {\r
add_pos(onf, onr + 1, posf, posr, numpos);\r
if ((onr <= gs->pawnDblStep) && (gs->board[onf][onr + 2] == NOPIECE))\r
add_pos(onf, onr + 2, posf, posr, numpos);\r
}\r
if (onf > 0) {
if (gs->board[onf - 1][onr + 1] != NOPIECE &&\r
- iscolor(gs->board[onf - 1][onr + 1], BLACK))\r
+ iscolor(gs->board[onf - 1][onr + 1], BLACK) &&
+ !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
add_pos(onf - 1, onr + 1, posf, posr, numpos);
if(gs->palace && onr >= gs->ranks/2 && (gs->board[onf-1][onr] || iscolor(gs->board[onf-1][onr], BLACK)))
add_pos(onf - 1, onr, posf, posr, numpos); // XQ promoted pawn
}\r
if (onf < gs->files-1) {
if (gs->board[onf + 1][onr + 1] != NOPIECE &&\r
- iscolor(gs->board[onf + 1][onr + 1], BLACK))\r
+ iscolor(gs->board[onf + 1][onr + 1], BLACK) &&
+ !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
add_pos(onf + 1, onr + 1, posf, posr, numpos);
if(gs->palace && onr >= gs->ranks/2 && (gs->board[onf+1][onr] || iscolor(gs->board[onf+1][onr], BLACK)))
add_pos(onf + 1, onr, posf, posr, numpos); // XQ promoted pawn
if (gs->ep_possible[0][onf] == 1)\r
add_pos(onf + 1, onr + 1, posf, posr, numpos);
} else {\r
- if (gs->board[onf][onr - 1] == NOPIECE || gs->palace) {\r
+ if (gs->board[onf][onr - 1] == NOPIECE || gs->palace || gs->promoType == 3) {\r
add_pos(onf, onr - 1, posf, posr, numpos);\r
if ((onr >= gs->ranks - gs->pawnDblStep - 1) && (gs->board[onf][onr - 2] == NOPIECE))\r
add_pos(onf, onr - 2, posf, posr, numpos);\r
}\r
if (onf > 0) {
if (gs->board[onf - 1][onr - 1] != NOPIECE &&\r
- iscolor(gs->board[onf - 1][onr - 1], WHITE))\r
+ iscolor(gs->board[onf - 1][onr - 1], WHITE) &&\r
+ !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
add_pos(onf - 1, onr - 1, posf, posr, numpos);
if(gs->palace && onr < gs->ranks/2 && !iscolor(gs->board[onf-1][onr], BLACK))
add_pos(onf - 1, onr, posf, posr, numpos); // XQ promoted pawn
}\r
if (onf < gs->files-1) {
if (gs->board[onf + 1][onr - 1] != NOPIECE &&\r
- iscolor(gs->board[onf + 1][onr - 1], WHITE))\r
+ iscolor(gs->board[onf + 1][onr - 1], WHITE) &&\r
+ !gs->palace && gs->promoType != 3) // no diagonal capture in XQ and Shogi\r
add_pos(onf + 1, onr - 1, posf, posr, numpos);
if(gs->palace && onr < gs->ranks/2 && !iscolor(gs->board[onf+1][onr], BLACK))
add_pos(onf + 1, onr, posf, posr, numpos); // XQ promoted pawn
// [HGM] castle: generalized castling, fr and tr give from and to file of Rook.
sprintf(mt->moveString, mt->toRank > mt->toFile ? "o-o-o" : "o-o");
} else {
+ if(gs->promoType == 3) { // Shogi-style promotions: not just Pawns, but many pieces can promote
+ int piece = gs->board[mt->fromFile][mt->fromRank];
+ mt->piecePromotionTo = NOPIECE;
+ if(colorval(piece) == WHITE && mt->fromRank < gs->ranks - gs->ranks/3
+ && mt->toRank < gs->ranks - gs->ranks/3 ||
+ colorval(piece) == BLACK && mt->fromRank >= gs->ranks/3
+ && mt->toRank >= gs->ranks/3 )
+ promote = NOPIECE; // suppress promotion outside zone
+ if(promote) { // promotion piece determined by original, no matter what was requested
+ switch(piecetype(piece)) {
+ case PAWN:
+ case LANCE:
+ case KNIGHT:
+ case SILVER:
+ promote = GOLD; break;
+ case BISHOP:
+ promote = DRAGONHORSE; break;
+ case ROOK:
+ promote = DRAGONKING; break;
+ default: promote = NOPIECE; // not a promotion
+ }
+ } else
+ switch(piecetype(piece)) { // force mandatory promotions
+ case KNIGHT:
+ if(mt->toRank == 1 || mt->toRank == gs->files-2) promote = GOLD;
+ case PAWN:
+ case LANCE:
+ if(mt->toRank == 0 || mt->toRank == gs->files-1) promote = GOLD;
+ default: break;
+ }
+ if(promote) mt->piecePromotionTo = promote | (colorval(gs->board[mt->fromFile][mt->fromRank]));\r
+ } else
if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
!gs->palace && // [HGM] XQ: no promotions in xiangqi\r
((mt->toRank == 0) || (mt->toRank == gs->ranks-1))) {
mt->fromFile = ALG_CASTLE;
}\r
\r
- if (mt->piecePromotionTo != NOPIECE) {\r
+ if (mt->piecePromotionTo != NOPIECE) {
promote = piecetype(mt->piecePromotionTo);\r
+printf("promotion piece = %d, type = %d",mt->piecePromotionTo, promote);\r
}\r
\r
return move_calculate(gs, mt, promote);\r