diff options
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/Makefile | 2 | ||||
-rw-r--r-- | mbbsd/chc.c | 8 | ||||
-rw-r--r-- | mbbsd/chess.c | 22 | ||||
-rw-r--r-- | mbbsd/go.c | 6 | ||||
-rw-r--r-- | mbbsd/gomo.c | 8 | ||||
-rw-r--r-- | mbbsd/pmore.c | 2 | ||||
-rw-r--r-- | mbbsd/reversi.c | 506 | ||||
-rw-r--r-- | mbbsd/talk.c | 31 |
8 files changed, 558 insertions, 27 deletions
diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 70775694..eb26c91f 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -15,7 +15,7 @@ OBJS= admin.o announce.o args.o assess.o bbs.o board.o cache.o cal.o card.o\ more.o name.o osdep.o othello.o read.o record.o register.o\ screen.o stuff.o talk.o term.o topsong.o user.o brc.o vice.o vote.o\ xyz.o voteboard.o syspost.o var.o passwd.o calendar.o go.o file.o \ - pmore.o chess.o + pmore.o chess.o reversi.o .if defined(DIET) OBJS+= random.o time.o alloc.o diff --git a/mbbsd/chc.c b/mbbsd/chc.c index 19fce8fb..a4d3eeeb 100644 --- a/mbbsd/chc.c +++ b/mbbsd/chc.c @@ -42,7 +42,7 @@ static void chc_init_user_userec(const userec_t *urec, ChessUser *user); static void chc_init_board(board_t board); static void chc_drawline(const ChessInfo* info, int line); static void chc_movecur(int r, int c); -static void chc_prepare_play(ChessInfo* info); +static int chc_prepare_play(ChessInfo* info); static int chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result); static void chc_prepare_step(ChessInfo* info, const void* step); static ChessGameResult chc_movechess(board_t board, const drc_t* move); @@ -105,7 +105,7 @@ static const ChessActions chc_actions = { &chc_drawline, &chc_movecur, &chc_prepare_play, - NULL, + NULL, /* process_key */ &chc_select, &chc_prepare_step, (ChessGameResult (*) (void*, const void*)) &chc_movechess, @@ -692,7 +692,7 @@ chc_init_user_userec(const userec_t *urec, ChessUser *user) user->orig_rating = user->rating; } -static void +static int chc_prepare_play(ChessInfo* info) { if (chc_ischeck((board_p) info->board, info->turn)) { @@ -701,6 +701,8 @@ chc_prepare_play(ChessInfo* info) bell(); } else info->warnmsg[0] = 0; + + return 0; } static int diff --git a/mbbsd/chess.c b/mbbsd/chess.c index 9df4f5bc..ca99bfaf 100644 --- a/mbbsd/chess.c +++ b/mbbsd/chess.c @@ -56,6 +56,7 @@ static const struct { { "gomoku", 6, &gomoku_replay }, { "chc", 3, &chc_replay }, { "go", 2, &gochess_replay }, + { "reversi",7, &reversi_replay }, { NULL } }; @@ -386,9 +387,9 @@ ChessReplayUntil(ChessInfo* info, int n) /* spcial for last one to maintian information correct */ step = ChessHistoryRetrieve(info, info->current_step); + info->turn = info->current_step++ & 1; info->actions->prepare_step(info, step); info->actions->apply_step(info->board, step); - info->current_step++; } static int @@ -778,6 +779,7 @@ ChessPlayFuncWatch(ChessInfo* info) /* at head but redo-ed */ info->actions->init_board(info->board); info->current_step = 0; + info->turn = 1; ChessReplayUntil(info, info->history.used - 1); ChessRedraw(info); } @@ -786,10 +788,10 @@ ChessPlayFuncWatch(ChessInfo* info) result == CHESS_STEP_SPECIAL) { if (info->current_step == info->history.used - 1) { /* was watching up-to-date board */ + info->turn = info->current_step++ & 1; info->actions->prepare_step(info, &info->step_tmp); info->actions->apply_step(info->board, &info->step_tmp); info->actions->drawstep(info, &info->step_tmp); - info->current_step++; } } else if (result == CHESS_STEP_PASS) strcpy(info->last_movestr, "虛手"); @@ -817,10 +819,10 @@ ChessPlayFuncWatch(ChessInfo* info) else { const void* step = ChessHistoryRetrieve(info, info->current_step); + info->turn = info->current_step++ & 1; info->actions->prepare_step(info, step); info->actions->apply_step(info->board, step); info->actions->drawstep(info, step); - info->current_step++; } break; @@ -1070,13 +1072,15 @@ ChessPlay(ChessInfo* info) for (game_result = CHESS_RESULT_CONTINUE; game_result == CHESS_RESULT_CONTINUE; info->turn ^= 1) { - info->actions->prepare_play(info); - ChessDrawLine(info, CHESS_DRAWING_TURN_ROW); - ChessDrawLine(info, CHESS_DRAWING_WARN_ROW); - game_result = info->play_func[(int) info->turn](info); + if (info->actions->prepare_play(info)) + info->pass[(int) info->turn] = 1; + else { + ChessDrawLine(info, CHESS_DRAWING_TURN_ROW); + ChessDrawLine(info, CHESS_DRAWING_WARN_ROW); + game_result = info->play_func[(int) info->turn](info); + } - if (info->constants->pass_is_step && - info->pass[0] && info->pass[1]) + if (info->pass[0] && info->pass[1]) game_result = CHESS_RESULT_END; } @@ -68,7 +68,7 @@ static void go_init_user_userec(const userec_t* urec, ChessUser* user); static void go_init_board(board_t board); static void go_drawline(const ChessInfo* info, int line); static void go_movecur(int r, int c); -static void go_prepare_play(ChessInfo* info); +static int go_prepare_play(ChessInfo* info); static int go_process_key(ChessInfo* info, int key, ChessGameResult* result); static int go_select(ChessInfo* info, rc_t location, ChessGameResult* result); @@ -545,7 +545,7 @@ go_movecur(int r, int c) move(r + 2, c * 2 + 3); } -static void +static int go_prepare_play(ChessInfo* info) { if (((go_tag_t*) info->tag)->game_end) { @@ -557,6 +557,8 @@ go_prepare_play(ChessInfo* info) if (info->history.used == 1) ChessDrawLine(info, b_lines); /* clear the 'x' instruction */ + + return 0; } static int diff --git a/mbbsd/gomo.c b/mbbsd/gomo.c index 71f0bbfc..e3664176 100644 --- a/mbbsd/gomo.c +++ b/mbbsd/gomo.c @@ -26,7 +26,7 @@ static void gomo_init_user_userec(const userec_t* urec, ChessUser* user); static void gomo_init_board(board_t board); static void gomo_drawline(const ChessInfo* info, int line); static void gomo_movecur(int r, int c); -static void gomo_prepare_play(ChessInfo* info); +static int gomo_prepare_play(ChessInfo* info); static int gomo_select(ChessInfo* info, rc_t location, ChessGameResult* result); static void gomo_prepare_step(ChessInfo* info, const gomo_step_t* step); @@ -42,7 +42,7 @@ const static ChessActions gomo_actions = { &gomo_drawline, &gomo_movecur, &gomo_prepare_play, - NULL, + NULL, /* process_key */ &gomo_select, (void (*)(ChessInfo*, const void*)) &gomo_prepare_step, (ChessGameResult (*)(void*, const void*)) &gomo_apply_step, @@ -323,11 +323,13 @@ gomo_movecur(int r, int c) move(r + 2, c * 2 + 3); } -static void +static int gomo_prepare_play(ChessInfo* info) { if (!gomo_move_warn(*(int*) info->tag, info->warnmsg)) info->warnmsg[0] = 0; + + return 0; } static int diff --git a/mbbsd/pmore.c b/mbbsd/pmore.c index dd22ed60..d71fd1ee 100644 --- a/mbbsd/pmore.c +++ b/mbbsd/pmore.c @@ -1523,7 +1523,7 @@ static const char * const pmore_help[] = { "(t/[-/]+) 主題式閱\讀:循序/前/後篇", "(\\/|) 切換顯示原始內容", // this IS already aligned! "(w/W/l) 切換自動斷行/斷行符號/分隔線顯示方式", - "(p/o) 播放動畫/切換傳統模式(狀態列與斷行方式)", + "(p/z/o) 播放動畫/棋局打譜/切換傳統模式(狀態列與斷行方式)", "(q/←) (h/H/?/F1) 結束/本說明畫面", #ifdef DEBUG "(d) 切換除錯(debug)模式", diff --git a/mbbsd/reversi.c b/mbbsd/reversi.c new file mode 100644 index 00000000..c396ef0a --- /dev/null +++ b/mbbsd/reversi.c @@ -0,0 +1,506 @@ +/* $Id$ */ + +#include "bbs.h" + +#define MAX_TIME (300) +#define BRDSIZ (8) /* 棋盤單邊大小 */ + +#define NONE_CHESS " " +#define WHITE_CHESS "●" +#define BLACK_CHESS "○" +#define HINT_CHESS "#" +#define NONE 0 +#define HINT 1 +#define BLACK 2 +#define WHITE 3 + +#define STARTY 10 + +#define INVERT(COLOR) (((COLOR))==WHITE?BLACK:WHITE) + +#define IS_BLANK(COLOR) ((COLOR) < BLACK) /* NONE or HINT */ +#define IS_CHESS(COLOR) ((COLOR) >= BLACK) +#define TURN_TO_COLOR(TURN) (WHITE - (TURN)) +#define COLOR_TO_TURN(COLOR) (WHITE - (COLOR)) + +typedef char color_t; +typedef color_t board_t[BRDSIZ + 2][BRDSIZ + 2]; +typedef color_t (*board_p)[BRDSIZ + 2]; +/* [0] & [9] are dummy */ + +typedef struct { + ChessStepType type; /* necessary one */ + color_t color; + rc_t loc; +} reversi_step_t; + +typedef struct { + int number[2]; +} reversi_tag_t; + +/* chess framework action functions */ +static void reversi_init_user(const userinfo_t *uinfo, ChessUser *user); +static void reversi_init_user_userec(const userec_t *urec, ChessUser *user); +static void reversi_init_board(board_t board); +static void reversi_drawline(const ChessInfo* info, int line); +static void reversi_movecur(int r, int c); +static int reversi_prepare_play(ChessInfo* info); +static int reversi_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result); +static void reversi_prepare_step(ChessInfo* info, const reversi_step_t* step); +static ChessGameResult reversi_apply_step(board_t board, const reversi_step_t* step); +static void reversi_drawstep(ChessInfo* info, const void* move); +static ChessGameResult reversi_post_game(ChessInfo* info); +static void reversi_gameend(ChessInfo* info, ChessGameResult result); +static void reversi_genlog(ChessInfo* info, FILE* fp, ChessGameResult result); + +static const char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS}; +static const char DIRX[] = {-1, -1, -1, 0, 1, 1, 1, 0}; +static const char DIRY[] = {-1, 0, 1, 1, 1, 0, -1, -1}; + +static const ChessActions reversi_actions = { + &reversi_init_user, + &reversi_init_user_userec, + (void (*) (void*)) &reversi_init_board, + &reversi_drawline, + &reversi_movecur, + &reversi_prepare_play, + NULL, /* process_key */ + &reversi_select, + (void (*)(ChessInfo*, const void*)) &reversi_prepare_step, + (ChessGameResult (*)(void*, const void*)) &reversi_apply_step, + &reversi_drawstep, + &reversi_post_game, + &reversi_gameend, + &reversi_genlog +}; + +const static ChessConstants reversi_constants = { + sizeof(reversi_step_t), + MAX_TIME, + BRDSIZ, + BRDSIZ, + 0, + "黑白棋", + "photo_reversi", +#ifdef GLOBAL_REVERSI_LOG + GLOBAL_REVERSI_LOG, +#else + NULL, +#endif + { "", "" }, + { "白棋", "黑棋" }, +}; + +static int +can_put(board_t board, color_t who, int x, int y) +{ + int i, temp, checkx, checky; + + if (IS_BLANK(board[x][y])) + for (i = 0; i < 8; ++i) { + checkx = x + DIRX[i]; + checky = y + DIRY[i]; + temp = board[checkx][checky]; + if (IS_BLANK(temp)) + continue; + if (temp != who) { + while (board[checkx += DIRX[i]][checky += DIRY[i]] == temp); + if (board[checkx][checky] == who) + return 1; + } + } + return 0; +} + +static int +caculate_hint(board_t board, color_t who) +{ + int i, j, count = 0; + + for (i = 1; i <= 8; i++) + for (j = 1; j <= 8; j++) { + if (board[i][j] == HINT) + board[i][j] = NONE; + if (can_put(board, who, i, j)) { + board[i][j] = HINT; + ++count; + } + } + return count; +} + +static void +reversi_init_user(const userinfo_t* uinfo, ChessUser* user) +{ + strlcpy(user->userid, uinfo->userid, sizeof(user->userid)); + user->win = + user->lose = + user->tie = 0; +} + +static void +reversi_init_user_userec(const userec_t* urec, ChessUser* user) +{ + strlcpy(user->userid, urec->userid, sizeof(user->userid)); + user->win = + user->lose = + user->tie = 0; +} + +static void +reversi_init_board(board_t board) +{ + memset(board, NONE, sizeof(board_t)); + board[4][4] = board[5][5] = WHITE; + board[4][5] = board[5][4] = BLACK; + + caculate_hint(board, BLACK); +} + +static void +reversi_drawline(const ChessInfo* info, int line){ + static const char* num_str[] = + {"", "1", "2", "3", "4", "5", "6", "7", "8"}; + if(line) + move(line, STARTY); + + if (line == 0) { + prints(ANSI_COLOR(1;46) " 黑白棋對戰 " ANSI_COLOR(45) + "%30s VS %-20s%10s" ANSI_RESET, + info->user1.userid, info->user2.userid, + info->mode == CHESS_MODE_WATCH ? "[觀棋模式]" : ""); + } else if (line == 2) + outs(" A B C D E F G H"); + else if (line == 3) + outs("┌─┬─┬─┬─┬─┬─┬─┬─┐"); + else if (line == 19) + outs("└─┴─┴─┴─┴─┴─┴─┴─┘"); + else if (line == 20) + prints(" (黑) %-15s%2d%*s", + info->myturn ? info->user1.userid : info->user2.userid, + ((reversi_tag_t*)info->tag)->number[COLOR_TO_TURN(BLACK)], + 34 - 24, ""); + else if (line == 21) + prints(" (白) %-15s%2d%*s", + info->myturn ? info->user2.userid : info->user1.userid, + ((reversi_tag_t*)info->tag)->number[COLOR_TO_TURN(WHITE)], + 34 - 24, ""); + else if (line > 3 && line < 19) { + if ((line & 1) == 1) + outs("├─┼─┼─┼─┼─┼─┼─┼─┤"); + else { + int x = line / 2 - 1; + int y; + board_p board = (board_p) info->board; + + move(line, STARTY - 2); + prints("%s│", num_str[x]); + for(y = 1; y <= 8; ++y) + prints("%s│", CHESS_TYPE[(int) board[x][y]]); + } + } + + ChessDrawExtraInfo(info, line, 4); +} + +static void +reversi_movecur(int r, int c) +{ + move(r * 2 + 4, c * 4 + STARTY + 2); +} + +static int +reversi_prepare_play(ChessInfo* info) +{ + int x, y; + int result; + board_p board = (board_p) info->board; + reversi_tag_t* tag = (reversi_tag_t*) info->tag; + + tag->number[0] = tag->number[1] = 0; + for(x = 1; x <= 8; ++x) + for(y = 1; y <= 8; ++y) + if (IS_CHESS(board[x][y])) + ++tag->number[COLOR_TO_TURN(board[x][y])]; + + result = !caculate_hint(board, TURN_TO_COLOR(info->turn)); + if (result) { + reversi_step_t step = { CHESS_STEP_SPECIAL, TURN_TO_COLOR(info->turn) }; + if (info->turn == info->myturn) { + ChessStepSend(info, &step); + ChessHistoryAppend(info, &step); + strcpy(info->last_movestr, "你必須放棄這一步!!"); + } else { + ChessStepReceive(info, &step); + strcpy(info->last_movestr, "對方必須放棄這一步!!"); + } + } + + ChessRedraw(info); + return result; +} + +static int +reversi_select(ChessInfo* info, rc_t loc, ChessGameResult* result) +{ + board_p board = (board_p) info->board; + + ++loc.r; ++loc.c; + if (can_put(board, TURN_TO_COLOR(info->turn), loc.r, loc.c)) { + reversi_step_t step = { CHESS_STEP_NORMAL, + TURN_TO_COLOR(info->turn), loc }; + reversi_apply_step(board, &step); + + snprintf(info->last_movestr, sizeof(info->last_movestr), + "%c%d", step.loc.c - 1 + 'A', step.loc.r); + + ChessStepSend(info, &step); + ChessHistoryAppend(info, &step); + + return 1; + } else + return 0; +} + +static ChessGameResult +reversi_apply_step(board_t board, const reversi_step_t* step) +{ + int i; + color_t opposite = INVERT(step->color); + + if (step->type != CHESS_STEP_NORMAL) + return CHESS_RESULT_CONTINUE; + + for (i = 0; i < 8; ++i) { + int x = step->loc.r; + int y = step->loc.c; + + while (board[x += DIRX[i]][y += DIRY[i]] == opposite); + + if (board[x][y] == step->color) { + x = step->loc.r; + y = step->loc.c; + + while (board[x += DIRX[i]][y += DIRY[i]] == opposite) + board[x][y] = step->color; + } + } + board[step->loc.r][step->loc.c] = step->color; + + return CHESS_RESULT_CONTINUE; +} + +static void +reversi_prepare_step(ChessInfo* info, const reversi_step_t* step) +{ + if (step->type == CHESS_STEP_NORMAL) + snprintf(info->last_movestr, sizeof(info->last_movestr), + "%c%d", step->loc.c - 1 + 'A', step->loc.r); + else if (step->color == TURN_TO_COLOR(info->myturn)) + strcpy(info->last_movestr, "你必須放棄這一步!!"); + else + strcpy(info->last_movestr, "對方必須放棄這一步!!"); +} + +static void +reversi_drawstep(ChessInfo* info, const void* move) +{ + ChessRedraw(info); +} + +static ChessGameResult +reversi_post_game(ChessInfo* info) +{ + int x, y; + board_p board = (board_p) info->board; + reversi_tag_t* tag = (reversi_tag_t*) info->tag; + + tag->number[0] = tag->number[1] = 0; + for(x = 1; x <= 8; ++x) + for(y = 1; y <= 8; ++y) + if (board[x][y] == HINT) + board[x][y] = NONE; + else if (IS_CHESS(board[x][y])) + ++tag->number[COLOR_TO_TURN(board[x][y])]; + + ChessRedraw(info); + + if (tag->number[0] == tag->number[1]) + return CHESS_RESULT_TIE; + else if (tag->number[(int) info->myturn] < tag->number[info->myturn ^ 1]) + return CHESS_RESULT_LOST; + else + return CHESS_RESULT_WIN; +} + +static void +reversi_gameend(ChessInfo* info, ChessGameResult result) +{ + /* nothing to do now + * TODO game record */ +} + +static void +reversi_genlog(ChessInfo* info, FILE* fp, ChessGameResult result) +{ + const int nStep = info->history.used; + int i; + + for (i = 2; i <= 21; i++) + fprintf(fp, "%.*s\n", big_picture[i].len, big_picture[i].data); + + fprintf(fp, "\n"); + fprintf(fp, "按 z 可進入打譜模式\n"); + fprintf(fp, "\n"); + + fprintf(fp, "<reversilog>\nblack:%s\nwhite:%s\n", + info->myturn ? info->user1.userid : info->user2.userid, + info->myturn ? info->user2.userid : info->user1.userid); + + for (i = 0; i < nStep; ++i) { + const reversi_step_t* const step = + (const reversi_step_t*) ChessHistoryRetrieve(info, i); + if (step->type == CHESS_STEP_NORMAL) + fprintf(fp, "[%2d]%s ==> %c%-5d", i + 1, + CHESS_TYPE[(int) step->color], + 'A' + step->loc.c - 1, step->loc.r); + else + fprintf(fp, "[%2d]%s ==> pass ", i + 1, + CHESS_TYPE[(int) step->color]); + if (i % 2) + fputc('\n', fp); + } + + if (i % 2) + fputc('\n', fp); + fputs("</reversilog>\n", fp); +} + +static int +reversi_loadlog(FILE *fp, ChessInfo *info) +{ + char buf[256]; + +#define INVALID_ROW(R) ((R) <= 0 || (R) > 8) +#define INVALID_COL(C) ((C) <= 0 || (C) > 8) + while (fgets(buf, sizeof(buf), fp)) { + if (strcmp("</reversilog>\n", buf) == 0) + return 1; + 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)) + reversi_init_user_userec(&rec, user); + } else if (buf[0] == '[') { + /* "[ 1]● ==> C4 [ 2]○ ==> C5" */ + reversi_step_t step = { CHESS_STEP_NORMAL }; + int c, r; + const char *p = buf; + int i; + + for(i=0; i<2; i++) { + p = strchr(p, '>'); + + if (p == NULL) break; + + ++p; /* skip '>' */ + while (*p && isspace(*p)) ++p; + if (!*p) break; + + /* i=0, p -> "C4 ..." */ + /* i=1, p -> "C5\n" */ + + if (strncmp(p, "pass", 4) == 0) + /* [..] .. => pass */ + step.type = CHESS_STEP_SPECIAL; + else { + c = p[0] - 'A' + 1; + r = atoi(p + 1); + + if (INVALID_COL(c) || INVALID_ROW(r)) + break; + + step.loc.r = r; + step.loc.c = c; + } + + step.color = i==0 ? BLACK : WHITE; + ChessHistoryAppend(info, &step); + } + } + } +#undef INVALID_ROW +#undef INVALID_COL + return 0; +} + +void +reversi(int s, ChessGameMode mode) +{ + ChessInfo* info = NewChessInfo(&reversi_actions, &reversi_constants, s, mode); + board_t board; + reversi_tag_t tag = { { 2, 2 } }; /* will be overridden */ + + reversi_init_board(board); + + info->board = board; + info->tag = &tag; + + info->cursor.r = 3; + info->cursor.c = 3; + + if (mode == CHESS_MODE_WATCH) + setutmpmode(CHESSWATCHING); + else + setutmpmode(REVERSI); + currutmp->sig = SIG_REVERSI; + + ChessPlay(info); + + DeleteChessInfo(info); +} + +int +reversi_main(void) +{ + return ChessStartGame('r', SIG_REVERSI, "黑白棋"); +} + +int +reversi_personal(void) +{ + reversi(0, CHESS_MODE_PERSONAL); + return 0; +} + +int +reversi_watch(void) +{ + return ChessWatchGame(&reversi, REVERSI, "黑白棋"); +} + +ChessInfo* +reversi_replay(FILE* fp) +{ + ChessInfo *info; + + info = NewChessInfo(&reversi_actions, &reversi_constants, + 0, CHESS_MODE_REPLAY); + + if(!reversi_loadlog(fp, info)) { + DeleteChessInfo(info); + return NULL; + } + + info->board = malloc(sizeof(board_t)); + info->tag = malloc(sizeof(reversi_tag_t)); + + reversi_init_board(info->board); + /* tag will be initialized later */ + + return info; +} diff --git a/mbbsd/talk.c b/mbbsd/talk.c index 7495bcba..a4ba7a1d 100644 --- a/mbbsd/talk.c +++ b/mbbsd/talk.c @@ -7,10 +7,10 @@ static char * const IdleTypeTable[] = { "偶在花呆啦", "情人來電", "覓食中", "拜見周公", "假死狀態", "我在思考" }; static char * const sig_des[] = { - "鬥雞", "聊天", "", "下棋", "象棋", "暗棋", "下圍棋", + "鬥雞", "聊天", "", "下棋", "象棋", "暗棋", "下圍棋", "下黑白棋", }; static char * const withme_str[] = { - "談天", "下五子棋", "鬥寵物", "下象棋", "下暗棋", "下圍棋", NULL + "談天", "下五子棋", "鬥寵物", "下象棋", "下暗棋", "下圍棋", "下黑白棋", NULL }; #define MAX_SHOW_MODE 6 @@ -1566,10 +1566,11 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) if (ch == EDITING || ch == TALK || ch == CHATING || ch == PAGE || ch == MAILALL || ch == MONITOR || ch == M_FIVE || ch == CHC || - ch == DARK || ch == UMODE_GO || ch == CHESSWATCHING || + ch == DARK || ch == UMODE_GO || ch == CHESSWATCHING || ch == REVERSI || (!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3)) || uin->lockmode == M_FIVE || uin->lockmode == CHC) { - if (ch == CHC || ch == M_FIVE || ch == UMODE_GO || ch == CHESSWATCHING) { + if (ch == CHC || ch == M_FIVE || ch == UMODE_GO || + ch == CHESSWATCHING || ch == REVERSI) { sock = make_connection_to_somebody(uin, 20); if (sock < 0) vmsg("無法建立連線"); @@ -1599,6 +1600,10 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) case SIG_GO: gochess(msgsock, CHESS_MODE_WATCH); break; + + case SIG_REVERSI: + reversi(msgsock, CHESS_MODE_WATCH); + break; } } } @@ -1638,7 +1643,8 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) outc('\n'); } } - outs("要和他(她) (T)談天(F)下五子棋(P)鬥寵物(C)下象棋(D)下暗棋(G)下圍棋\n"); + move(4, 0); + outs("要和他(她) (T)談天(F)下五子棋(P)鬥寵物(C)下象棋(D)下暗棋(G)下圍棋(R)下黑白棋"); getdata(5, 0, " (N)沒事找錯人了?[N] ", genbuf, 4, LCECHO); } @@ -1661,6 +1667,9 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) case 'g': uin->sig = SIG_GO; break; + case 'r': + uin->sig = SIG_REVERSI; + break; case 'p': reload_chicken(); getuser(uin->userid, &xuser); @@ -1705,7 +1714,8 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) close(sock); currutmp->sockactive = NA; - if (uin->sig == SIG_CHC || uin->sig == SIG_GOMO || uin->sig == SIG_GO) + if (uin->sig == SIG_CHC || uin->sig == SIG_GOMO || + uin->sig == SIG_GO || uin->sig == SIG_REVERSI) ChessEstablishRequest(msgsock); add_io(msgsock, 0); @@ -1725,7 +1735,6 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) if (c == 'y') { snprintf(save_page_requestor, sizeof(save_page_requestor), "%s (%s)", uin->userid, uin->nickname); - /* gomo */ switch (uin->sig) { case SIG_DARK: main_dark(msgsock, uin); @@ -1742,6 +1751,9 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) case SIG_GO: gochess(msgsock, CHESS_MODE_VERSUS); break; + case SIG_REVERSI: + reversi(msgsock, CHESS_MODE_VERSUS); + break; case SIG_TALK: default: do_talk(msgsock); @@ -3164,7 +3176,7 @@ talkreply(void) currutmp->destuid = uip->uid; currstat = REPLY; /* 避免出現動畫 */ - is_chess = (sig == SIG_CHC || sig == SIG_GOMO || sig == SIG_GO); + is_chess = (sig == SIG_CHC || sig == SIG_GOMO || sig == SIG_GO || sig == SIG_REVERSI); a = reply_connection_request(uip); if (a < 0) { @@ -3254,6 +3266,9 @@ talkreply(void) case SIG_GO: gochess(a, CHESS_MODE_VERSUS); break; + case SIG_REVERSI: + reversi(a, CHESS_MODE_VERSUS); + break; case SIG_TALK: default: do_talk(a); |