const char *TypeStrings[NUM_GAMETYPES] = {"untimed", "blitz", "standard",
"nonstandard", "wild", "lightning",
- "bughouse"};
+ "bughouse", "gothic", "knightmate",
+ "capablanca"};
/* this method is awful! how about allocation as we need it and freeing
afterwards! */
return tstr;
}
-const char *bstr[] = {"untimed", "blitz", "standard", "non-standard", "wild", "lightning", "Bughouse"};
+const char *bstr[] = {"untimed", "blitz", "standard", "non-standard", "wild", "lightning", "Bughouse", "Gothic", "Knightmate", "Capablanca"};
const char *rstr[] = {"unrated", "rated"};
if(cat && cat[0]) {
if (!strcmp(cat, "bughouse"))
return TYPE_BUGHOUSE;
+ if (!strcmp(cat, "gothic"))
+ return TYPE_GOTHIC;
+ if (!strcmp(cat, "knightmate"))
+ return TYPE_KNIGHTMATE;
+ if (!strcmp(cat, "capablanca"))
+ return TYPE_CAPABLANCA;
if (board && board[0]) {
if (!strcmp(cat, "wild"))
return TYPE_WILD;
if ((game_globals.garray[g].status != GAME_SETUP) &&
(check_kings(&game_globals.garray[g].game_state))) {
- d_printf( "Game has invalid amount of kings. Aborting...\n");
+ d_printf( "Game has invalid number of kings. Aborting...\n");
+{ int f, r;
+d_printf("files = %d, ranks = %d\n", game_globals.garray[g].game_state.files, game_globals.garray[g].game_state.ranks);
+for(r=0; r<game_globals.garray[g].game_state.ranks; r++) {
+ for(f=0; f<game_globals.garray[g].game_state.files; f++)
+ d_printf("b[%d][%d]=%d\n",f,r,game_globals.garray[g].game_state.board[f][r]);
+}
+}
game_finish(g);
for (p = 0; p < player_globals.p_num; p++) {
sprintf(endstr, "%s checkmated",
game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
break;
+ case END_BARE:
+ sprintf(endstr, "%s bared",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_PERPETUAL:
+ sprintf(endstr, "%s perpetually checking",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
case END_RESIGN:
sprintf(endstr, "%s resigned",
game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
case END_RESIGN:
case END_FLAG:
case END_ADJWIN:
+ case END_BARE:
+ case END_PERPETUAL:
return ((game_globals.garray[g].winner == WHITE) ? symbols[0] : symbols[1]);
break;
case END_AGREEDDRAW:
"\n[Event \"%s %s %s game\"]\n"
"[Site \"%s, %s\"]\n",
config_get_tmp("SERVER_NAME"),
- rstr[game_globals.garray[g].rated], bstr[game_globals.garray[g].type],
+ rstr[game_globals.garray[g].rated], /*bstr[game_globals.garray[g].type],*/
+ game_globals.garray[g].variant, // [HGM] allow more variation in game_types
config_get_tmp("SERVER_NAME"),
config_get_tmp("SERVER_LOCATION"));
strftime(tmp, sizeof(tmp),
"[BlackElo \"%d\"]\n",
game_globals.garray[g].white_name, game_globals.garray[g].black_name, wr, br);
strcat(gameString, tmp);
+ if(game_globals.garray[g].game_state.variant[0]) { // [HGM] variant: print variant tag
+ sprintf(tmp,
+ "[Variant \"%s\"]\n",
+ game_globals.garray[g].game_state.variant);
+ strcat(gameString, tmp);
+ }
+ if(game_globals.garray[g].game_state.setup) { // [HGM] setup: print the FEN
+ sprintf(tmp,
+ "[Setup \"1\"]\n"
+ "[FEN \"%s\"]\n",
+ game_globals.garray[g].FENstartPos);
+ strcat(gameString, tmp);
+ }
sprintf(tmp,
"[TimeControl \"%d+%d\"]\n"
"[Mode \"ICS\"]\n"
col = 0;
}
strcat(gameString, tmp);
+ if(moves[i].depth > 0) { // [HGM] computer game, add {score/depth} comment
+ if ((col += sprintf(tmp, "{%s%.2f/%d} ", moves[i].score > 0 ? "+" : "",
+ moves[i].score, moves[i].depth)) > 70) {
+ strcat(gameString, "\n");
+ col = 0;
+ }
+ strcat(gameString, tmp);
+ }
}
strcat(gameString, "\n");
} else {
strcat(gameString, "\nUnrated ");
}
- strcat (gameString, TypeStrings[game_globals.garray[g].type]);
+// strcat (gameString, TypeStrings[game_globals.garray[g].type]);
+ strcat (gameString, game_globals.garray[g].variant);
strcat(gameString, " match, initial time: ");
if ((game_globals.garray[g].bInitTime != game_globals.garray[g].wInitTime) || (game_globals.garray[g].wIncrement != game_globals.garray[g].bIncrement)) { /* different starting times */
sprintf(tmp, "%d minutes, increment: %d seconds AND %d minutes, increment: %d seconds.\n\n", game_globals.garray[g].wInitTime / 600, game_globals.garray[g].wIncrement / 10, game_globals.garray[g].bInitTime / 600, game_globals.garray[g].bIncrement / 10);
sprintf(tmp, "%d minutes, increment: %d seconds.\n\n", game_globals.garray[g].wInitTime / 600, game_globals.garray[g].wIncrement / 10);
}
strcat(gameString, tmp);
+
+ if(game_globals.garray[g].game_state.setup) { // [HGM] setup: print the initial position board
+ char *q; struct game_state_t initial_gs; struct move_t ml[600]; int r, f;
+
+ initial_gs.gameNum = g;
+ initial_gs.wkrmoved = 0; // [HGM] for some reason calling reset_board_vars() does not work here
+ initial_gs.wqrmoved = 0; // so I just duplicated the code and pasted it here...
+ initial_gs.wkmoved = 0;
+ initial_gs.bkrmoved = 0;
+ initial_gs.bqrmoved = 0;
+ initial_gs.bkmoved = 0;
+ initial_gs.onMove = WHITE;
+ initial_gs.lastIrreversable = -1;
+ initial_gs.files = game_globals.garray[g].game_state.files;
+ initial_gs.ranks = game_globals.garray[g].game_state.ranks;
+ initial_gs.holdings = game_globals.garray[g].game_state.holdings;
+ strcpy(initial_gs.variant, game_globals.garray[g].game_state.variant);
+ for (f = 0; f < 2; f++) {
+ for (r = 0; r < initial_gs.files; r++)
+ initial_gs.ep_possible[f][r] = 0;
+ for (r = PAWN; r <= PIECES-1; r++)
+ initial_gs.holding[f][r-PAWN] = 0;
+ }
+ FEN_to_board(game_globals.garray[g].FENstartPos ,&initial_gs);
+
+ kludgeFlag = 1; // [HGM] setup: this is not thread safe. Must it be???
+ q = board_to_string(
+ game_globals.garray[g].white_name,
+ game_globals.garray[g].black_name,
+ game_globals.garray[g].wTime,
+ game_globals.garray[g].bTime,
+ &initial_gs,
+ ml,
+ 11,
+ WHITE, 0, 0);
+ kludgeFlag = 0;
+
+ strcat(gameString, q);
+ strcat(gameString, "\n");
+ }
sprintf(tmp, "Move %-19s%-19s\n", game_globals.garray[g].white_name, game_globals.garray[g].black_name);
strcat(gameString, tmp);
strcat(gameString, "---- ---------------- ----------------\n");
game_ended(g, (game_globals.garray[g].white == p) ? WHITE : BLACK, END_LOSTCONNECTION);
}
-int CharToPiece(char c)
+int CharToPiece(char c, char *variant)
{
+
+ if(variant) {
+ if(!strcmp(variant, "shogi")) {
+ switch(c) {
+ case 'N':
+ return W_HONORABLEHORSE;
+ case 'n':
+ return B_HONORABLEHORSE;
+ case 'L':
+ return W_LANCE;
+ case 'l':
+ return B_LANCE;
+ case 'S':
+ return W_SILVER;
+ case 's':
+ return B_SILVER;
+ case 'G':
+ return W_GOLD;
+ case 'g':
+ return B_GOLD;
+ }
+ } else if(!strcmp(variant, "xiangqi")) {
+ switch(c) {
+ case 'A':
+ return W_MANDARIN;
+ case 'a':
+ return B_MANDARIN;
+ case 'H':
+ return W_HORSE;
+ case 'h':
+ return B_HORSE;
+ case 'C':
+ return W_CANNON;
+ case 'c':
+ return B_CANNON;
+ }
+ } else if(!strcmp(variant, "super")) {
+ switch(c) {
+ case 'E':
+ return W_EMPRESS;
+ case 'e':
+ return B_EMPRESS;
+ case 'S':
+ return W_PRINCESS;
+ case 's':
+ return B_PRINCESS;
+ case 'Z':
+ return W_AMAZON;
+ case 'z':
+ return B_AMAZON;
+ case 'V':
+ return W_CENTAUR;
+ case 'v':
+ return B_CENTAUR;
+ }
+ } else if(!strcmp(variant, "spartan")) {
+ switch(c) {
+ case 'w':
+ return B_WARLORD;
+ case 'g':
+ return B_GENERAL;
+ case 'l':
+ return B_LIEUTENANT;
+ case 'c':
+ return B_CAPTAIN;
+ case 'h':
+ return B_HOPLITE;
+ }
+ }
+ }
switch (c) {
case 'P':
return W_PAWN;
return W_ROOK;
case 'r':
return B_ROOK;
+ case 'A':
+ return W_CARDINAL;
+ case 'a':
+ return B_CARDINAL;
+ case 'C':
+ return W_MARSHALL;
+ case 'c':
+ return B_MARSHALL;
+ case 'M':
+ return W_MAN;
+ case 'm':
+ return B_MAN;
case 'Q':
return W_QUEEN;
case 'q':
return B_QUEEN;
+ case 'E':
+ if(!strcmp(variant, "seirawan")) return W_ELEPHANT;
+ return W_ELEPHANT;
+ case 'e':
+ if(!strcmp(variant, "seirawan")) return B_ELEPHANT;
+ return B_ELEPHANT;
+ case 'H':
+ return W_HAWK;
+ case 'h':
+ return B_HAWK;
case 'K':
return W_KING;
case 'k':
case B_PAWN:
return 'p';
case W_KNIGHT:
+ case W_HONORABLEHORSE:
return 'N';
case B_KNIGHT:
+ case B_HONORABLEHORSE:
return 'n';
case W_BISHOP:
return 'B';
return 'R';
case B_ROOK:
return 'r';
+ case W_CARDINAL:
+ case W_MANDARIN:
+ case W_ALFIL2:
+ return 'A';
+ case B_CARDINAL:
+ case B_MANDARIN:
+ case B_ALFIL2:
+ return 'a';
+ case W_CANNON:
+ case W_MARSHALL:
+ return 'C';
+ case B_CAPTAIN:
+ case B_CANNON:
+ case B_MARSHALL:
+ return 'c';
+ case W_MAN:
+ case W_MINISTER:
+ return 'M';
+ case B_MAN:
+ case B_MINISTER:
+ return 'm';
case W_QUEEN:
return 'Q';
case B_QUEEN:
return 'q';
+ case W_SELEPHANT:
+ case W_ELEPHANT:
+ case W_EMPRESS:
+ return 'E';
+ case B_SELEPHANT:
+ case B_ELEPHANT:
+ case B_EMPRESS:
+ return 'e';
+ case W_ALFIL:
+ return 'B';
+ case B_ALFIL:
+ return 'b';
+ case W_FERZ:
+ return 'Q';
+ case B_FERZ:
+ return 'q';
+ case W_FERZ2:
+ return 'F';
+ case B_FERZ2:
+ return 'f';
+ case W_WAZIR:
+ case W_WOODY:
+ return 'W';
+ case B_WARLORD:
+ case B_WAZIR:
+ case B_WOODY:
+ return 'w';
+ case W_HAWK:
+ case W_HORSE:
+ case W_PRIESTESS:
+ case W_NIGHTRIDER:
+ return 'H';
+ case B_HAWK:
+ case B_HORSE:
+ case B_HOPLITE:
+ case B_PRIESTESS:
+ case B_NIGHTRIDER:
+ return 'h';
+ case W_SILVER:
+ case W_PRINCESS:
+ case W_MAN2:
+ return 'S';
+ case B_SILVER:
+ case B_PRINCESS:
+ case B_MAN2:
+ return 's';
+ case W_GOLD:
+ case W_MASTODON:
+ return 'G';
+ case B_GOLD:
+ case B_GENERAL:
+ case B_MASTODON:
+ return 'g';
+ case W_AMAZON:
+ return 'Z';
+ case B_AMAZON:
+ return 'z';
+ case W_CENTAUR:
+ return 'V';
+ case B_CENTAUR:
+ return 'v';
case W_KING:
return 'K';
case B_KING:
return 'k';
+ case W_LANCE:
+ return 'L';
+ case B_LIEUTENANT:
+ case B_LANCE:
+ return 'l';
default:
return ' ';
}
if (game_globals.garray[g].type == TYPE_BLITZ) {
game_globals.garray[g].white_rating = player_globals.parray[wp].b_stats.rating;
game_globals.garray[g].black_rating = player_globals.parray[bp].b_stats.rating;
- } else if (game_globals.garray[g].type == TYPE_WILD) {
+ } else if (game_globals.garray[g].type == TYPE_WILD ||
+ game_globals.garray[g].type == TYPE_KNIGHTMATE ||
+ game_globals.garray[g].type == TYPE_CAPABLANCA ||
+ game_globals.garray[g].type == TYPE_GOTHIC) {
game_globals.garray[g].white_rating = player_globals.parray[wp].w_stats.rating;
game_globals.garray[g].black_rating = player_globals.parray[bp].w_stats.rating;
} else if (game_globals.garray[g].type == TYPE_LIGHT) {
if (!fp) {
return -1;
}
- for (piece=PAWN; piece <= QUEEN; piece++) {
+ for (piece=PAWN; piece < KING; piece++) {
game_globals.garray[g].game_state.holding[0][piece-PAWN]
= game_globals.garray[g].game_state.holding[1][piece-PAWN] = 0;
}
wr = player_globals.parray[wp].b_stats.rating;
br = player_globals.parray[bp].b_stats.rating;
type[1] = 'b';
- } else if (game_globals.garray[g].type == TYPE_WILD) {
+ } else if (game_globals.garray[g].type == TYPE_WILD ||
+ game_globals.garray[g].type == TYPE_KNIGHTMATE ||
+ game_globals.garray[g].type == TYPE_CAPABLANCA ||
+ game_globals.garray[g].type == TYPE_GOTHIC) {
wr = player_globals.parray[wp].w_stats.rating;
br = player_globals.parray[bp].w_stats.rating;
type[1] = 'w';
sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR,
player_globals.parray[wp].login[0], player_globals.parray[wp].login, STATS_GAMES);
- write_g_out(g, fname, 10, isDraw, EndSymbol, player_globals.parray[wp].name, &now);
+ write_g_out(g, fname, 40, isDraw, EndSymbol, player_globals.parray[wp].name, &now);
sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR,
player_globals.parray[bp].login[0], player_globals.parray[bp].login, STATS_GAMES);
- write_g_out(g, fname, 10, isDraw, EndSymbol, player_globals.parray[bp].name, &now);
+ write_g_out(g, fname, 40, isDraw, EndSymbol, player_globals.parray[bp].name, &now);
if (isDraw)
Result = -1;
int f, r;
- for (f = 0; f < 8; f++) {
- for (r = 0; r < 8; r++) {
+ for (f = 0; f < gs->files; f++) {
+ for (r = 0; r < gs->ranks; r++) {
if (gs->board[f][r] == B_KING) blackking++;
if (gs->board[f][r] == W_KING) whiteking++;
}
}
- if (blackking == 1 && whiteking == 1) return 0; /* Perfect! */
+ if ((blackking == 1 || blackking == 2 && !strcmp(gs->variant, "spartan")) && whiteking == 1) return 0; /* Perfect! */
return -1;
}