diff options
Diffstat (limited to 'FICS/gameproc.c.orig')
-rw-r--r-- | FICS/gameproc.c.orig | 2826 |
1 files changed, 0 insertions, 2826 deletions
diff --git a/FICS/gameproc.c.orig b/FICS/gameproc.c.orig deleted file mode 100644 index 832f5c9..0000000 --- a/FICS/gameproc.c.orig +++ /dev/null @@ -1,2826 +0,0 @@ -/* gameproc.c - * - */ - -/* - fics - An internet chess server. - Copyright (C) 1993 Richard V. Nash - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -/* Revision history: - name email yy/mm/dd Change - Richard Nash 93/10/22 Created -*/ - -#include "stdinclude.h" - -#include "common.h" -#include "command.h" -#include "ficsmain.h" -#include "config.h" -#include "playerdb.h" -#include "gamedb.h" -#include "gameproc.h" -#include "movecheck.h" -#include "utils.h" -#include "ratings.h" -#include "rmalloc.h" -#include "comproc.h" -#include "matchproc.h" -#include "formula.h" -#include "eco.h" -#include "network.h" -/* #include "hostinfo.h" */ - -PUBLIC void game_ended(int g, int winner, int why) -{ - char outstr[200]; - char tmp[200]; - int p; - int rate_change = 0; - int isDraw = 0; - int whiteResult; - char winSymbol[10]; - char EndSymbol[10]; - char *NameOfWinner, *NameOfLoser; - int beingplayed = 0; /* i.e. it wasn't loaded for adjudication */ - - beingplayed = (parray[garray[g].black].game == g); - - sprintf(outstr, "\n{Game %d (%s vs. %s) ", g + 1, - parray[garray[g].white].name, - parray[garray[g].black].name); - garray[g].result = why; - garray[g].winner = winner; - if (winner == WHITE) { - whiteResult = RESULT_WIN; - strcpy(winSymbol, "1-0"); - NameOfWinner = parray[garray[g].white].name; - NameOfLoser = parray[garray[g].black].name; - } else { - whiteResult = RESULT_LOSS; - strcpy(winSymbol, "0-1"); - NameOfWinner = parray[garray[g].black].name; - NameOfLoser = parray[garray[g].white].name; - } - switch (why) { - case END_CHECKMATE: - sprintf(tmp, "%s checkmated} %s\n", NameOfLoser, winSymbol); - strcpy(EndSymbol, "Mat"); - rate_change = 1; - break; - case END_RESIGN: - sprintf(tmp, "%s resigns} %s\n", NameOfLoser, winSymbol); - strcpy(EndSymbol, "Res"); - rate_change = 1; - break; - case END_FLAG: - sprintf(tmp, "%s forfeits on time} %s\n", NameOfLoser, winSymbol); - strcpy(EndSymbol, "Fla"); - rate_change = 1; - break; - case END_STALEMATE: - sprintf(tmp, "Game drawn by stalemate} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "Sta"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_AGREEDDRAW: - sprintf(tmp, "Game drawn by mutual agreement} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "Agr"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_BOTHFLAG: - sprintf(tmp, "Game drawn because both players ran out of time} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "Fla"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_REPETITION: - sprintf(tmp, "Game drawn by repetition} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "Rep"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_50MOVERULE: - sprintf(tmp, "Game drawn by the 50 move rule} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "50"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_ADJOURN: - sprintf(tmp, "Game adjourned by mutual agreement} *\n"); - game_save(g); - break; - case END_LOSTCONNECTION: - sprintf(tmp, "%s lost connection; game ", NameOfWinner); - if (parray[garray[g].white].registered && parray[garray[g].black].registered) { - sprintf(tmp, "adjourned} *\n"); - game_save(g); - } else - sprintf(tmp, "aborted} *\n"); - whiteResult = RESULT_ABORT; - break; - case END_ABORT: - sprintf(tmp, "Game aborted by mutual agreement} *\n"); - whiteResult = RESULT_ABORT; - break; - case END_COURTESY: - sprintf(tmp, "Game courtesyaborted by %s} *\n", NameOfWinner); - whiteResult = RESULT_ABORT; - break; - case END_COURTESYADJOURN: - sprintf(tmp, "Game courtesyadjourned by %s} *\n", NameOfWinner); - game_save(g); - break; - case END_NOMATERIAL: - /* Draw by insufficient material (e.g., lone K vs. lone K) */ - sprintf(tmp, "Neither player has mating material} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "NM "); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_FLAGNOMATERIAL: - sprintf(tmp, "%s ran out of time and %s has no material to mate} 1/2-1/2\n", - NameOfLoser, NameOfWinner); - isDraw = 1; - strcpy(EndSymbol, "TM "); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_ADJWIN: - sprintf(tmp, "%s wins by adjudication} %s\n", NameOfWinner, winSymbol); - strcpy(EndSymbol, "Adj"); - rate_change = 1; - break; - case END_ADJDRAW: - sprintf(tmp, "Game drawn by adjudication} 1/2-1/2\n"); - isDraw = 1; - strcpy(EndSymbol, "Adj"); - rate_change = 1; - whiteResult = RESULT_DRAW; - break; - case END_ADJABORT: - sprintf(tmp, "Game aborted by adjudication} *\n"); - whiteResult = RESULT_ABORT; - break; - default: - sprintf(tmp, "Hmm, the game ended and I don't know why} *\n"); - break; - } - strcat(outstr, tmp); - if (beingplayed) { - pprintf_noformat(garray[g].white, outstr); - pprintf_noformat(garray[g].black, outstr); - - for (p = 0; p < p_num; p++) { - if ((p == garray[g].white) || (p == garray[g].black)) - continue; - if (parray[p].status != PLAYER_PROMPT) - continue; - if (!parray[p].i_game && !player_is_observe(p, g)) - continue; - pprintf_noformat(p, outstr); - pprintf_prompt(p, ""); - } - } - if ((garray[g].rated) && (rate_change)) { - /* Adjust ratings */ - rating_update(g); - if (parray[garray[g].white].network_player && - parray[garray[g].black].network_player) { - if (MailGameResult) { /* Send to ratings server */ - if (isDraw) { - /* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" : - garray[g].type == TYPE_WILD ? "wild " : "stand", " - parray[garray[g].white].name, parray[garray[g].black].name, - "draw"); */ - } else { -/* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" : garray[g].type == TYPE_WILD ? "wild " : "stand", - parray[garray[g].white].name, - parray[garray[g].black].name, - (winner == WHITE) ? parray[garray[g].white].name : - parray[garray[g].black].name); */ - } - } - } - } else { - if (beingplayed) { - pprintf(garray[g].white, "No ratings adjustment done.\n"); - pprintf(garray[g].black, "No ratings adjustment done.\n"); - } - } - if (rate_change) - game_write_complete(g, isDraw, EndSymbol); - /* Mail off the moves */ - if (parray[garray[g].white].automail) { - pcommand(garray[g].white, "mailmoves"); - } - if (parray[garray[g].black].automail) { - pcommand(garray[g].black, "mailmoves"); - } - parray[garray[g].white].num_white++; - parray[garray[g].white].lastColor = WHITE; - parray[garray[g].black].num_black++; - parray[garray[g].black].lastColor = BLACK; - parray[garray[g].white].last_opponent = garray[g].black; - parray[garray[g].black].last_opponent = garray[g].white; - if (beingplayed) { - parray[garray[g].white].game = -1; - parray[garray[g].black].game = -1; - parray[garray[g].white].opponent = -1; - parray[garray[g].black].opponent = -1; - if (garray[g].white != commanding_player) - pprintf_prompt(garray[g].white, ""); - if (garray[g].black != commanding_player) - pprintf_prompt(garray[g].black, ""); - if (parray[garray[g].white].simul_info.numBoards) { - player_simul_over(garray[g].white, g, whiteResult); - } - } - game_finish(g); -} - -PUBLIC void process_move(int p, char *command) -{ - int g; - move_t move; - int result; - unsigned now; - int len; /* loon: for lame promotion hack */ - int i; - - if (parray[p].game <0) { - pprintf(p, "You are not playing a game.\n"); - return; - } - player_decline_offers(p, -1, -PEND_SIMUL); - g = parray[p].game; - - if (garray[g].status != GAME_EXAMINE) { - if (parray[p].side != garray[g].game_state.onMove) { - pprintf(p, "It is not your move.\n"); - return; - } - if (garray[g].clockStopped) { - pprintf(p, "Game clock is paused, use \"unpause\" to resume.\n"); - return; - } - } - if ((len = strlen(command)) > 1) { - if (command[len - 2] == '=') { - switch (tolower(command[strlen(command) - 1])) { - case 'n': - parray[p].promote = KNIGHT; - break; - case 'b': - parray[p].promote = BISHOP; - break; - case 'r': - parray[p].promote = ROOK; - break; - case 'q': - parray[p].promote = QUEEN; - break; - default: - pprintf(p, "Don't understand that move.\n"); - return; - break; - } - } - } - switch (parse_move(command, &garray[g].game_state, &move, parray[p].promote)) { - case MOVE_ILLEGAL: - pprintf(p, "Illegal move.\n"); - return; - break; - case MOVE_AMBIGUOUS: - pprintf(p, "Ambiguous move.\n"); - return; - break; - default: - break; - } - - if (garray[g].status == GAME_EXAMINE) { - garray[g].numHalfMoves++; - if (garray[g].numHalfMoves > garray[g].examMoveListSize) { - garray[g].examMoveListSize += 20; /* Allocate 20 moves at a time */ - if (!garray[g].examMoveList) { - garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize); - } else { - garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize); - } - } - result = execute_move(&garray[g].game_state, &move, 1); - move.atTime = now; - move.tookTime = 0; - garray[g].examMoveList[garray[g].numHalfMoves - 1] = move; - /* roll back time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - - } else { /* real game */ - i = parray[p].opponent; - if (parray[i].simul_info.numBoards && - (parray[i].simul_info.boards[parray[i].simul_info.onBoard] != g)) { - pprintf(p, "It isn't your turn: wait until the simul giver is at your board.\n"); - return; - } -#ifdef TIMESEAL - - - if (con[parray[p].socket].timeseal) { /* does he use timeseal? */ - if (parray[p].side == WHITE) { - garray[g].wLastRealTime = garray[g].wRealTime; - garray[g].wTimeWhenMoved = con[parray[p].socket].time; - if (((garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove) < 0) || - (garray[g].wTimeWhenReceivedMove == 0)) { - /* might seem weird - but could be caused by a person moving BEFORE - he receives the board pos (this is possible due to lag) but it's - safe to say he moved in 0 secs :-) */ - garray[g].wTimeWhenReceivedMove = garray[g].wTimeWhenMoved; - } else { - garray[g].wRealTime -= garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove; - } - } else if (parray[p].side == BLACK) { - garray[g].bLastRealTime = garray[g].bRealTime; - garray[g].bTimeWhenMoved = con[parray[p].socket].time; - if (((garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove) < 0) || - (garray[g].bTimeWhenReceivedMove == 0)) { - /* might seem weird - but could be caused by a person moving BEFORE - he receives the board pos (this is possible due to lag) but it's - safe to say he moved in 0 secs :-) */ - garray[g].bTimeWhenReceivedMove = garray[g].bTimeWhenMoved; - } else { - garray[g].bRealTime -= garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove; - } - } - } - if (parray[p].side == WHITE) { - /* we need to reset the opp's time for receiving the board since the - timeseal decoder only alters the time if it's 0 Otherwise the time - would be changed if the player did a refresh which would screw up - the timings */ - garray[g].bTimeWhenReceivedMove = 0; - } else { - /* we need to reset the opp's time for receiving the board since the - timeseal decoder only alters the time if it's 0 Otherwise the time - would be changed if the player did a refresh which would screw up - the timings */ - garray[g].wTimeWhenReceivedMove = 0; - } - -#endif - - game_update_time(g); - - /* maybe add autoflag here in the future? */ - -#ifdef TIMESEAL - - if (con[parray[p].socket].timeseal) { /* does he use timeseal? */ - if (parray[p].side == WHITE) { - garray[g].wRealTime += garray[g].wIncrement * 100; - garray[g].wTime = garray[g].wRealTime / 100; /* remember to conv to - tenth secs */ - } else if (parray[p].side == BLACK) { - garray[g].bRealTime += garray[g].bIncrement * 100; /* conv to ms */ - garray[g].bTime = garray[g].bRealTime / 100; /* remember to conv to - tenth secs */ - } - } else { - if (garray[g].game_state.onMove == BLACK) { - garray[g].bTime += garray[g].bIncrement; - } - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += garray[g].wIncrement; - } - } - -#else - - if (garray[g].game_state.onMove == BLACK) { - garray[g].bTime += garray[g].bIncrement; - } - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += garray[g].wIncrement; - } -#endif - - /* Do the move */ - garray[g].numHalfMoves++; - if (garray[g].numHalfMoves > garray[g].moveListSize) { - garray[g].moveListSize += 20; /* Allocate 20 moves at a time */ - if (!garray[g].moveList) { - garray[g].moveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].moveListSize); - } else { - garray[g].moveList = (move_t *) rrealloc(garray[g].moveList, sizeof(move_t) * garray[g].moveListSize); - } - } - result = execute_move(&garray[g].game_state, &move, 1); - now = tenth_secs(); - move.atTime = now; - if (garray[g].numHalfMoves > 1) { - move.tookTime = move.atTime - garray[g].lastMoveTime; - } else { - move.tookTime = move.atTime - garray[g].startTime; - } - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - -#ifdef TIMESEAL - - if (con[parray[p].socket].timeseal) { /* does he use timeseal? */ - if (parray[p].side == WHITE) { - move.tookTime = (garray[parray[p].game].wTimeWhenMoved - - garray[parray[p].game].wTimeWhenReceivedMove) / 100; - } else { - move.tookTime = (garray[parray[p].game].bTimeWhenMoved - - garray[parray[p].game].bTimeWhenReceivedMove) / 100; - } - } -#endif - - garray[g].moveList[garray[g].numHalfMoves - 1] = move; - } - - send_boards(g); - - strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g)); - - if (result == MOVE_ILLEGAL) { - pprintf(p, "Internal error, illegal move accepted!\n"); - } - if ((result == MOVE_OK) && (garray[g].status == GAME_EXAMINE)) { - int p1; - - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf_prompt(p1, "%s moves: %s\n", parray[p].name, move.algString); - } - } - } - if (result == MOVE_CHECKMATE) { - if (garray[g].status == GAME_EXAMINE) { - int p1; - - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "%s has been checkmated.\n", - (CToggle(garray[g].game_state.onMove) == BLACK) ? "White" : "Black"); - } - } - } else { - game_ended(g, CToggle(garray[g].game_state.onMove), END_CHECKMATE); - } - } - if (result == MOVE_STALEMATE) { - if (garray[g].status == GAME_EXAMINE) { - int p1; - - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "Stalemate.\n"); - } - } - } else { - game_ended(g, CToggle(garray[g].game_state.onMove), END_STALEMATE); - } - } - if (result == MOVE_NOMATERIAL) { - if (garray[g].status == GAME_EXAMINE) { - int p1; - - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "No mating material.\n"); - } - } - } else { - game_ended(g, CToggle(garray[g].game_state.onMove), END_NOMATERIAL); - } - } -} - -int GameNumFromParam(int p, int *p1, parameter *param) -{ - if (param->type == TYPE_WORD) { - *p1 = player_find_part_login(param->val.word); - if (*p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param->val.word); - return -1; - } - if (parray[*p1].game <0) - pprintf(p, "%s is not playing a game.\n", parray[*p1].name); - return parray[*p1].game; - } else { /* Must be an integer */ - *p1 = -1; - if (param->val.integer <= 0) - pprintf(p, "%d is not a valid game number.\n", param->val.integer); - return param->val.integer - 1; - } -} - -PUBLIC int com_resign(int p, param_list param) -{ - int g, o, oconnected, confused = 0; - - if (param[0].type == TYPE_NULL) { - g = parray[p].game; - if ((g < 0) || (garray[g].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - } else { - player_decline_offers(p, -1, -1); - game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN); - } - } else if (FindPlayer(p, ¶m[0], &o, &oconnected)) { - g = game_new(); - if (game_read(g, p, o) < 0) { - if (game_read(g, o, p) < 0) { - confused = 1; - pprintf(p, "You have no stored game with %s\n", parray[o].name); - } else { - garray[g].white = o; - garray[g].black = p; - } - } else { - garray[g].white = p; - garray[g].black = o; - } - if (!confused) { - pprintf(p, "You resign your stored game with %s\n", parray[o].name); - game_delete(garray[g].white, garray[g].black); - game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN); - pcommand(p, "message %s I have resigned our stored game \"%s vs. %s.\"", - parray[o].name, - parray[garray[g].white].name, - parray[garray[g].black].name); - if (!oconnected) - player_remove(o); - } - } - return COM_OK; -} - -/* -PUBLIC int com_resign(int p, param_list param) -{ - ASSERT(param[0].type == TYPE_NULL); - if ((parray[p].game <0) || (garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -1); - game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_RESIGN); - return COM_OK; -} -*/ - -PUBLIC int com_draw(int p, param_list param) -{ - int p1; - int move_num = 0; - int i = 0, flag = 0; - - ASSERT(param[0].type == TYPE_NULL); - if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - if (garray[parray[p].game].numHalfMoves - ((garray[parray[p].game].game_state.lastIrreversable == -1) ? 0 : garray[parray[p].game].game_state.lastIrreversable) > 99) { - game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_50MOVERULE); - return COM_OK; - } - if (garray[parray[p].game].game_state.lastIrreversable != -1) - move_num = garray[parray[p].game].game_state.lastIrreversable; - - for (i = (garray[parray[p].game].numHalfMoves - 1); i <= garray[parray[p].game].numHalfMoves; i++) { - flag = 0; - if (garray[parray[p].game].game_state.lastIrreversable != -1) - move_num = garray[parray[p].game].game_state.lastIrreversable; - for (; move_num <= garray[parray[p].game].numHalfMoves; move_num++) { - if ((strlen(garray[parray[p].game].boardList[move_num])) != - (strlen(garray[parray[p].game].boardList[i]))) - continue; - - if (!strcmp(garray[parray[p].game].boardList[move_num], - garray[parray[p].game].boardList[i])) - flag++; - } - if (flag >= 3) { - if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) { - player_remove_request(parray[p].opponent, p, PEND_DRAW); - player_decline_offers(p, -1, -1); - } - game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_REPETITION); - return COM_OK; - } - } - - p1 = parray[p].opponent; - if (parray[p1].simul_info.numBoards && - parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != - parray[p].game) { - pprintf(p, "You can only make requests when the simul player is at your board.\n"); - return COM_OK; - } - if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) { - player_remove_request(parray[p].opponent, p, PEND_DRAW); - player_decline_offers(p, -1, -1); - game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_AGREEDDRAW); - } else { - pprintf(parray[p].opponent, "\n"); - pprintf_highlight(parray[p].opponent, "%s", parray[p].name); - pprintf_prompt(parray[p].opponent, " offers you a draw.\n"); - pprintf(p, "Draw request sent.\n"); - player_add_request(p, parray[p].opponent, PEND_DRAW, 0); - } - return COM_OK; -} - -PUBLIC int com_pause(int p, param_list param) -{ - int g; - int now; - - ASSERT(param[0].type == TYPE_NULL); - if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - g = parray[p].game; - if (garray[g].wTime == 0) { - pprintf(p, "You can't pause untimed games.\n"); - return COM_OK; - } - if (garray[g].clockStopped) { - pprintf(p, "Game is already paused, use \"unpause\" to resume.\n"); - return COM_OK; - } - if (player_find_pendfrom(p, parray[p].opponent, PEND_PAUSE) >= 0) { - player_remove_request(parray[p].opponent, p, PEND_PAUSE); - garray[g].clockStopped = 1; - /* Roll back the time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - pprintf_prompt(parray[p].opponent, "\n%s accepted pause. Game clock paused.\n", - parray[p].name); - pprintf(p, "Game clock paused.\n"); - } else { - pprintf(parray[p].opponent, "\n"); - pprintf_highlight(parray[p].opponent, "%s", parray[p].name); - pprintf_prompt(parray[p].opponent, " requests to pause the game.\n"); - pprintf(p, "Pause request sent.\n"); - player_add_request(p, parray[p].opponent, PEND_PAUSE, 0); - } - return COM_OK; -} - -PUBLIC int com_unpause(int p, param_list param) -{ - int now; - int g; - - ASSERT(param[0].type == TYPE_NULL); - if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - g = parray[p].game; - if (!garray[g].clockStopped) { - pprintf(p, "Game is not paused.\n"); - return COM_OK; - } - garray[g].clockStopped = 0; - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - pprintf(p, "Game clock resumed.\n"); - pprintf_prompt(parray[p].opponent, "\nGame clock resumed.\n"); - return COM_OK; -} - -PUBLIC int com_abort(int p, param_list param) -{ - int p1, g, myColor, yourColor; - - ASSERT(param[0].type == TYPE_NULL); - - g = parray[p].game; - if ((g < 0) || (garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - p1 = parray[p].opponent; - myColor = (p == garray[g].white ? WHITE : BLACK); - yourColor = (myColor == WHITE ? BLACK : WHITE); - - if (parray[p1].simul_info.numBoards && - parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) { - pprintf(p, "You can only make requests when the simul player is at your board.\n"); - return COM_OK; - } - if (player_find_pendfrom(p, p1, PEND_ABORT) >= 0) { - player_remove_request(p1, p, PEND_ABORT); - player_decline_offers(p, -1, -1); - game_ended(g, yourColor, END_ABORT); - } else { - game_update_time(g); - -#ifdef TIMESEAL - - if (con[parray[parray[p].opponent].socket].timeseal) { /* opp uses timeseal? */ - - /* If opponent has timeseal - we have no use for courtesyabort since - courtesyabort was used when opponent lagged out of time which cannot - happen with timeseal - only courtesyadjourn should be possible. - Thus: the request can only be for a normal abort of the game. */ - - pprintf(p1, "\n"); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf_prompt(p1, " would like to abort the game.\n"); - pprintf(p, "Abort request sent.\n"); - player_add_request(p, p1, PEND_ABORT, 0); - } else { - if ((myColor == WHITE && garray[g].wTime > 0 && garray[g].bTime <= 0) - || (myColor == BLACK && garray[g].bTime > 0 && garray[g].wTime <= 0)) { - /* player wants to abort + opponent is out of time = courtesyabort */ - pprintf(p, "Since you have time, and your opponent has none, the game has been aborted."); - pprintf(p1, "Your opponent has aborted the game rather than calling your flag."); - player_decline_offers(p, -1, -1); - game_ended(g, myColor, END_COURTESY); - } else { - pprintf(p1, "\n"); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf_prompt(p1, " would like to abort the game.\n"); - pprintf(p, "Abort request sent.\n"); - player_add_request(p, p1, PEND_ABORT, 0); - } - } - -#else - - if ((myColor == WHITE && garray[g].wTime > 0 && garray[g].bTime <= 0) - || (myColor == BLACK && garray[g].bTime > 0 && garray[g].wTime <= 0)) { - /* player wants to abort + opponent is out of time = courtesyabort */ - pprintf(p, "Since you have time, and your opponent has none, the game has been aborted."); - pprintf(p1, "Your opponent has aborted the game rather than calling your flag."); - player_decline_offers(p, -1, -1); - game_ended(g, myColor, END_COURTESY); - } else { - pprintf(p1, "\n"); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf(p1, " would like to abort the game; "); - pprintf_prompt(p1, "type \"abort\" to accept.\n"); - pprintf(p, "Abort request sent.\n"); - player_add_request(p, p1, PEND_ABORT, 0); - } - -#endif - - } - return COM_OK; -} - -#if 0 -int Courtesy(int p, int type) -{ - int g; - - if (parray[p].game <0) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - g = parray[p].game; - if (garray[g].wInitTime == 0) { - if (type == END_COURTESY) - pprintf(p, "You can't courtesy abort an untimed game, just resign.\n"); - else if (type == END_COURTESYADJOURN) - pprintf(p, "You can't courtesy adjourn an untimed game, just resign.\n"); - return COM_OK; - } - game_update_time(g); - if (((garray[g].white == p) && (garray[g].bTime <= 0) && (garray[g].wTime > 0)) || - ((garray[g].black == p) && (garray[g].wTime <= 0) && (garray[g].bTime > 0))) { - player_decline_offers(p, -1, -1); - game_ended(parray[p].game, (garray[g].white == p) ? WHITE : BLACK, type); - } else { - if (type == END_COURTESY) - pprintf(p, "Game not aborted.\n"); - else if (type == END_COURTESYADJOURN) - pprintf(p, "Game not adjourned.\n"); - pprintf(p, "Either your opponent still has time, or you are out of time also.\n"); - } - return COM_OK; -} - -PUBLIC int com_courtesyabort(int p, param_list param) -{ - ASSERT(param[0].type == TYPE_NULL); - return Courtesy(p, END_COURTESY); -} - -PUBLIC int com_courtesyadjourn(int p, param_list param) -{ - ASSERT(param[0].type == TYPE_NULL); - if (!garray[parray[p].game].rated) { - pprintf(p, "You cannot adjourn an unrated game. Use \"courtesyabort\".\n"); - return COM_OK; - } - return Courtesy(p, END_COURTESYADJOURN); -} -#endif - -PUBLIC int com_courtesyabort(int p, param_list param) -{ - pprintf(p, "Courtesyabort is obsolete; use \"abort\" instead.\n"); - return COM_OK; -} - -PUBLIC int com_courtesyadjourn(int p, param_list param) -{ - pprintf(p, "Use \"adjourn\" to courtesyadjourn a game.\n"); - return COM_OK; -} - -PRIVATE int player_has_mating_material(game_state_t *gs, int color) -{ - int i, j; - int piece; - int minor_pieces = 0; - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) { - piece = gs->board[i][j]; - switch (piecetype(piece)) { - case BISHOP: - case KNIGHT: - if (iscolor(piece, color)) - minor_pieces++; - break; - case KING: - case NOPIECE: - break; - default: - if (iscolor(piece, color)) - return 1; - } - } - return ((minor_pieces > 1) ? 1 : 0); -} - -PUBLIC int com_flag(int p, param_list param) -{ - int g; - int myColor; - - ASSERT(param[0].type == TYPE_NULL); - if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - g = parray[p].game; - myColor = (p == garray[g].white ? WHITE : BLACK); - if (garray[g].wInitTime == 0) { - pprintf(p, "You can't flag an untimed game.\n"); - return COM_OK; - } - if (garray[g].numHalfMoves < 2) { - pprintf(p, "You cannot flag if your opponent has not moved.\nYou can use abort instead.\n"); - return COM_OK; - } - game_update_time(g); - -#ifdef TIMESEAL - - { - int wt, bt; - - if (con[parray[p].socket].timeseal) { /* do caller use timeseal? */ - if (myColor == WHITE) { - wt = garray[g].wRealTime; - } else { - bt = garray[g].bRealTime; - } - } else { - if (myColor == WHITE) { - wt = garray[g].wTime; - } else { - bt = garray[g].bTime; - } - } - - if (con[parray[parray[p].opponent].socket].timeseal) { /* opp uses timeseal? */ - if (myColor == WHITE) { - bt = garray[g].bRealTime; - } else { - wt = garray[g].wRealTime; - } - } else { - if (myColor == WHITE) { - bt = garray[g].bTime; - } else { - wt = garray[g].wTime; - } - } - - /* the clocks to compare is now in wt and bt */ - - if ((wt <= 0) && (bt <= 0)) { - player_decline_offers(p, -1, -1); - game_ended(g, myColor, END_BOTHFLAG); - return COM_OK; - } - if (myColor == WHITE) { - if (bt > 0) { - pprintf(p, "Your opponent is not out of time!\n"); - return COM_OK; - } - } else { - if (wt > 0) { - pprintf(p, "Your opponent is not out of time!\n"); - return COM_OK; - } - } - } - -#else - - if ((garray[g].wTime <= 0) && (garray[g].bTime <= 0)) { - player_decline_offers(p, -1, -1); - game_ended(g, myColor, END_BOTHFLAG); - return COM_OK; - } - if (myColor == WHITE) { - if (garray[g].bTime > 0) { - pprintf(p, "Your opponent is not out of time!\n"); - return COM_OK; - } - } else { - if (garray[g].wTime > 0) { - pprintf(p, "Your opponent is not out of time!\n"); - return COM_OK; - } - } - -#endif - - player_decline_offers(p, -1, -1); - if (player_has_mating_material(&garray[g].game_state, myColor)) - game_ended(g, myColor, END_FLAG); - else - game_ended(g, myColor, END_FLAGNOMATERIAL); - return COM_OK; -} - -PUBLIC int com_adjourn(int p, param_list param) -{ - int p1, g, myColor, yourColor; - - ASSERT(param[0].type == TYPE_NULL); - g = parray[p].game; - if ((g < 0) || (garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - p1 = parray[p].opponent; - if (!(parray[p].registered && parray[p1].registered)) { - pprintf(p, "Both players must be registered to adjorn a game. Use \"abort\".\n"); - return COM_OK; - } - myColor = (p == garray[g].white ? WHITE : BLACK); - yourColor = (myColor == WHITE ? BLACK : WHITE); - - if (player_find_pendfrom(p, p1, PEND_ADJOURN) >= 0) { - player_remove_request(p1, p, PEND_ADJOURN); - player_decline_offers(p, -1, -1); - game_ended(parray[p].game, yourColor, END_ADJOURN); - } else { - game_update_time(g); - if (((myColor == WHITE) && (garray[g].wTime > 0) && (garray[g].bTime <= 0)) - || ((myColor == BLACK) && (garray[g].bTime > 0) && (garray[g].wTime <= 0))) { -/* player wants to adjourn + opponent is out of time = courtesyadjourn */ - pprintf(p, "Since you have time, and your opponent has none, the game has been adjourned."); - pprintf(p1, "Your opponent has adjourned the game rather than calling your flag."); - player_decline_offers(p, -1, -1); - game_ended(g, myColor, END_COURTESYADJOURN); - } else { - pprintf(p1, "\n"); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf(p1, " would like to adjourn the game; "); - pprintf_prompt(p1, "type \"adjourn\" to accept.\n"); - pprintf(p, "Adjourn request sent.\n"); - player_add_request(p, p1, PEND_ADJOURN, 0); - } - } - return COM_OK; -} - -PRIVATE int gamesortfunc(const void *i, const void *j) -{ - return (GetRating(&parray[garray[*(int *) i].white], garray[*(int *) i].type) + - GetRating(&parray[garray[*(int *) i].black], garray[*(int *) i].type) + - ((garray[*(int *) i].status == GAME_EXAMINE) ? 10000 : 0) - - GetRating(&parray[garray[*(int *) j].white], garray[*(int *) j].type) - - GetRating(&parray[garray[*(int *) j].black], garray[*(int *) j].type) - - ((garray[*(int *) j].status == GAME_EXAMINE) ? 10000 : 0)); -} - - -PUBLIC int com_games(int p, param_list param) -{ - int i, j; - int wp, bp; - int ws, bs; - int selected = 0; - int count = 0; - int totalcount; - char *s = NULL; - int slen = 0; - int *sortedgames; /* for qsort */ - - totalcount = game_count(); - if (totalcount == 0) { - pprintf(p, "There are no games in progress.\n"); - } else { - sortedgames = rmalloc(totalcount * sizeof(int)); /* for qsort */ - - if (param[0].type == TYPE_WORD) { - s = param[0].val.word; - slen = strlen(s); - selected = atoi(s); - if (selected < 0) - selected = 0; - } - for (i = 0; i < g_num; i++) { - if ((garray[i].status != GAME_ACTIVE) && (garray[i].status != GAME_EXAMINE)) - continue; - if ((selected) && (selected != i + 1)) - continue; /* not selected game number */ - wp = garray[i].white; - bp = garray[i].black; - if ((!selected) && s && strncasecmp(s, garray[i].white_name, slen) && - strncasecmp(s, garray[i].black_name, slen)) - continue; /* player names did not match */ - sortedgames[count++] = i; - } - if (!count) - pprintf(p, "No matching games were found (of %d in progress).\n", totalcount); - else { - qsort(sortedgames, count, sizeof(int), gamesortfunc); - pprintf(p, "\n"); - for (j = 0; j < count; j++) { - i = sortedgames[j]; - wp = garray[i].white; - bp = garray[i].black; - board_calc_strength(&garray[i].game_state, &ws, &bs); - if (garray[i].status != GAME_EXAMINE) { - pprintf_noformat(p, "%2d %4s %-11.11s %4s %-10.10s [%c%c%c%3d %3d] ", - i + 1, - ratstrii(GetRating(&parray[wp], - garray[i].type), - parray[wp].registered), - parray[wp].name, - ratstrii(GetRating(&parray[bp], - garray[i].type), - parray[bp].registered), - parray[bp].name, - (garray[i].private) ? 'p' : ' ', - *bstr[garray[i].type], - *rstr[garray[i].rated], - garray[i].wInitTime / 600, - garray[i].wIncrement / 10); - game_update_time(i); - pprintf_noformat(p, "%6s -", - tenth_str((garray[i].wTime > 0 ? garray[i].wTime : 0), 0)); - pprintf_noformat(p, "%6s (%2d-%2d) %c: %2d\n", - tenth_str((garray[i].bTime > 0 ? garray[i].bTime : 0), 0), - ws, bs, - (garray[i].game_state.onMove == WHITE) ? 'W' : 'B', - garray[i].game_state.moveNum); - } else { - pprintf_noformat(p, "%2d (Exam. %4d %-11.11s %4d %-10.10s) [%c%c%c%3d %3d] ", - i + 1, - garray[i].white_rating, - garray[i].white_name, - garray[i].black_rating, - garray[i].black_name, - (garray[i].private) ? 'p' : ' ', - *bstr[garray[i].type], - *rstr[garray[i].rated], - garray[i].wInitTime / 600, - garray[i].wIncrement / 10); - pprintf_noformat(p, "%c: %2d\n", - (garray[i].game_state.onMove == WHITE) ? 'W' : 'B', - garray[i].game_state.moveNum); - } - } - if (count < totalcount) - pprintf(p, "\n %d game%s displayed (of %d in progress).\n", count, - (count == 1) ? "" : "s", totalcount); - else - pprintf(p, "\n %d game%s displayed.\n", totalcount, (totalcount == 1) ? "" : "s"); - } - rfree(sortedgames); - } - return COM_OK; -} - -PRIVATE int do_observe(int p, int obgame) -{ - if ((garray[obgame].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, game %d is a private game.\n", obgame + 1); - return COM_OK; - } - if ((garray[obgame].white == p) || (garray[obgame].black == p)) { - if (garray[obgame].status != GAME_EXAMINE) { - pprintf(p, "You cannot observe a game that you are playing.\n"); - return COM_OK; - } - } - if (player_is_observe(p, obgame)) { - pprintf(p, "Removing game %d from observation list.\n", obgame + 1); - player_remove_observe(p, obgame); - } else { - if (!player_add_observe(p, obgame)) { - pprintf(p, "You are now observing game %d.\n", obgame + 1); - send_board_to(obgame, p); - } else { - pprintf(p, "You are already observing the maximum number of games.\n"); - } - } - return COM_OK; -} - -PUBLIC void unobserveAll(int p) -{ - int i; - - for (i = 0; i < parray[p].num_observe; i++) { - pprintf(p, "Removing game %d from observation list.\n", parray[p].observe_list[i] + 1); - } - parray[p].num_observe = 0; - return; -} - -PUBLIC int com_unobserve(int p, param_list param) -{ - int gNum, p1; - - if (param[0].type == TYPE_NULL) { - unobserveAll(p); - return COM_OK; - } - gNum = GameNumFromParam(p, &p1, ¶m[0]); - if (gNum < 0) - return COM_OK; - if (!player_is_observe(p, gNum)) { - pprintf(p, "You are not observing game %d.\n", gNum); - } else { - player_remove_observe(p, gNum); - pprintf(p, "Removing game %d from observation list.\n", gNum + 1); - } - return COM_OK; -} - -PUBLIC int com_observe(int p, param_list param) -{ - int i; - int p1, obgame; - - if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are still examining a game.\n"); - return COM_OK; - } - if (param[0].type == TYPE_NULL) { - unobserveAll(p); - return COM_OK; - } - obgame = GameNumFromParam(p, &p1, ¶m[0]); - if (obgame < 0) - return COM_OK; - - if ((obgame >= g_num) || ((garray[obgame].status != GAME_ACTIVE) && - (garray[obgame].status != GAME_EXAMINE))) { - pprintf(p, "There is no such game.\n"); - return COM_OK; - } - if ((p1 >= 0) && parray[p1].simul_info.numBoards) { - for (i = 0; i < parray[p1].simul_info.numBoards; i++) - if (parray[p1].simul_info.boards[i] >= 0) - do_observe(p, parray[p1].simul_info.boards[i]); - } else { - do_observe(p, obgame); - } - return COM_OK; -} - -PUBLIC int com_allobservers(int p, param_list param) -{ - int obgame; - int p1; - int start, end; - int g; - int first; - - if (param[0].type == TYPE_NULL) { - obgame = -1; - } else { - obgame = GameNumFromParam(p, &p1, ¶m[0]); - if (obgame < 0) - return COM_OK; - } - if (obgame == -1) { - start = 0; - end = g_num; - } else if ((obgame >= g_num) || ((obgame < g_num) - && ((garray[obgame].status != GAME_ACTIVE) - && (garray[obgame].status != GAME_EXAMINE)))) { - pprintf(p, "There is no such game.\n"); - return COM_OK; - } else { - start = obgame; - end = obgame + 1; - } - - /* list games being played */ - - for (g = start; g < end; g++) { - if ((garray[g].status == GAME_ACTIVE) && - ((parray[p].adminLevel > 0) || (garray[g].private == 0))) { - for (first = 1, p1 = 0; p1 < p_num; p1++) { - if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g))) { - if (first) { - pprintf(p, "Observing %2d [%s vs. %s]:", - g + 1, - parray[garray[g].white].name, - parray[garray[g].black].name); - first = 0; - } - pprintf(p, " %s%s", (parray[p1].game >=0) ? "#" : "", parray[p1].name); - } - } - if (!first) - pprintf(p, "\n"); - } - } - - /* list games being examined last */ - - for (g = start; g < end; g++) { - if ((garray[g].status == GAME_EXAMINE) && - ((parray[p].adminLevel > 0) || (garray[g].private == 0))) { - for (first = 1, p1 = 0; p1 < p_num; p1++) { - if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g) || - (parray[p1].game == g))) { - if (first) { - if (strcmp(garray[g].white_name, garray[g].black_name)) { - pprintf(p, "Examining %2d [%s vs %s]:", g + 1, - garray[g].white_name, garray[g].black_name); - } else { - pprintf(p, "Examining %2d (scratch):", g + 1); - } - first = 0; - } - pprintf(p, " %s%s", (parray[p1].game == g) ? "#" : "", parray[p1].name); - } - } - if (!first) - pprintf(p, "\n"); - } - } - return COM_OK; -} - -PUBLIC int com_unexamine(int p, param_list param) -{ - int g, p1, flag = 0; - - if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) { - pprintf(p, "You are not examining any games.\n"); - return COM_OK; - } - g = parray[p].game; - parray[p].game = -1; - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if ((parray[p1].game == g) &&(p != p1)) { - /* ok - there are other examiners to take over the game */ - flag = 1; - } - if ((player_is_observe(p1, g)) || (parray[p1].game == g)) { - pprintf(p1, "%s stopped examining game %d.\n", parray[p].name, g + 1); - } - } - if (!flag) { - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g)) { - pprintf(p1, "There are no examiners.\n"); - pcommand(p1, "unobserve %d", g + 1); - } - } - game_remove(g); - } - pprintf(p, "You are no longer examining game %d.\n", g + 1); - return COM_OK; -} - -PUBLIC int com_mexamine(int p, param_list param) -{ - int g, p1, p2; - - if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) { - pprintf(p, "You are not examining any games.\n"); - return COM_OK; - } - p1 = player_find_part_login(param[0].val.word); - if (p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word); - return COM_OK; - } - g = parray[p].game; - if (!player_is_observe(p1, g)) { - pprintf(p, "%s must observe the game you are analysing.\n", parray[p1].name); - return COM_OK; - } else { - if (parray[p1].game >=0) { - pprintf(p, "%s is already analysing the game.\n", parray[p1].name); - return COM_OK; - } - /* if we get here - let's make him examiner of the game */ - unobserveAll(p1); /* fix for Xboard */ - player_decline_offers(p1, -1, PEND_MATCH); - player_withdraw_offers(p1, -1, PEND_MATCH); - player_withdraw_offers(p1, -1, PEND_SIMUL); - - parray[p1].game = g; /* yep - it really is that easy :-) */ - pprintf(p1, "You are now examiner of game %d.\n", g + 1); - send_board_to(g, p1); /* pos not changed - but fixes Xboard */ - for (p2 = 0; p2 < p_num; p2++) { - if (parray[p2].status != PLAYER_PROMPT) - continue; - if (p2 == p1) - continue; - if ((player_is_observe(p2, g)) || (parray[p2].game == g)) { - pprintf_prompt(p2, "%s is now examiner of game %d.\n", parray[p1].name, g + 1); - } - } - } - return COM_OK; -} - -PUBLIC int com_moves(int p, param_list param) -{ - int g; - int p1; - - if (param[0].type == TYPE_NULL) { - if (parray[p].game >=0) { - g = parray[p].game; - } else if (parray[p].num_observe) { - for (g = 0; g < parray[p].num_observe; g++) { - pprintf(p, "%s\n", movesToString(parray[p].observe_list[g], 0)); - } - return COM_OK; - } else { - pprintf(p, "You are neither playing, observing nor examining a game.\n"); - return COM_OK; - } - } else { - g = GameNumFromParam(p, &p1, ¶m[0]); - if (g < 0) - return COM_OK; - } - if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) && - (garray[g].status != GAME_EXAMINE))) { - pprintf(p, "There is no such game.\n"); - return COM_OK; - } - if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - return COM_OK; - } - pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */ - return COM_OK; -} - -PUBLIC int com_mailmoves(int p, param_list param) -{ - int g; - int p1; - char subj[81]; - - if (!parray[p].registered) { - pprintf(p, "Only registered people can use the mailhelp command.\n"); - return COM_OK; - } - - if (param[0].type == TYPE_NULL) { - if (parray[p].game >=0) { - g = parray[p].game; - } else { - pprintf(p, "You are neither playing, observing nor examining a game.\n"); - return COM_OK; - } - } else { - g = GameNumFromParam(p, &p1, ¶m[0]); - if (g < 0) - return COM_OK; - } - if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) && (garray[g].status != GAME_EXAMINE))) { - pprintf(p, "There is no such game.\n"); - return COM_OK; - } - if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - return COM_OK; - } - sprintf(subj, "FICS game report %s vs %s", garray[g].white_name, garray[g].black_name); - if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) { - pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n"); - } else { - pprintf(p, "Moves mailed.\n"); - } - return COM_OK; -} - -PUBLIC int com_oldmoves(int p, param_list param) -{ - int g; - int p1 = p; - - if (param[0].type == TYPE_NULL) { - p1 = p; - } else if (param[0].type == TYPE_WORD) { - p1 = player_find_part_login(param[0].val.word); - if (p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word); - return COM_OK; - } - } - g = FindOldGameFor(p1); - if (g < 0) { - pprintf(p, "There is no old game for %s.\n", parray[p1].name); - return COM_OK; - } - if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - return COM_OK; - } - pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */ - return COM_OK; -} - -PUBLIC int com_mailoldmoves(int p, param_list param) -{ - int g; - int p1 = p; - char subj[81]; - - if (!parray[p].registered) { - pprintf(p, "Only registered people can use the mailhelp command.\n"); - return COM_OK; - } - - if (param[0].type == TYPE_NULL) { - p1 = p; - } else if (param[0].type == TYPE_WORD) { - p1 = player_find_part_login(param[0].val.word); - if (p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word); - return COM_OK; - } - } - g = FindOldGameFor(p1); - if (g < 0) { - pprintf(p, "There is no old game for %s.\n", parray[p1].name); - return COM_OK; - } - if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - return COM_OK; - } - sprintf(subj, "FICS game report %s vs %s", garray[g].white_name, garray[g].black_name); - if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) { - pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n"); - } else { - pprintf(p, "Moves mailed.\n"); - } - return COM_OK; -} - -PUBLIC int com_load(int p, param_list param) -{ - pprintf(p, "Obsolete command, please use match <opponent>.\n"); - return COM_OK; -} - -void ExamineScratch(int p) -{ - char category, board; - int g = game_new(); - - unobserveAll(p); - - player_decline_offers(p, -1, PEND_MATCH); - player_withdraw_offers(p, -1, PEND_MATCH); - player_withdraw_offers(p, -1, PEND_SIMUL); - - garray[g].wInitTime = garray[g].wIncrement = 0; - garray[g].bInitTime = garray[g].bIncrement = 0; - garray[g].timeOfStart = tenth_secs(); - garray[g].wTime = garray[g].bTime = 0; - garray[g].rated = 0; - garray[g].clockStopped = 0; - garray[g].type = TYPE_UNTIMED; - garray[g].white = garray[g].black = p; - garray[g].status = GAME_EXAMINE; - garray[g].startTime = tenth_secs(); - garray[g].lastMoveTime = garray[g].startTime; - garray[g].lastDecTime = garray[g].startTime; - garray[g].totalHalfMoves = 0; - - parray[p].side = WHITE; /* oh well... */ - parray[p].game = g; - - category = board = '\0'; - if (board_init(&garray[g].game_state, &category, &board)) { - pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n"); - fprintf(stderr, "FICS: PROBLEM LOADING BOARD. Game Aborted.\n"); - } - garray[g].game_state.gameNum = g; - strcpy(garray[g].white_name, parray[p].name); - strcpy(garray[g].black_name, parray[p].name); - - send_boards(g); - - strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g)); -} - -PRIVATE int ExamineStored(FILE * fp, int p, char *filename) -{ - int g; - char category[100], board[100]; - game *gg; - - unobserveAll(p); - - player_decline_offers(p, -1, PEND_MATCH); - player_withdraw_offers(p, -1, PEND_MATCH); - player_withdraw_offers(p, -1, PEND_SIMUL); - - g = game_new(); - gg = &garray[g]; - category[0] = '\0'; - board[0] = '\0'; - if (board_init(&gg->game_state, category, board)) { - pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n"); - fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n", - category, board); - return -1; - } - gg->status = GAME_EXAMINE; - if (ReadGameAttrs(fp, filename, g) < 0) { - pprintf(p, "Gamefile is corrupt; please notify an admin.\n"); - return -1; - } - gg->totalHalfMoves = gg->numHalfMoves; - gg->numHalfMoves = 0; - gg->revertHalfMove = 0; - gg->white = p; - gg->black = p; - gg->game_state.gameNum = g; - - gg->startTime = tenth_secs(); - gg->lastMoveTime = gg->startTime; - gg->lastDecTime = gg->startTime; - - parray[p].side = WHITE; /* oh well... */ - parray[p].game = g; - - send_boards(g); - - strcpy(gg->boardList[gg->numHalfMoves], boardToFEN(g)); - return g; -} - -void ExamineAdjourned(int p, int p1, int p2) -{ - FILE *fp; - char filename[1024]; - char *p1Login, *p2Login; - int g; - - p1Login = parray[p1].login; - p2Login = parray[p2].login; - - sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p1Login, p2Login); - fp = fopen(filename, "r"); - if (!fp) { - sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p1Login, p2Login); - fp = fopen(filename, "r"); - if (!fp) { - sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p2Login, p1Login); - fp = fopen(filename, "r"); - if (!fp) { - sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p2Login, p1Login); - fp = fopen(filename, "r"); - if (!fp) { - pprintf(p, "No stored game between \"%s\" and \"%s\".\n", - parray[p1].name, parray[p2].name); - return; - } - } - } - } - g = ExamineStored(fp, p, filename); - fclose(fp); - - if (g >= 0) { - if (garray[g].white_name[0] == '\0') - strcpy(garray[g].white_name, p1Login); - if (garray[g].black_name[0] == '\0') - strcpy(garray[g].black_name, p2Login); - } - return; -} - -char *FindHistory(int p, int p1, int game) -{ - FILE *fpHist; - static char fileName[MAX_FILENAME_SIZE]; - int index; - long when; - - sprintf(fileName, "%s/player_data/%c/%s.%s", stats_dir, - parray[p1].login[0], parray[p1].login, STATS_GAMES); - fpHist = fopen(fileName, "r"); - if (fpHist == NULL) { - pprintf(p, "No games in history for %s.\n", parray[p1].name); - return(NULL); - } - do { - fscanf(fpHist, "%d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %*s %ld", - &index, &when); - } while (!feof(fpHist) && index != game); - - if (feof(fpHist)) { - pprintf(p, "There is no history game %d for %s.\n", game, parray[p1].name); - fclose(fpHist); - return(NULL); - } - fclose(fpHist); - - sprintf(fileName, "%s/%ld/%ld", hist_dir, when % 100, when); - return(fileName); -} - -void ExamineHistory(int p, int p1, int game) -{ - char *fileName; - - fileName = FindHistory(p, p1, game); - if (fileName != NULL) { - FILE *fpGame = fopen(fileName, "r"); - if (fpGame == NULL) { - pprintf(p, "History game %d not available for %s.\n", game, parray[p1].name); - } else { - ExamineStored(fpGame, p, fileName); - } - } - return; -} - -PUBLIC int com_examine(int p, param_list param) -{ - int p1, p2 = p, p1conn, p2conn = 1; - - if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are already examining a game.\n"); - } else if (parray[p].game >=0) { - pprintf(p, "You are playing a game.\n"); - } else if (param[0].type == TYPE_NULL) { - ExamineScratch(p); - } else if (param[0].type == TYPE_WORD) { - if (!FindPlayer(p, ¶m[0], &p1, &p1conn)) - return COM_OK; - - if (param[1].type == TYPE_INT) - ExamineHistory(p, p1, param[1].val.integer); - else { - if (param[1].type == TYPE_WORD - && !FindPlayer(p, ¶m[1], &p2, &p2conn)) - return COM_OK; - - ExamineAdjourned(p, p1, p2); - if (!p2conn) - player_remove(p2); - } - if (!p1conn) - player_remove(p1); - } - return COM_OK; -} - -PUBLIC int com_stored(int p, param_list param) -{ - DIR *dirp; -#ifdef USE_DIRENT - struct dirent *dp; -#else - struct direct *dp; -#endif - int p1, connected; - char dname[MAX_FILENAME_SIZE]; -#if 0 /* replacing all the code below with a - FindPlayer call; This stuff was buggy - anyway. */ - if (param[0].type == TYPE_WORD) { - if ((p1 = player_find_part_login(param[0].val.word)) < 0) { /* not logged in */ - connected = 0; - p1 = player_new(); - if (player_read(p1, param[0].val.word)) { - player_remove(p1); - pprintf(p, "There is no player by that name.\n"); - return COM_OK; - } - } else { - connected = 1; - } - } else { - p1 = p; - connected = 1; - } -#endif - if (!FindPlayer(p, ¶m[0], &p1, &connected)) - return COM_OK; - - sprintf(dname, "%s/%c", adj_dir, parray[p1].login[0]); - dirp = opendir(dname); - if (!dirp) { - pprintf(p, "Player %s has no games stored.\n", parray[p1].name); - if (!connected) - player_remove(p1); - return COM_OK; - } - pprintf(p, "Stored games for %s:\n", parray[p1].name); - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { - if (file_has_pname(dp->d_name, parray[p1].login)) { - pprintf(p, " %s vs. %s\n", file_wplayer(dp->d_name), file_bplayer(dp->d_name)); - } - } - - closedir(dirp); - pprintf(p, "\n"); - if (!connected) - player_remove(p1); - return COM_OK; -} - -PUBLIC int com_mailstored(int p, param_list param) -{ - int wp, wconnected, bp, bconnected, gotit = 0; - int g = -1; - - if (!FindPlayer(p, ¶m[0], &wp, &wconnected)) - return (COM_OK); - - if (param[1].type == TYPE_INT) { /* look for a game from history */ - char *fileName = FindHistory(p, wp, param[1].val.integer); - if (fileName != NULL) { - FILE *fpGame = fopen(fileName, "r"); - if (fpGame == NULL) { - pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, parray[wp].name); - } else { - g = game_new(); - if (ReadGameAttrs(fpGame, fileName, g) < 0) - pprintf(p, "Gamefile is corrupt; please notify an admin.\n"); - else - gotit = 1; - } - fclose(fpGame); - } - } else { /* look for a stored game between the players */ - if (FindPlayer(p, ¶m[1], &bp, &bconnected)) { - - g = game_new(); - if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */ - gotit = 1; - } else if (game_read(g, bp, wp) >= 0) { /* or black-white */ - gotit = 1; - } else { - pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name); - } - if (!bconnected) - player_remove(bp); - } - } - - if (gotit) { - if (strcasecmp(parray[p].name, garray[g].white_name) && strcasecmp(parray[p] -.name, garray[g].black_name) && garray[g].private && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - } else { - char subj[81]; - if (param[1].type == TYPE_INT) - sprintf(subj, "FICS history game: %s %d", parray[wp].name, param[1].val.integer); - else - sprintf(subj, "FICS adjourned game %s vs %s", garray[g].white_name, garray[g].black_name); - if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) - pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n"); - else - pprintf(p, "Moves mailed.\n"); - } - } - if (!wconnected) - player_remove(wp); - if (g != -1) - game_remove(g); - return(COM_OK); -} - -/* it would be good to write a FindStored and nuke all the game_read(foo,bar) - game_read(bar,foo) etc. this stuff is a mess... */ - -PUBLIC int com_smoves(int p, param_list param) -{ - int wp, wconnected, bp, bconnected, gotit = 0; - int g = -1; - - if (!FindPlayer(p, ¶m[0], &wp, &wconnected)) - return(COM_OK); - - if (param[1].type == TYPE_INT) { -/* look for a game from history */ - char *fileName = FindHistory(p, wp, param[1].val.integer); - if (fileName != NULL) { - FILE *fpGame = fopen(fileName, "r"); - if (fpGame == NULL) { - pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, parray[wp].name); - } else { - g = game_new(); - if (ReadGameAttrs(fpGame, fileName, g) < 0) { - pprintf(p, "Gamefile is corrupt; please notify an admin.\n"); - } else { - gotit = 1; - } - } - fclose(fpGame); - } - } else { -/* look for a stored game between the players */ - if (FindPlayer(p, ¶m[1], &bp, &bconnected)) { - - g = game_new(); - if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */ - gotit = 1; - } else if (game_read(g, bp, wp) >= 0) { /* or black-white */ - gotit = 1; - } else { - pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name); - } - if (!bconnected) - player_remove(bp); - } - } - - if (gotit) { - if (strcasecmp(parray[p].name, garray[g].white_name) && strcasecmp(parray[p].name, garray[g].black_name) && garray[g].private && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - } else { - pprintf(p, "%s\n", movesToString(g, 0)); - } - } - if (!wconnected) - player_remove(wp); - if (g != -1) - game_remove(g); - return(COM_OK); -} - -PUBLIC int com_sposition(int p, param_list param) -{ - int wp, wconnected, bp, bconnected, confused = 0; - int g; - - if (!FindPlayer(p, ¶m[0], &wp, &wconnected)) - return (COM_OK); - if (!FindPlayer(p, ¶m[1], &bp, &bconnected)) - return COM_OK; - - g = game_new(); - if (game_read(g, wp, bp) < 0) { /* if no game white-black, */ - if (game_read(g, bp, wp) < 0) { /* look for black-white */ - confused = 1; - pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name); - } else { - int tmp; - tmp = wp; - wp = bp; - bp = tmp; - tmp = wconnected; - wconnected = bconnected; - bconnected = tmp; - } - } - if (!confused) { - if ((wp != p) && (bp != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) { - pprintf(p, "Sorry, that is a private game.\n"); - } else { - garray[g].white = wp; - garray[g].black = bp; - garray[g].startTime = tenth_secs(); - garray[g].lastMoveTime = garray[g].startTime; - garray[g].lastDecTime = garray[g].startTime; - pprintf(p, "Position of stored game %s vs. %s\n", parray[wp].name, parray[bp].name); - send_board_to(g, p); - } - } - game_remove(g); - if (!wconnected) - player_remove(wp); - if (!bconnected) - player_remove(bp); - return COM_OK; -} - -PUBLIC int com_forward(int p, param_list param) -{ - int nHalfMoves = 1; - int g, i; - int p1; - unsigned now; - - if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) { - pprintf(p, "You are not examining any games.\n"); - return COM_OK; - } - g = parray[p].game; - if (!strcmp(garray[g].white_name, garray[g].black_name)) { - pprintf(p, "You cannot go forward; no moves are stored.\n"); - return COM_OK; - } - if (param[0].type == TYPE_INT) { - nHalfMoves = param[0].val.integer; - } - if (garray[g].numHalfMoves > garray[g].revertHalfMove) { - pprintf(p, "No more moves.\n"); - return COM_OK; - } - if (garray[g].numHalfMoves < garray[g].totalHalfMoves) { - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "%s goes forward %d move%s.\n", - parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s"); - } - } - } - for (i = 0; i < nHalfMoves; i++) { - if (garray[g].numHalfMoves < garray[g].totalHalfMoves) { - execute_move(&garray[g].game_state, &garray[g].moveList[garray[g].numHalfMoves], 1); - if (garray[g].numHalfMoves + 1 > garray[g].examMoveListSize) { - garray[g].examMoveListSize += 20; /* Allocate 20 moves at a - time */ - if (!garray[g].examMoveList) { - garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize); - } else { - garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize); - } - } - garray[g].examMoveList[garray[g].numHalfMoves] = garray[g].moveList[garray[g].numHalfMoves]; - garray[g].revertHalfMove++; - garray[g].numHalfMoves++; - } else { - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "End of game.\n"); - } - } - break; - } - } - /* roll back time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - return COM_OK; -} - -PUBLIC int com_backward(int p, param_list param) -{ - int nHalfMoves = 1; - int g, i; - int p1; - unsigned now; - - if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) { - pprintf(p, "You are not examining any games.\n"); - return COM_OK; - } - g = parray[p].game; - if (param[0].type == TYPE_INT) { - nHalfMoves = param[0].val.integer; - } - if (garray[g].numHalfMoves != 0) { - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "%s backs up %d move%s.\n", - parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s"); - } - } - } - for (i = 0; i < nHalfMoves; i++) { - if (backup_move(g, REL_EXAMINE) != MOVE_OK) { - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "Beginning of game.\n"); - } - } - - break; - } - } - if (garray[g].numHalfMoves < garray[g].revertHalfMove) { - garray[g].revertHalfMove = garray[g].numHalfMoves; - } - /* roll back time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - return COM_OK; -} - -PUBLIC int com_revert(int p, param_list param) -{ - int nHalfMoves = 1; - int g, i; - int p1; - unsigned now; - - if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) { - pprintf(p, "You are not examining any games.\n"); - return COM_OK; - } - g = parray[p].game; - nHalfMoves = garray[g].numHalfMoves - garray[g].revertHalfMove; - if (nHalfMoves == 0) { - pprintf(p, "Already at mainline.\n"); - return COM_OK; - } - if (nHalfMoves < 0) { /* eek - should NEVER happen! */ - fprintf(stderr, "OUCH! in com_revert: nHalfMoves < 0\n"); - return COM_OK; - } - for (p1 = 0; p1 < p_num; p1++) { - if (parray[p1].status != PLAYER_PROMPT) - continue; - if (player_is_observe(p1, g) || parray[p1].game == g) { - pprintf(p1, "%s reverts to mainline.\n", parray[p].name); - } - } - for (i = 0; i < nHalfMoves; i++) { - backup_move(g, REL_EXAMINE);/* should never return error */ - } - /* roll back time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - return COM_OK; -} - -PUBLIC int com_takeback(int p, param_list param) -{ - int nHalfMoves = 1; - int from; - int g, i; - int p1; - - if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - p1 = parray[p].opponent; - if (parray[p1].simul_info.numBoards && - parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != - parray[p].game) { - pprintf(p, "You can only make requests when the simul player is at your board.\n"); - return COM_OK; - } - g = parray[p].game; - if (param[0].type == TYPE_INT) { - nHalfMoves = param[0].val.integer; - } - if ((from = player_find_pendfrom(p, parray[p].opponent, PEND_TAKEBACK)) >= 0) { - player_remove_request(parray[p].opponent, p, PEND_TAKEBACK); - if (parray[p].p_from_list[from].param1 == nHalfMoves) { - /* Doing the takeback */ - player_decline_offers(p, -1, -PEND_SIMUL); - for (i = 0; i < nHalfMoves; i++) { - if (backup_move(g, REL_GAME) != MOVE_OK) { - pprintf(garray[g].white, "Can only backup %d moves\n", i); - pprintf(garray[g].black, "Can only backup %d moves\n", i); - break; - } - } - -#ifdef TIMESEAL - - garray[g].wTimeWhenReceivedMove = 0; - garray[g].bTimeWhenReceivedMove = 0; - -#endif - - send_boards(g); - } else { - if (garray[g].numHalfMoves < nHalfMoves) { - pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves); - pprintf_prompt(parray[p].opponent, "\n%s has declined the takeback request.\n", parray[p].name, nHalfMoves); - return COM_OK; - } - pprintf(p, "You disagree on the number of half-moves to takeback.\n"); - pprintf(p, "Alternate takeback request sent.\n"); - pprintf_prompt(parray[p].opponent, "\n%s proposes a different number (%d) of half-move(s).\n", parray[p].name, nHalfMoves); - player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves); - } - } else { - if (garray[g].numHalfMoves < nHalfMoves) { - pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves); - return COM_OK; - } - pprintf(parray[p].opponent, "\n"); - pprintf_highlight(parray[p].opponent, "%s", parray[p].name); - pprintf_prompt(parray[p].opponent, " would like to take back %d half move(s).\n", - nHalfMoves); - pprintf(p, "Takeback request sent.\n"); - player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves); - } - return COM_OK; -} - - -PUBLIC int com_switch(int p, param_list param) -{ - int g = parray[p].game; - int tmp, now; - int p1; - char *strTmp; - - if ((g < 0) || (garray[g].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - p1 = parray[p].opponent; - if (parray[p1].simul_info.numBoards && - parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) { - pprintf(p, "You can only make requests when the simul player is at your board.\n"); - return COM_OK; - } - if (player_find_pendfrom(p, parray[p].opponent, PEND_SWITCH) >= 0) { - player_remove_request(parray[p].opponent, p, PEND_SWITCH); - /* Doing the switch */ - player_decline_offers(p, -1, -PEND_SIMUL); - - tmp = garray[g].white; - garray[g].white = garray[g].black; - garray[g].black = tmp; - parray[p].side = (parray[p].side == WHITE) ? BLACK : WHITE; - strTmp = strdup(garray[g].white_name); - strcpy(garray[g].white_name, garray[g].black_name); - strcpy(garray[g].black_name, strTmp); - strfree(strTmp); - - parray[parray[p].opponent].side = - (parray[parray[p].opponent].side == WHITE) ? BLACK : WHITE; - /* Roll back the time */ - if (garray[g].game_state.onMove == WHITE) { - garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } else { - garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime); - } - now = tenth_secs(); - if (garray[g].numHalfMoves == 0) - garray[g].timeOfStart = now; - garray[g].lastMoveTime = now; - garray[g].lastDecTime = now; - send_boards(g); - return COM_OK; - } - if (garray[g].rated && garray[g].numHalfMoves > 0) { - pprintf(p, "You cannot switch sides once a rated game is underway.\n"); - return COM_OK; - } - pprintf(parray[p].opponent, "\n"); - pprintf_highlight(parray[p].opponent, "%s", parray[p].name); - pprintf_prompt(parray[p].opponent, " would like to switch sides.\nType \"accept\" to switch sides, or \"decline\" to refuse.\n"); - pprintf(p, "Switch request sent.\n"); - player_add_request(p, parray[p].opponent, PEND_SWITCH, 0); - return COM_OK; -} - - -PUBLIC int com_history(int p, param_list param) -{ - int p1, connected; - char fname[MAX_FILENAME_SIZE]; - - if (!FindPlayer(p, ¶m[0], &p1, &connected)) - return COM_OK; - - sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p1].login[0], - parray[p1].login, STATS_GAMES); - pgames(p, p1, fname); - if (!connected) - player_remove(p1); - return COM_OK; -} - -PUBLIC int com_time(int p, param_list param) -{ - int p1, g; - - if (param[0].type == TYPE_NULL) { - g = parray[p].game; - if ((g < 0) || (garray[g].status == GAME_EXAMINE)) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - } else { - g = GameNumFromParam(p, &p1, ¶m[0]); - if (g < 0) - return COM_OK; - } - if ((g < 0) || (g >= g_num) || (garray[g].status != GAME_ACTIVE)) { - pprintf(p, "There is no such game.\n"); - return COM_OK; - } - game_update_time(g); - pprintf(p, "White (%s) : %d mins, %d secs\n", - parray[garray[g].white].name, - garray[g].wTime / 600, - (garray[g].wTime - ((garray[g].wTime / 600) * 600)) / 10); - pprintf(p, "Black (%s) : %d mins, %d secs\n", - parray[garray[g].black].name, - garray[g].bTime / 600, - (garray[g].bTime - ((garray[g].bTime / 600) * 600)) / 10); - return COM_OK; -} - -PUBLIC int com_boards(int p, param_list param) -{ - char *category = NULL; - char dname[MAX_FILENAME_SIZE]; - DIR *dirp; -#ifdef USE_DIRENT - struct dirent *dp; -#else - struct direct *dp; -#endif - - if (param[0].type == TYPE_WORD) - category = param[0].val.word; - if (category) { - pprintf(p, "Boards Available For Category %s:\n", category); - sprintf(dname, "%s/%s", board_dir, category); - } else { - pprintf(p, "Categories Available:\n"); - sprintf(dname, "%s", board_dir); - } - dirp = opendir(dname); - if (!dirp) { - pprintf(p, "No such category %s, try \"boards\".\n", category); - return COM_OK; - } - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { - if (!strcmp(dp->d_name, ".")) - continue; - if (!strcmp(dp->d_name, "..")) - continue; - pprintf(p, "%s\n", dp->d_name); - } - closedir(dirp); - return COM_OK; -} - -PUBLIC int com_simmatch(int p, param_list param) -{ - int p1, g, adjourned; - int num; - char tmp[100]; - - if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You are still examining a game.\n"); - return COM_OK; - } - p1 = player_find_part_login(param[0].val.word); - if (p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word); - return COM_OK; - } - if (p == p1) { - pprintf(p, "You can't simmatch yourself!\n"); - return COM_OK; - } - if (player_find_pendfrom(p, p1, PEND_SIMUL) >= 0) { - player_remove_request(p, p1, PEND_MATCH); - player_remove_request(p1, p, PEND_MATCH); - player_remove_request(p, p1, PEND_SIMUL); - player_remove_request(p1, p, PEND_SIMUL); - player_withdraw_offers(p, -1, PEND_SIMUL); - player_decline_offers(p1, -1, PEND_SIMUL); - player_withdraw_offers(p1, -1, PEND_SIMUL); - player_decline_offers(p, -1, PEND_MATCH); - player_withdraw_offers(p, -1, PEND_MATCH); - player_decline_offers(p1, -1, PEND_MATCH); - player_withdraw_offers(p1, -1, PEND_MATCH); - - - - /* Accepting Simul ! */ - - - if (parray[p].simul_info.numBoards >= MAX_SIMUL) { - pprintf(p, "You are already playing the maximum of %d boards.\n", MAX_SIMUL); - pprintf(p1, "Simul request removed, boards filled.\n"); - return COM_OK; - } - unobserveAll(p); /* stop observing when match starts */ - unobserveAll(p1); - - g = game_new(); - adjourned = 0; - if (game_read(g, p, p1) >= 0) - adjourned = 1; - if (!adjourned) { /* no adjourned game, so begin a new game */ - game_remove(g); - - if (create_new_match(p, p1, 0, 0, 0, 0, 0, "standard", "standard", 1)) { - pprintf(p, "There was a problem creating the new match.\n"); - pprintf_prompt(p1, "There was a problem creating the new match.\n"); - return COM_OK; - } - } else { /* resume adjourned game */ - game_delete(p, p1); - - sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s simul.}\n", g + 1, parray[p].name, parray[p1].name, rstr[garray[g].rated], bstr[garray[g].type]); - pprintf(p, tmp); - pprintf(p1, tmp); - - garray[g].white = p; - garray[g].black = p1; - garray[g].status = GAME_ACTIVE; - garray[g].startTime = tenth_secs(); - garray[g].lastMoveTime = garray[g].startTime; - garray[g].lastDecTime = garray[g].startTime; - parray[p].game = g; - parray[p].opponent = p1; - parray[p].side = WHITE; - parray[p1].game = g; - parray[p1].opponent = p; - parray[p1].side = BLACK; - send_boards(g); - } - - num = parray[p].simul_info.numBoards; - parray[p].simul_info.results[num] = -1; - parray[p].simul_info.boards[num] = parray[p].game; - parray[p].simul_info.numBoards++; - if (parray[p].simul_info.numBoards > 1 && - parray[p].simul_info.onBoard >= 0) - player_goto_board(p, parray[p].simul_info.onBoard); - else - parray[p].simul_info.onBoard = 0; - return COM_OK; - } - if (player_find_pendfrom(p, -1, PEND_SIMUL) >= 0) { - pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n"); - return COM_OK; - } - if (parray[p].simul_info.numBoards) { - pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n"); - return COM_OK; - } - if (parray[p].game >=0) { - pprintf(p, "You are already playing a game.\n"); - return COM_OK; - } - if (!parray[p1].sopen) { - pprintf_highlight(p, "%s", parray[p1].name); - pprintf(p, " is not open to receiving simul requests.\n"); - return COM_OK; - } - if (parray[p1].simul_info.numBoards >= MAX_SIMUL) { - pprintf_highlight(p, "%s", parray[p1].name); - pprintf(p, " is already playing the maximum of %d boards.\n", MAX_SIMUL); - return COM_OK; - } -/* loon: checking for some crazy situations we can't allow :) */ - - if ((parray[p1].game >=0) &&(parray[p1].simul_info.numBoards == 0)) { - pprintf_highlight(p, "%s", parray[p1].name); - if (parray[garray[parray[p1].game].white].simul_info.numBoards) { - pprintf(p, " is playing in "); - pprintf_highlight(p, "%s", parray[parray[p1].opponent].name); - pprintf(p, "'s simul, and can't accept.\n"); - } else { - pprintf(p, " can't begin a simul while playing a non-simul game.\n"); - } - return COM_OK; - } -/* loon: this was (p, p1, PEND_SIMUL) but player_add_request needs 4 args... -if 0 is the incorrect 4th arg, please fix :) */ - - g = game_new(); /* Check if an adjourned untimed game */ - adjourned = ((game_read(g, p, p1) < 0) && (game_read(g, p1, p) < 0)) ? 0 : 1; - if (adjourned) { - if (!(garray[g].type == TYPE_UNTIMED)) - adjourned = 0; - } - game_remove(g); - - if (player_add_request(p, p1, PEND_SIMUL, 0)) { - pprintf(p, "Maximum number of pending actions reached. Your request was not sent.\nTry again later.\n"); - return COM_OK; - } else { - pprintf(p1, "\n"); - pprintf_highlight(p1, "%s", parray[p].name); - if (adjourned) { - pprintf_prompt(p1, " requests to continue an adjourned simul game.\n"); - pprintf(p, "Request to resume simul sent. Adjourned game found.\n"); - } else { - pprintf_prompt(p1, " requests to join a simul match with you.\n"); - pprintf(p, "Simul match request sent.\n"); - } - } - return COM_OK; -} - -PUBLIC int com_goboard(int p, param_list param) -{ - int on, g, p1; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - p1 = player_find_part_login(param[0].val.word); - if (p1 < 0) { - pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word); - return COM_OK; - } - if (p == p1) { - pprintf(p, "You can't goboard yourself!\n"); - return COM_OK; - } - on = parray[p].simul_info.onBoard; - g = parray[p].simul_info.boards[on]; - if (p1 == garray[g].black) { - pprintf(p, "You are already at that board!\n"); - return COM_OK; - } - if (parray[p].simul_info.numBoards > 1) { - player_decline_offers(p, -1, -PEND_SIMUL); - if (player_goto_simulgame_bynum(p, parray[p1].game) !=-1) { - if (g >= 0) { - pprintf(garray[g].black, "\n"); - pprintf_highlight(garray[g].black, "%s", parray[p].name); - pprintf_prompt(garray[g].black, " has moved away from your board.\n"); - } - } - } else - pprintf(p, "You are only playing one board!\n"); - return COM_OK; -} - -PUBLIC int com_gonum(int p, param_list param) -{ - int on, g, gamenum; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - on = parray[p].simul_info.onBoard; - g = parray[p].simul_info.boards[on]; - gamenum = param[0].val.integer - 1; - if (gamenum < 0) - gamenum = 0; - if (on == gamenum) { - pprintf(p, "You are already at that board!\n"); - return COM_OK; - } - if (parray[p].simul_info.numBoards > 1) { - player_decline_offers(p, -1, -PEND_SIMUL); - if (player_goto_simulgame_bynum(p, gamenum) != -1) { - if (g >= 0) { - pprintf(garray[g].black, "\n"); - pprintf_highlight(garray[g].black, "%s", parray[p].name); - pprintf_prompt(garray[g].black, " has moved away from your board.\n"); - } - } - } else - pprintf(p, "You are only playing one board!\n"); - return COM_OK; -} - -PUBLIC int com_simnext(int p, param_list param) -{ - int on, g; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - if (parray[p].simul_info.numBoards > 1) { - player_decline_offers(p, -1, -PEND_SIMUL); - on = parray[p].simul_info.onBoard; - g = parray[p].simul_info.boards[on]; - if (g >= 0) { - pprintf(garray[g].black, "\n"); - pprintf_highlight(garray[g].black, "%s", parray[p].name); - pprintf_prompt(garray[g].black, " is moving away from your board.\n"); - player_goto_next_board(p); - } - } else - pprintf(p, "You are only playing one board!\n"); - return COM_OK; -} - - -PUBLIC int com_simprev(int p, param_list param) -{ - int on, g; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - if (parray[p].simul_info.numBoards > 1) { - player_decline_offers(p, -1, -PEND_SIMUL); - on = parray[p].simul_info.onBoard; - g = parray[p].simul_info.boards[on]; - if (g >= 0) { - pprintf(garray[g].black, "\n"); - pprintf_highlight(garray[g].black, "%s", parray[p].name); - pprintf_prompt(garray[g].black, " is moving back to the previous board.\n"); - } - player_goto_prev_board(p); - } else - pprintf(p, "You are only playing one board!\n"); - return COM_OK; -} - -PUBLIC int com_simgames(int p, param_list param) -{ - int p1 = p; - - if (param[0].type == TYPE_WORD) { - if ((p1 = player_find_part_login(param[0].val.word)) < 0) { - pprintf(p, "No player named %s is logged in.\n", param[0].val.word); - return COM_OK; - } - } - if (p1 == p) - pprintf(p, "You are playing %d simultaneous games.\n", - player_num_active_boards(p1)); - else - pprintf(p, "%s is playing %d simultaneous games.\n", parray[p1].name, - player_num_active_boards(p1)); - return COM_OK; -} - -PUBLIC int com_simpass(int p, param_list param) -{ - int g, p1, on; - - if (parray[p].game <0) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - g = parray[p].game; - p1 = garray[g].white; - if (!parray[p1].simul_info.numBoards) { - pprintf(p, "You are not participating in a simul.\n"); - return COM_OK; - } - if (p == p1) { - pprintf(p, "You are the simul holder and cannot pass!\n"); - return COM_OK; - } - if (player_num_active_boards(p1) == 1) { - pprintf(p, "This is the only game, so passing is futile.\n"); - return COM_OK; - } - on = parray[p1].simul_info.onBoard; - if (on != g) { - pprintf(p, "You cannot pass until the simul holder arrives!\n"); - return COM_OK; - } - if (garray[g].passes >= MAX_SIMPASS) { - if (parray[p].bell) - pprintf(p, "\a"); - pprintf(p, "You have reached your maximum of %d passes.\n", MAX_SIMPASS); - pprintf(p, "Please move IMMEDIATELY!\n"); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf_prompt(p1, " tried to pass, but is out of passes.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -PEND_SIMUL); - - garray[g].passes++; - pprintf(p, "You have passed and have %d passes left.\n", - (MAX_SIMPASS - garray[g].passes)); - pprintf_highlight(p1, "%s", parray[p].name); - pprintf_prompt(p1, " has decided to pass and has %d passes left.\n", - (MAX_SIMPASS - garray[g].passes)); - player_goto_next_board(p1); - return COM_OK; -} - -PUBLIC int com_simabort(int p, param_list param) -{ - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -PEND_SIMUL); - game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard], - WHITE, END_ABORT); - return COM_OK; -} - -PUBLIC int com_simallabort(int p, param_list param) -{ - int i; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -PEND_SIMUL); - for (i = 0; i < parray[p].simul_info.numBoards; i++) { - if (parray[p].simul_info.boards[i] >= 0) { - game_ended(parray[p].simul_info.boards[i], - WHITE, END_ABORT); - } - } - return COM_OK; -} - -PUBLIC int com_simadjourn(int p, param_list param) -{ - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -PEND_SIMUL); - game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard], - WHITE, END_ADJOURN); - return COM_OK; -} - -PUBLIC int com_simalladjourn(int p, param_list param) -{ - int i; - - if (!parray[p].simul_info.numBoards) { - pprintf(p, "You are not giving a simul.\n"); - return COM_OK; - } - player_decline_offers(p, -1, -PEND_SIMUL); - for (i = 0; i < parray[p].simul_info.numBoards; i++) { - if (parray[p].simul_info.boards[i] >= 0) { - game_ended(parray[p].simul_info.boards[i], - WHITE, END_ADJOURN); - } - } - return COM_OK; -} - -PUBLIC int com_moretime(int p, param_list param) -{ - int g, increment; - - ASSERT(param[0].type == TYPE_INT); - if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) { - pprintf(p, "You cannot use moretime in an examined game.\n"); - return COM_OK; - } - increment = param[0].val.integer; - if (increment <= 0) { - pprintf(p, "Moretime requires an integer value greater than zero.\n"); - return COM_OK; - } - if (parray[p].game <0) { - pprintf(p, "You are not playing a game.\n"); - return COM_OK; - } - if (increment > 600) { - pprintf(p, "Moretime has a maximum limit of 600 seconds.\n"); - increment = 600; - } - g = parray[p].game; - if (garray[g].white == p) { - garray[g].bTime += increment * 10; -#ifdef TIMESEAL - garray[g].bRealTime += increment * 10 * 100; -#endif - pprintf(p, "%d seconds were added to your opponents clock\n", - increment); - pprintf_prompt(parray[p].opponent, - "\nYour opponent has added %d seconds to your clock.\n", - increment); - } - if (garray[g].black == p) { - garray[g].wTime += increment * 10;; -#ifdef TIMESEAL - garray[g].wRealTime += increment * 10 * 100; -#endif - pprintf(p, "%d seconds were added to your opponents clock\n", - increment); - pprintf_prompt(parray[p].opponent, - "\nYour opponent has added %d seconds to your clock.\n", - increment); - } - return COM_OK; -} |