summaryrefslogtreecommitdiffstats
path: root/mbbsd/gomo.c
diff options
context:
space:
mode:
authorscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-28 22:36:54 +0800
committerscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-28 22:36:54 +0800
commit544b6475f029f5396bea9ebca0994111e74d1200 (patch)
treea118f5effae4482def8d881794bf7ea7f676c381 /mbbsd/gomo.c
parentbd3cb69722802ca63edbc0d60a8e07f19ab31359 (diff)
downloadpttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar.gz
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar.bz2
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar.lz
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar.xz
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.tar.zst
pttbbs-544b6475f029f5396bea9ebca0994111e74d1200.zip
Chess functions:
* chc machine readable log - http://www.elephantbase.net/protocol/cchess_pgn.htm - http://www.elephantbase.net/protocol/cchess_move.htm * chc and gomoku replay work * key binding 'z' in pmore() for chess replay * avoid crash when watching (the watchee's mateid is empty) git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3105 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/gomo.c')
-rw-r--r--mbbsd/gomo.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/mbbsd/gomo.c b/mbbsd/gomo.c
index 521fdb76..872648e5 100644
--- a/mbbsd/gomo.c
+++ b/mbbsd/gomo.c
@@ -5,7 +5,7 @@
#define QCAST int (*)(const void *, const void *)
#define BOARD_LINE_ON_SCREEN(X) ((X) + 2)
-static const char* turn_color[] = { ANSI_COLOR(30;43), ANSI_COLOR(37;43) };
+static const char* turn_color[] = { ANSI_COLOR(37;43), ANSI_COLOR(30;43) };
enum Turn {
WHT = 0,
@@ -261,6 +261,15 @@ gomo_init_user(const userinfo_t* uinfo, ChessUser* user)
}
static void
+gomo_init_user_userec(const userec_t* urec, ChessUser* user)
+{
+ strlcpy(user->userid, urec->userid, sizeof(user->userid));
+ user->win = urec->five_win;
+ user->lose = urec->five_lose;
+ user->tie = urec->five_tie;
+}
+
+static void
gomo_init_board(board_t board)
{
memset(board, 0xff, sizeof(board_t));
@@ -402,6 +411,9 @@ gomo_gameend(ChessInfo* info, ChessGameResult result)
cuser.five_tie = user1->tie;
passwd_update(usernum, &cuser);
+ } else if (info->mode == CHESS_MODE_REPLAY) {
+ free(info->board);
+ free(info->tag);
}
}
@@ -488,3 +500,65 @@ gomoku_watch(void)
{
return ChessWatchGame(&gomoku, M_FIVE, "¤­¤l´Ñ");
}
+
+ChessInfo*
+gomoku_replay(FILE* fp)
+{
+ ChessInfo *info;
+ char buf[256];
+
+ info = NewChessInfo(&gomo_actions, &gomo_constants,
+ 0, CHESS_MODE_REPLAY);
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (strcmp("</gomokulog>\n", buf) == 0)
+ break;
+ else if (strncmp("black:", buf, 6) == 0 ||
+ strncmp("white:", buf, 6) == 0) {
+ /* /(black|white):([a-zA-Z0-9]+)/; $2 */
+ userec_t rec;
+ ChessUser *user = (buf[0] == 'b' ? &info->user1 : &info->user2);
+
+ chomp(buf);
+ if (getuser(buf + 6, &rec))
+ gomo_init_user_userec(&rec, user);
+ } else if (buf[0] == '[') {
+ /* "[ 1]¡´ ==> H8 [ 2]¡³ ==> H9" *
+ * 012345678901234567890123456789 */
+ gomo_step_t step = { CHESS_STEP_NORMAL, BLK };
+ int c = buf[11] - 'A';
+ int r = BRDSIZ - 1 - (buf[12] - '0');
+
+#define INVALID_ROW(R) ((R) < 0 || (R) >= BRDSIZ)
+#define INVALID_COL(C) ((C) < 0 || (C) >= BRDSIZ)
+ if (INVALID_COL(c) || INVALID_ROW(r))
+ continue;
+
+ step.loc.r = r;
+ step.loc.c = c;
+ ChessHistoryAppend(info, &step);
+
+ if (strlen(buf) < 28)
+ continue;
+
+ c = buf[28] - 'A';
+ r = BRDSIZ - (buf[29] - '0');
+
+ if (INVALID_COL(c) || INVALID_ROW(r))
+ continue;
+
+ step.color = WHT;
+ step.loc.r = r;
+ step.loc.c = c;
+ ChessHistoryAppend(info, &step);
+ }
+ }
+
+ info->board = malloc(sizeof(board_t));
+ info->tag = malloc(sizeof(int));
+
+ gomo_init_board(info->board);
+ *(int*)(info->tag) = 0;
+
+ return info;
+}