return 0;
}
+static int legal_hoplite_move( struct game_state_t *gs, int ff, int fr, int tf, int tr )
+{
+ if (ff == tf) { /* Capture ? */
+ if (gs->board[tf][tr] == NOPIECE) return 0;
+ if (gs->onMove == WHITE) {
+ if(iscolor(gs->board[tf][tr],WHITE)) return 0;
+ if (tr - fr == 1) return 1;
+ } else {
+ if(iscolor(gs->board[tf][tr],BLACK)) return 0;
+ if (fr - tr == 1) return 1;
+ }
+ return 0;
+ }
+ if (ff != tf) {
+ if (gs->board[tf][tr] != NOPIECE) return 0;
+ if (gs->onMove == WHITE) {
+ if (tr == fr+1 && abs(tf-ff) == 1) return 1;
+ if (tr != fr+2 || abs(tf-ff) != 2) return 0;
+ if (fr > gs->pawnDblStep) return 0;
+ return 1;
+ } else {
+ if (tr == fr-1 && abs(tf-ff) == 1) return 1;
+ if (tr != fr-2 || abs(tf-ff) != 2) return 0;
+ if (fr < gs->ranks - 1 - gs->pawnDblStep) return 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int legal_knight_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
{
int dx, dy;
return legal_ferz_move(gs, ff, fr, tf, tr) || legal_alfil_move(gs, ff, fr, tf, tr);
}
+static int legal_lieutenant_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ return legal_modernelephant_move(gs, ff, fr, tf, tr) ||
+ fr == tr && abs(ff - tf) == 1 && gs->board[tf][tr] == NOPIECE;
+}
+
static int legal_priestess_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
{
return legal_knight_move(gs, ff, fr, tf, tr) || legal_ferz_move(gs, ff, fr, tf, tr)
}
}
+static void possible_hoplite_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ if (gs->onMove == WHITE) { // in Spartan Chess there are no white hoplites...
+ if (gs->board[onf][onr + 1] != NOPIECE &&
+ iscolor(gs->board[onf][onr + 1], BLACK)) {
+ add_pos(onf, onr + 1, posf, posr, numpos);
+ }
+ if (onf > 0) {
+ if (gs->board[onf - 1][onr + 1] == NOPIECE) {
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+ if (onf > 1 && (onr <= gs->pawnDblStep) /*&& (gs->board[onf-2][onr + 2] == NOPIECE)*/)
+ add_pos(onf - 2, onr + 2, posf, posr, numpos);
+ }
+ }
+ if (onf < gs->files-1) {
+ if (gs->board[onf + 1][onr + 1] == NOPIECE) {
+ add_pos(onf + 1, onr + 1, posf, posr, numpos);
+ if (onf < gs->files-2 && (onr <= gs->pawnDblStep) /*&& (gs->board[onf+2][onr + 2] == NOPIECE)*/)
+ add_pos(onf + 2, onr + 2, posf, posr, numpos);
+ }
+ }
+ } else {
+ if (gs->board[onf][onr - 1] != NOPIECE &&
+ iscolor(gs->board[onf][onr - 1], WHITE)) {
+ add_pos(onf, onr - 1, posf, posr, numpos);
+ }
+ if (onf > 0) {
+ if (gs->board[onf - 1][onr - 1] == NOPIECE) {
+ add_pos(onf - 1, onr - 1, posf, posr, numpos);
+ if (onf > 1 && (onr >= gs->ranks - gs->pawnDblStep - 1) /*&& (gs->board[onf - 2][onr - 2] == NOPIECE)*/)
+ add_pos(onf - 2, onr - 2, posf, posr, numpos);
+ }
+ }
+ if (onf < gs->files-1) {
+ if (gs->board[onf + 1][onr - 1] == NOPIECE) {
+ add_pos(onf + 1, onr - 1, posf, posr, numpos);
+ if (onf < gs->files-2 && (onr >= gs->ranks - gs->pawnDblStep - 1) /*&& (gs->board[onf + 2][onr - 2] == NOPIECE)*/)
+ add_pos(onf + 2, onr - 2, posf, posr, numpos);
+ }
+ }
+ }
+}
+
static void possible_knight_moves(struct game_state_t * gs,
int onf, int onr,
int *posf, int *posr, int *numpos)
possible_alfil_moves(gs, onf, onr, posf, posr, numpos);
}
+static void possible_lieutenant_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ possible_modernelephant_moves(gs, onf, onr, posf, posr, numpos);
+ if (onf < gs->files-1 && (gs->board[onf+1][onr] == NOPIECE))
+ add_pos(onf + 1, onr, posf, posr, numpos);
+ if (onf > 0 && (gs->board[onf-1][onr] == NOPIECE))
+ add_pos(onf - 1, onr, posf, posr, numpos);
+}
+
static void possible_priestess_moves(struct game_state_t * gs,
int onf, int onr,
int *posf, int *posr, int *numpos)
case PAWN:
legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
break;
+ case HOPLITE:
+ legal = legal_hoplite_move(gs, fFile, fRank, tFile, tRank);
+ break;
case KNIGHT:
legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
break;
case ROOK:
legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
break;
+ case WARLORD:
case HAWK:
case CARDINAL:
case PRINCESS:
case AMAZON:
legal = legal_amazon_move(gs, fFile, fRank, tFile, tRank);
break;
+ case CAPTAIN:
case WOODY:
legal = legal_woody_move(gs, fFile, fRank, tFile, tRank);
break;
case WAZIR:
legal = legal_wazir_move(gs, fFile, fRank, tFile, tRank);
break;
+ case LIEUTENANT:
+ legal = legal_lieutenant_move(gs, fFile, fRank, tFile, tRank);
+ break;
case ALFIL:
case ALFIL2:
legal = legal_alfil_move(gs, fFile, fRank, tFile, tRank);
case DRAGONHORSE:
legal = legal_dragonhorse_move(gs, fFile, fRank, tFile, tRank);
break;
+ case GENERAL:
case DRAGONKING:
legal = legal_dragonking_move(gs, fFile, fRank, tFile, tRank);
break;
if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
!gs->palace && // [HGM] XQ: no promotions in xiangqi
((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
+ if(promote == KING) return MOVE_ILLEGAL; // no king in normal chess
if(!promote && (mt->toRank == 0 || mt->toRank == gs->ranks-1)) { // promotion obligatory, but not specified
if(gs->promoType != 2) promote = QUEEN; else { // choose a default
for(promote=PIECES-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break;
// non-promotion can still be an option for deeper promotion zones
mt->piecePromotionTo = promote ? (promote | stm) : NOPIECE;
if(promote && gs->promoType == 2 && !gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
+ } else
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == HOPLITE) &&
+ ((mt->toRank < gs->promoZone) || (mt->toRank >= gs->ranks - gs->promoZone))) {
+ if(!promote || promote == KING) {
+ int f, r, k=0, king = gs->onMove == WHITE ? W_KING : B_KING;
+ for(r=0; r<gs->ranks;r++) for(f=0; f<gs->files; f++) k += (gs->board[f][r] == king);
+ if(k > 1) { // we already have two kings
+ if(promote == KING) return MOVE_ILLEGAL; // three kings not allowed
+ promote = WARLORD; // use strongest piece as default
+ } else promote = KING; // if no promo-piece given, this could be mate test, so test if promoting to King evades
+ } else
+ if(promote == MASTODON) promote = GENERAL; else
+ if(promote == WOODY) promote = WARLORD; else
+ if(promote == MARSHALL) promote = CAPTAIN; else
+ if(promote != LIEUTENANT) return MOVE_ILLEGAL;
+ mt->piecePromotionTo = (promote | stm);
} else if(gs->drops == 2 && promote && mt->fromRank == (stm == WHITE ? 0 : gs->ranks-1)) { // [HGM] Seirawan-style gating
int i; struct game *g = &game_globals.garray[gs->gameNum];
if(!gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified
}
}
if (kf < 0) {
- d_printf( "CHESSD: Error game with no king!\n");
- return 0;
+// d_printf( "CHESSD: Error game with no king!\n");
+ return -1;
}
for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
NextPieceLoop(gs->board, &f, &r, gs->onMove, gs->files, gs->ranks);) {
if (legal_move(gs, f, r, kf, kr)) { /* In Check? */
+ if(gs->onMove == WHITE && !strcmp(gs->variant, "spartan")) { // first king is in check, but we might have spare
+//printf("spartan K-capt %c%d%c%d\n",f+'a',r+1,kf+'a',kr+1);
+ gs->board[kf][kr] = B_MAN; // temporarily cure the check on the first King by replacing the latter;
+ r = in_check(gs);
+ gs->board[kf][kr] = B_KING; // and put it back
+//printf("duple = %d\n",r);
+ return r != 0; // if we have no second king (r = -1) or the second is also attacked (r = 1) we are in check.
+ }
return 1;
}
}
case PAWN:
possible_pawn_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
+ case HOPLITE:
+ possible_hoplite_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
case KNIGHT:
possible_knight_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
case ROOK:
possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
+ case WARLORD:
case HAWK:
case CARDINAL:
case PRINCESS:
case AMAZON:
possible_amazon_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
+ case CAPTAIN:
case WOODY:
possible_woody_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
case MODERNELEPHANT:
possible_modernelephant_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
+ case LIEUTENANT:
+ possible_lieutenant_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
case PRIESTESS:
possible_priestess_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
case DRAGONHORSE:
possible_dragonhorse_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
+ case GENERAL:
case DRAGONKING:
possible_dragonking_moves(gs, f, r, possiblef, possibler, &numpossible);
break;
}
gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
if (m->piecePromotionTo != NOPIECE) {
- gs->board[m->fromFile][m->fromRank] = PAWN |
+ int piece;
+ switch(piecetype(m->piecePromotionTo)) { // Spartan pieces came from Hoplite, Shogi is problematic
+ case KING:
+ case CAPTAIN:
+ case LIEUTENANT:
+ case WARLORD:
+ case GENERAL: piece = HOPLITE; break;
+ case DRAGONHORSE: piece = BISHOP; break;
+ case DRAGONKING: piece = ROOK; break;
+ case GOLD: // TODO: figure out what original was
+ default: piece = PAWN;
+ }
+ gs->board[m->fromFile][m->fromRank] = piece |
colorval(gs->board[m->fromFile][m->fromRank]);
}
/******************