summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-15 14:26:17 +0800
committerscw <scw@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-15 14:26:17 +0800
commit98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9 (patch)
tree319ebe57c18b21b8f31c95cd92626163e472b7e2
parent5936d5aa8dd56d023c8aa475ac0505406af88268 (diff)
downloadpttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar.gz
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar.bz2
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar.lz
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar.xz
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.tar.zst
pttbbs-98f0f5e0a45c6771ce43d69a13aa9b9ecce3faf9.zip
Gomoku convertion to chess.c framework
* versus, watching and personal playing * undo function removed due to the restriction of the framework currently chess.c framework update * resign confirm * invited peer can be watched !!!NOTE!!! Gomoku protocal not backward compatible RESTART WHOLE system to ensure correctness git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3036 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--include/chc.h15
-rw-r--r--include/chess.h4
-rw-r--r--include/gomo.h4
-rw-r--r--include/proto.h5
-rw-r--r--mbbsd/chc.c133
-rw-r--r--mbbsd/chess.c242
-rw-r--r--mbbsd/gomo.c917
-rw-r--r--mbbsd/menu.c11
-rw-r--r--mbbsd/talk.c21
-rw-r--r--mbbsd/var.c4
10 files changed, 551 insertions, 805 deletions
diff --git a/include/chc.h b/include/chc.h
index 900d4dd1..8b7fb23b 100644
--- a/include/chc.h
+++ b/include/chc.h
@@ -1,20 +1,6 @@
-#define SIDE_ROW 7
-#define REAL_TURN_ROW 8
-#define STEP_ROW 9
-#define REAL_TIME_ROW1 10
-#define REAL_TIME_ROW2 11
-#define REAL_WARN_ROW 13
-#define MYWIN_ROW 17
-#define HISWIN_ROW 18
-
-#define PHOTO_TURN_ROW 19
-#define PHOTO_TIME_ROW1 20
-#define PHOTO_TIME_ROW2 21
-#define PHOTO_WARN_ROW 22
#define CHE_O(c) ((c) >> 3)
#define CHE_P(c) ((c) & 7)
-#define dim(x) (sizeof(x) / sizeof(x[0]))
#define CHE(a, b) ((a) | ((b) << 3))
/* TODO let user flip chessboard */
#define REDDOWN(info) ((info)->myturn==RED)
@@ -26,7 +12,6 @@
#define RED_COLOR ANSI_COLOR(1;31)
#define BLACK_REVERSE ANSI_COLOR(1;37;46)
#define RED_REVERSE ANSI_COLOR(1;37;41)
-#define TURN_COLOR ANSI_COLOR(1;33)
#define BRD_ROW 10
#define BRD_COL 9
diff --git a/include/chess.h b/include/chess.h
index bf9443ce..a917efcc 100644
--- a/include/chess.h
+++ b/include/chess.h
@@ -143,6 +143,7 @@ typedef struct ChessConstants {
int traditional_timeout;
int board_height;
int board_width;
+ const char *chess_name;
const char *photo_file_name;
const char *log_board;
const char *turn_color[2];
@@ -180,4 +181,7 @@ void ChessEstablishRequest(int sock);
void ChessAcceptingRequest(int sock);
void ChessShowRequest(void);
+void ChessDrawLine(const ChessInfo* info, int line);
+void ChessDrawExtraInfo(const ChessInfo* info, int line);
+
#endif /* INCLUDE_CHESS_H */
diff --git a/include/gomo.h b/include/gomo.h
index b1228ba8..b5e8d014 100644
--- a/include/gomo.h
+++ b/include/gomo.h
@@ -3,9 +3,9 @@
#ifndef _INCLUDE_GOMO_H
#define _INCLUDE_GOMO_H
-#define BBLANK (0) /* 空白 */
+#define BBLANK (-1) /* 空白 */
+#define BWHITE (0) /* 白子, 後手 */
#define BBLACK (1) /* 黑子, 先手 */
-#define BWHITE (2) /* 白子, 後手 */
#define MAX_TIME (300) /*最長idle秒數*/
#ifndef BRDSIZ
#define BRDSIZ (15) /* 棋盤單邊大小 */
diff --git a/include/proto.h b/include/proto.h
index c20be401..a39a65c7 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -293,7 +293,10 @@ int gochess(int fd);
int GoBot(void);
/* gomo */
-int gomoku(int fd);
+void gomoku(int s, ChessGameMode mode);
+int gomoku_main(void);
+int gomoku_personal(void);
+int gomoku_watch(void);
/* guess */
int guess_main(void);
diff --git a/mbbsd/chc.c b/mbbsd/chc.c
index 40b190fa..f1339e14 100644
--- a/mbbsd/chc.c
+++ b/mbbsd/chc.c
@@ -116,6 +116,7 @@ static const ChessConstants chc_constants = {
CHC_TIMEOUT,
BRD_ROW,
BRD_COL,
+ "楚河漢界",
"photo_cchess",
#ifdef GLOBAL_CCHESS_LOG
GLOBAL_CCHESS_LOG,
@@ -194,12 +195,6 @@ getstep(board_t board, const rc_t *from, const rc_t *to, char buf[])
return buf;
}
-static void
-showstep(const ChessInfo* info)
-{
- outs(info->last_movestr);
-}
-
inline static const char*
chc_timestr(int second)
{
@@ -215,22 +210,6 @@ chc_drawline(const ChessInfo* info, int line)
board_p board = (board_p) info->board;
chc_tag_data_t *tag = info->tag;
- if (line == CHESS_DRAWING_TURN_ROW)
- line = info->photo ? PHOTO_TURN_ROW : REAL_TURN_ROW;
- else if (line == CHESS_DRAWING_TIME_ROW) {
- if(info->photo) {
- chc_drawline(info, PHOTO_TIME_ROW1);
- chc_drawline(info, PHOTO_TIME_ROW2);
- } else {
- chc_drawline(info, REAL_TIME_ROW1);
- chc_drawline(info, REAL_TIME_ROW2);
- }
- return;
- } else if (line == CHESS_DRAWING_WARN_ROW)
- line = info->photo ? PHOTO_WARN_ROW : REAL_WARN_ROW;
- else if (line == CHESS_DRAWING_STEP_ROW)
- line = STEP_ROW;
-
move(line, 0);
clrtoeol();
if (line == 0) {
@@ -271,100 +250,7 @@ chc_drawline(const ChessInfo* info, int line)
prints("%s ", num_str[REDDOWN(info)?1:0][i]);
}
- if (info->photo) {
- if (line >= 3 && line < 3 + CHESS_PHOTO_LINE) {
- outs(" ");
- outs(info->photo + (line - 3) * CHESS_PHOTO_COLUMN);
- } else if (line >= PHOTO_TURN_ROW && line <= PHOTO_WARN_ROW) {
- outs(" ");
- if (line == PHOTO_TURN_ROW)
- prints("%s%s" ANSI_RESET,
- TURN_COLOR,
- info->myturn == info->turn ? "輪到你下棋了" : "等待對方下棋");
- else if (line == PHOTO_TIME_ROW1) {
- if (info->mode == CHESS_MODE_WATCH) {
- if (!info->timelimit)
- prints("每手限時五分鐘");
- else
- prints("局時: %5s",
- chc_timestr(info->timelimit->free_time));
- } else if (info->lefthand[0])
- prints("我方剩餘時間 %s / %2d 步",
- chc_timestr(info->lefttime[0]),
- info->lefthand[0]);
- else
- prints("我方剩餘時間 %s",
- chc_timestr(info->lefttime[0]));
- } else if (line == PHOTO_TIME_ROW2) {
- if (info->mode == CHESS_MODE_WATCH) {
- if (info->timelimit) {
- if (info->timelimit->time_mode ==
- CHESS_TIMEMODE_MULTIHAND)
- prints("步時: %s / %2d 步",
- chc_timestr(info->timelimit->limit_time),
- info->timelimit->limit_hand);
- else
- prints("讀秒: %5d 秒",
- info->timelimit->limit_time);
- }
- } else if (info->lefthand[1])
- prints("對方剩餘時間 %s / %2d 步",
- chc_timestr(info->lefttime[1]),
- info->lefthand[1]);
- else
- prints("對方剩餘時間 %s",
- chc_timestr(info->lefttime[1]));
- } else if (line == PHOTO_WARN_ROW)
- outs(info->warnmsg);
- }
- } else if (line >= 3 && line <= HISWIN_ROW) {
- outs(" ");
- if (line >= 3 && line < 3 + (int)dim(hint_str)) {
- outs(hint_str[line - 3]);
- } else if (line == SIDE_ROW) {
- prints(ANSI_COLOR(1) "你是%s%s" ANSI_RESET,
- turn_color[(int) info->myturn],
- turn_str[(int) info->myturn]);
- } else if (line == REAL_TURN_ROW) {
- prints("%s%s" ANSI_RESET,
- TURN_COLOR,
- info->myturn == info->turn ? "輪到你下棋了" : "等待對方下棋");
- } else if (line == STEP_ROW && info->last_movestr) {
- showstep(info);
- } else if (line == REAL_TIME_ROW1) {
- if (info->lefthand[0])
- prints("我方剩餘時間 %s / %2d 步",
- chc_timestr(info->lefttime[0]),
- info->lefthand[0]);
- else
- prints("我方剩餘時間 %s",
- chc_timestr(info->lefttime[0]));
- } else if (line == REAL_TIME_ROW2) {
- if (info->lefthand[1])
- prints("對方剩餘時間 %s / %2d 步",
- chc_timestr(info->lefttime[1]),
- info->lefthand[1]);
- else
- prints("對方剩餘時間 %s",
- chc_timestr(info->lefttime[1]));
- } else if (line == REAL_WARN_ROW) {
- outs(info->warnmsg);
- } else if (line == MYWIN_ROW) {
- prints(ANSI_COLOR(1;33) "%12.12s "
- ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "勝 "
- ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "敗 "
- ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "和" ANSI_RESET,
- info->user1.userid,
- info->user1.win, info->user1.lose - 1, info->user1.tie);
- } else if (line == HISWIN_ROW) {
- prints(ANSI_COLOR(1;33) "%12.12s "
- ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "勝 "
- ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "敗 "
- ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "和" ANSI_RESET,
- info->user2.userid,
- info->user2.win, info->user2.lose, info->user2.tie);
- }
- }
+ ChessDrawExtraInfo(info, line);
}
/*
* End of the drawing function.
@@ -511,8 +397,8 @@ chc_movechess(board_t board, const drc_t* move)
static void
chc_drawstep(ChessInfo* info, const drc_t* move)
{
- info->actions->drawline(info, LTR(info, move->from.r));
- info->actions->drawline(info, LTR(info, move->to.r));
+ ChessDrawLine(info, LTR(info, move->from.r));
+ ChessDrawLine(info, LTR(info, move->to.r));
}
/* 求兩座標行或列(rowcol)的距離 */
@@ -748,13 +634,13 @@ chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result)
/* they can pick up this */
tag->selected = 1;
tag->select = loc;
- chc_drawline(info, LTR(info, loc.r));
+ ChessDrawLine(info, LTR(info, loc.r));
}
return 0;
} else if (tag->select.r == loc.r && tag->select.c == loc.c) {
/* cancel selection */
tag->selected = 0;
- chc_drawline(info, LTR(info, loc.r));
+ ChessDrawLine(info, LTR(info, loc.r));
return 0;
} else if (chc_canmove(board, tag->select, loc)) {
/* moving the chess */
@@ -775,8 +661,8 @@ chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result)
getstep(board, &moving.from, &moving.to, info->last_movestr);
chc_movechess(board, &moving);
- chc_drawline(info, LTR(info, moving.from.r));
- chc_drawline(info, LTR(info, moving.to.r));
+ ChessDrawLine(info, LTR(info, moving.from.r));
+ ChessDrawLine(info, LTR(info, moving.to.r));
ChessHistoryAppend(info, &moving);
ChessStepSend(info, &moving);
@@ -789,7 +675,7 @@ chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result)
ANSI_COLOR(1;33) "不可以王見王" ANSI_RESET,
sizeof(info->warnmsg));
bell();
- chc_drawline(info, REAL_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
return 0;
}
} else
@@ -876,6 +762,7 @@ chc(int s, ChessGameMode mode)
setutmpmode(CHESSWATCHING);
else
setutmpmode(CHC);
+ currutmp->sig = SIG_CHC;
ChessPlay(info);
diff --git a/mbbsd/chess.c b/mbbsd/chess.c
index 7453a78f..1b585f12 100644
--- a/mbbsd/chess.c
+++ b/mbbsd/chess.c
@@ -3,10 +3,33 @@
#include "chess.h"
#define assert_not_reached() assert(!"Should never be here!!!")
+#define dim(x) (sizeof(x) / sizeof(x[0]))
#define CHESS_HISTORY_INITIAL_BUFFER_SIZE 300
#define CHESS_HISTORY_BUFFER_INCREMENT 50
+#define CHESS_DRAWING_SIDE_ROW 7
+#define CHESS_DRAWING_REAL_TURN_ROW 8
+#define CHESS_DRAWING_REAL_STEP_ROW 9
+#define CHESS_DRAWING_REAL_TIME_ROW1 10
+#define CHESS_DRAWING_REAL_TIME_ROW2 11
+#define CHESS_DRAWING_REAL_WARN_ROW 13
+#define CHESS_DRAWING_MYWIN_ROW 17
+#define CHESS_DRAWING_HISWIN_ROW 18
+#define CHESS_DRAWING_PHOTOED_TURN_ROW 19
+#define CHESS_DRAWING_PHOTOED_TIME_ROW1 20
+#define CHESS_DRAWING_PHOTOED_TIME_ROW2 21
+#define CHESS_DRAWING_PHOTOED_WARN_ROW 22
+#define CHESS_DRAWING_PHOTOED_STEP_ROW 23
+
+
+static const char * const ChessHintStr[] = {
+ " q 認輸離開",
+ " p 要求和棋",
+ "方向鍵 移動遊標",
+ "Enter 選擇/移動"
+};
+
static ChessInfo * CurrentPlayingGameInfo;
/* XXX: This is a BAD way to pass information.
@@ -115,6 +138,34 @@ ChessDrawHelpLine(const ChessInfo* info)
mouts(b_lines, 0, HelpStr[info->mode]);
}
+void
+ChessDrawLine(const ChessInfo* info, int line)
+{
+ if (line == b_lines)
+ ChessDrawHelpLine(info);
+ else if (line == CHESS_DRAWING_TURN_ROW)
+ line = info->photo ?
+ CHESS_DRAWING_PHOTOED_TURN_ROW :
+ CHESS_DRAWING_REAL_TURN_ROW;
+ else if (line == CHESS_DRAWING_TIME_ROW) {
+ if(info->photo) {
+ info->actions->drawline(info, CHESS_DRAWING_PHOTOED_TIME_ROW1);
+ info->actions->drawline(info, CHESS_DRAWING_PHOTOED_TIME_ROW2);
+ } else {
+ info->actions->drawline(info, CHESS_DRAWING_REAL_TIME_ROW1);
+ info->actions->drawline(info, CHESS_DRAWING_REAL_TIME_ROW2);
+ }
+ return;
+ } else if (line == CHESS_DRAWING_WARN_ROW)
+ line = info->photo ?
+ CHESS_DRAWING_PHOTOED_WARN_ROW :
+ CHESS_DRAWING_REAL_WARN_ROW;
+ else if (line == CHESS_DRAWING_STEP_ROW)
+ line = CHESS_DRAWING_REAL_STEP_ROW;
+
+ info->actions->drawline(info, line);
+}
+
static void
ChessRedraw(const ChessInfo* info)
{
@@ -135,9 +186,10 @@ ChessTimeCountDownCalc(ChessInfo* info, int who, int length)
if (info->lefttime[who] < 0) { /* only allowed when in free time */
if (info->lefthand[who])
return 1;
- info->lefttime[who] = info->timelimit->limit_time;
- info->lefthand[who] = info->timelimit->limit_hand;
- return 0;
+ info->lefttime[who] += info->timelimit->limit_time;
+ info->lefthand[who] = info->timelimit->limit_hand;
+
+ return (info->lefttime[who] < 0);
}
return 0;
@@ -147,7 +199,7 @@ int
ChessTimeCountDown(ChessInfo* info, int who, int length)
{
int result = ChessTimeCountDownCalc(info, who, length);
- info->actions->drawline(info, CHESS_DRAWING_TIME_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
return result;
}
@@ -290,13 +342,17 @@ ChessPlayFuncMy(ChessInfo* info)
while (!endturn) {
ChessStepType result;
- info->actions->drawline(info, CHESS_DRAWING_TIME_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
info->actions->movecur(info->cursor.r, info->cursor.c);
oflush();
ch = igetch();
- if (ChessTimeCountDown(info, 0, now - last_time))
- ch = 'q';
+ if (ChessTimeCountDown(info, 0, now - last_time)) {
+ /* ran out of time */
+ game_result = CHESS_RESULT_LOST;
+ endturn = 1;
+ break;
+ }
last_time = now;
switch (ch) {
@@ -338,8 +394,17 @@ ChessPlayFuncMy(ChessInfo* info)
break;
case 'q':
- game_result = CHESS_RESULT_LOST;
- endturn = 1;
+ {
+ char buf[4];
+ getdata(b_lines, 0, "是否真的要認輸?(y/N)",
+ buf, sizeof(buf), DOECHO);
+ ChessDrawHelpLine(info);
+
+ if (buf[0] == 'y' || buf[0] == 'Y') {
+ game_result = CHESS_RESULT_LOST;
+ endturn = 1;
+ }
+ }
break;
case 'p':
@@ -355,7 +420,7 @@ ChessPlayFuncMy(ChessInfo* info)
strlcpy(info->warnmsg,
ANSI_COLOR(1;33) "要求和棋!" ANSI_RESET,
sizeof(info->warnmsg));
- info->actions->drawline(info, CHESS_DRAWING_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
bell();
}
}
@@ -370,8 +435,8 @@ ChessPlayFuncMy(ChessInfo* info)
}
ChessTimeCountDown(info, 0, now - last_time);
ChessStepMade(info, 0);
- info->actions->drawline(info, CHESS_DRAWING_TIME_ROW);
- info->actions->drawline(info, CHESS_DRAWING_STEP_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_STEP_ROW);
return game_result;
}
@@ -393,14 +458,23 @@ ChessPlayFuncHis(ChessInfo* info)
}
last_time = now;
- info->actions->drawline(info, CHESS_DRAWING_TIME_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
move(1, 0);
oflush();
switch (igetch()) {
case 'q':
- game_result = CHESS_RESULT_LOST;
- endturn = 1;
+ {
+ char buf[4];
+ getdata(b_lines, 0, "是否真的要認輸?(y/N)",
+ buf, sizeof(buf), DOECHO);
+ ChessDrawHelpLine(info);
+
+ if (buf[0] == 'y' || buf[0] == 'Y') {
+ game_result = CHESS_RESULT_LOST;
+ endturn = 1;
+ }
+ }
break;
case 'p':
@@ -423,7 +497,7 @@ ChessPlayFuncHis(ChessInfo* info)
strlcpy(info->warnmsg,
ANSI_COLOR(1;33) "要求和局!" ANSI_RESET,
sizeof(info->warnmsg));
- info->actions->drawline(info, CHESS_DRAWING_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
} else {
info->actions->prepare_step(info, &info->step_tmp);
if (info->actions->apply_step(info->board, &info->step_tmp))
@@ -436,8 +510,8 @@ ChessPlayFuncHis(ChessInfo* info)
}
}
ChessTimeCountDown(info, 1, now - last_time);
- info->actions->drawline(info, CHESS_DRAWING_TIME_ROW);
- info->actions->drawline(info, CHESS_DRAWING_STEP_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_STEP_ROW);
return game_result;
}
@@ -452,7 +526,7 @@ ChessPlayFuncWatch(ChessInfo* info)
strlcpy(info->warnmsg, ANSI_COLOR(1;33) "棋局已結束" ANSI_RESET,
sizeof(info->warnmsg));
- info->actions->drawline(info, CHESS_DRAWING_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
move(1, 0);
switch (igetch()) {
@@ -656,7 +730,8 @@ ChessGenLogUser(ChessInfo* info, ChessGameResult result)
info->actions->genlog(info, fp, result);
fclose(fp);
- strlcpy(log_header.owner, "[楚河漢界]", sizeof(log_header.owner));
+ snprintf(log_header.owner, sizeof(log_header.owner), "[%s]",
+ info->constants->chess_name);
if(info->myturn == 0)
sprintf(log_header.title, "%s V.S. %s",
info->user1.userid, info->user2.userid);
@@ -702,7 +777,15 @@ ChessPlay(ChessInfo* info)
}
CurrentPlayingGameInfo = info;
- old_handler = Signal(SIGUSR1, &ChessWatchRequest);
+
+ {
+ sigset_t sigset;
+ old_handler = Signal(SIGUSR1, &ChessWatchRequest);
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGUSR1);
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+ }
if (info->mode == CHESS_MODE_WATCH) {
int i;
@@ -725,8 +808,8 @@ ChessPlay(ChessInfo* info)
game_result == CHESS_RESULT_CONTINUE;
info->turn ^= 1) {
info->actions->prepare_play(info);
- info->actions->drawline(info, CHESS_DRAWING_TURN_ROW);
- info->actions->drawline(info, CHESS_DRAWING_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_TURN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
game_result = info->play_func[(int) info->turn](info);
}
add_io(0, 0);
@@ -761,12 +844,13 @@ ChessPlay(ChessInfo* info)
if (game_result_str) {
strlcpy(info->warnmsg, game_result_str, sizeof(info->warnmsg));
- info->actions->drawline(info, CHESS_DRAWING_WARN_ROW);
+ ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
}
info->actions->gameend(info, game_result);
ChessGenLog(info, game_result);
+ currutmp->sig = -1;
Signal(SIGUSR1, old_handler);
CurrentPlayingGameInfo = NULL;
}
@@ -866,8 +950,10 @@ ChessWatchGame(void (*play)(int, ChessGameMode), int game, const char* title)
if ((uin = ChessSearchUser(-1, title)) == NULL)
return -1;
- if (uin->uid == currutmp->uid || uin->mode != game)
+ if (uin->uid == currutmp->uid || uin->mode != game) {
+ vmsg("無法建立連線");
return -1;
+ }
if (getans("是否進行觀棋? [N/y]") != 'y')
return 0;
@@ -1193,3 +1279,109 @@ ChessShowRequest(void)
}
}
+inline static const char*
+ChessTimeStr(int second)
+{
+ static char buf[10];
+ snprintf(buf, sizeof(buf), "%d:%02d", second / 60, second % 60);
+ return buf;
+}
+
+void
+ChessDrawExtraInfo(const ChessInfo* info, int line)
+{
+ if (info->photo) {
+ if (line >= 3 && line < 3 + CHESS_PHOTO_LINE) {
+ outs(" ");
+ outs(info->photo + (line - 3) * CHESS_PHOTO_COLUMN);
+ } else if (line >= CHESS_DRAWING_PHOTOED_TURN_ROW &&
+ line <= CHESS_DRAWING_PHOTOED_WARN_ROW) {
+ outs(" ");
+ if (line == CHESS_DRAWING_PHOTOED_TURN_ROW)
+ prints(ANSI_COLOR(1;33) "%s" ANSI_RESET,
+ info->myturn == info->turn ? "輪到你下棋了" : "等待對方下棋");
+ else if (line == CHESS_DRAWING_PHOTOED_TIME_ROW1) {
+ if (info->mode == CHESS_MODE_WATCH) {
+ if (!info->timelimit)
+ prints("每手限時五分鐘");
+ else
+ prints("局時: %5s",
+ ChessTimeStr(info->timelimit->free_time));
+ } else if (info->lefthand[0])
+ prints("我方剩餘時間 %s / %2d 步",
+ ChessTimeStr(info->lefttime[0]),
+ info->lefthand[0]);
+ else
+ prints("我方剩餘時間 %s",
+ ChessTimeStr(info->lefttime[0]));
+ } else if (line == CHESS_DRAWING_PHOTOED_TIME_ROW2) {
+ if (info->mode == CHESS_MODE_WATCH) {
+ if (info->timelimit) {
+ if (info->timelimit->time_mode ==
+ CHESS_TIMEMODE_MULTIHAND)
+ prints("步時: %s / %2d 步",
+ ChessTimeStr(info->timelimit->limit_time),
+ info->timelimit->limit_hand);
+ else
+ prints("讀秒: %5d 秒",
+ info->timelimit->limit_time);
+ }
+ } else if (info->lefthand[1])
+ prints("對方剩餘時間 %s / %2d 步",
+ ChessTimeStr(info->lefttime[1]),
+ info->lefthand[1]);
+ else
+ prints("對方剩餘時間 %s",
+ ChessTimeStr(info->lefttime[1]));
+ } else if (line == CHESS_DRAWING_PHOTOED_WARN_ROW)
+ outs(info->warnmsg);
+ }
+ } else if (line >= 3 && line <= CHESS_DRAWING_HISWIN_ROW) {
+ outs(" ");
+ if (line >= 3 && line < 3 + (int)dim(ChessHintStr)) {
+ outs(ChessHintStr[line - 3]);
+ } else if (line == CHESS_DRAWING_SIDE_ROW) {
+ prints(ANSI_COLOR(1) "你是%s%s" ANSI_RESET,
+ info->constants->turn_color[(int) info->myturn],
+ info->constants->turn_str[(int) info->myturn]);
+ } else if (line == CHESS_DRAWING_REAL_TURN_ROW) {
+ prints(ANSI_COLOR(1;33) "%s" ANSI_RESET,
+ info->myturn == info->turn ?
+ "輪到你下棋了" : "等待對方下棋");
+ } else if (line == CHESS_DRAWING_REAL_STEP_ROW && info->last_movestr) {
+ outs(info->last_movestr);
+ } else if (line == CHESS_DRAWING_REAL_TIME_ROW1) {
+ if (info->lefthand[0])
+ prints("我方剩餘時間 %s / %2d 步",
+ ChessTimeStr(info->lefttime[0]),
+ info->lefthand[0]);
+ else
+ prints("我方剩餘時間 %s",
+ ChessTimeStr(info->lefttime[0]));
+ } else if (line == CHESS_DRAWING_REAL_TIME_ROW2) {
+ if (info->lefthand[1])
+ prints("對方剩餘時間 %s / %2d 步",
+ ChessTimeStr(info->lefttime[1]),
+ info->lefthand[1]);
+ else
+ prints("對方剩餘時間 %s",
+ ChessTimeStr(info->lefttime[1]));
+ } else if (line == CHESS_DRAWING_REAL_WARN_ROW) {
+ outs(info->warnmsg);
+ } else if (line == CHESS_DRAWING_MYWIN_ROW) {
+ prints(ANSI_COLOR(1;33) "%12.12s "
+ ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "勝 "
+ ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "敗 "
+ ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "和" ANSI_RESET,
+ info->user1.userid,
+ info->user1.win, info->user1.lose - 1, info->user1.tie);
+ } else if (line == CHESS_DRAWING_HISWIN_ROW) {
+ prints(ANSI_COLOR(1;33) "%12.12s "
+ ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "勝 "
+ ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "敗 "
+ ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "和" ANSI_RESET,
+ info->user2.userid,
+ info->user2.win, info->user2.lose, info->user2.tie);
+ }
+ }
+}
diff --git a/mbbsd/gomo.c b/mbbsd/gomo.c
index 196fa933..561c4003 100644
--- a/mbbsd/gomo.c
+++ b/mbbsd/gomo.c
@@ -3,15 +3,71 @@
#include "gomo.h"
#define QCAST int (*)(const void *, const void *)
+#define BOARD_LINE_ON_SCREEN(X) ((X) + 2)
-static int tick, lastcount, mylasttick, hislasttick;
-//static char ku[BRDSIZ][BRDSIZ];
+static const char* turn_color[] = { ANSI_COLOR(30;43), ANSI_COLOR(37;43) };
-static Horder_t *v;
-static int draw_photo;
+enum Turn {
+ WHT = 0,
+ BLK
+};
+typedef struct {
+ ChessStepType type; /* necessary one */
+ int color;
+ rc_t loc;
+} gomo_step_t;
+
+typedef char board_t[BRDSIZ][BRDSIZ];
+typedef char (*board_p)[BRDSIZ];
+
+#if 0
#define move(y,x) move(y, (x) + ((y) < 2 || (y) > 16 ? 0 : \
(x) > 35 ? 11 : 8))
+#endif
+
+static void gomo_init_user(const userinfo_t* uinfo, 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_select(ChessInfo* info, rc_t location,
+ ChessGameResult* result);
+static void gomo_prepare_step(ChessInfo* info, const gomo_step_t* step);
+static int gomo_apply_step(board_t board, const gomo_step_t* step);
+static void gomo_drawstep(ChessInfo* info, const gomo_step_t* step);
+static void gomo_gameend(ChessInfo* info, ChessGameResult result);
+static void gomo_genlog(ChessInfo* info, FILE* fp, ChessGameResult result);
+
+ChessActions gomo_actions = {
+ &gomo_init_user,
+ (void (*)(void*)) &gomo_init_board,
+ &gomo_drawline,
+ &gomo_movecur,
+ &gomo_prepare_play,
+ &gomo_select,
+ (void (*)(ChessInfo*, const void*)) &gomo_prepare_step,
+ (int (*)(void*, const void*)) &gomo_apply_step,
+ (void (*)(ChessInfo*, const void*)) &gomo_drawstep,
+ &gomo_gameend,
+ &gomo_genlog
+};
+
+ChessConstants gomo_constants = {
+ sizeof(gomo_step_t),
+ MAX_TIME,
+ BRDSIZ,
+ BRDSIZ,
+ "五子棋",
+ "photo_fivechess",
+#ifdef GLOBAL_FIVECHESS_LOG
+ GLOBAL_FIVECHESS_LOG,
+#else
+ NULL,
+#endif
+ { ANSI_COLOR(37;43), ANSI_COLOR(30;43) },
+ { "白棋", "黑棋, 有禁手" },
+};
/* pattern and advance map */
@@ -26,7 +82,7 @@ intrevcmp(const void *a, const void *b)
// 最高位 1 表示對方的子, 或是牆
/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; dx,dy: -1,0,+1 */
static int
-gomo_getindex(char ku[][BRDSIZ], int x, int y, int color, int dx, int dy)
+gomo_getindex(board_t ku, int x, int y, int color, int dx, int dy)
{
int i, k, n;
for (n = -1, i = 0, k = 1; i < 5; i++, k*=2) {
@@ -49,25 +105,25 @@ gomo_getindex(char ku[][BRDSIZ], int x, int y, int color, int dx, int dy)
return n;
}
-int
+ChessGameResult
chkwin(int style, int limit)
{
if (style == 0x0c)
- return 1 /* style */ ;
+ return CHESS_RESULT_WIN;
else if (limit == 0) {
if (style == 0x0b)
- return 1 /* style */ ;
- return 0;
+ return CHESS_RESULT_WIN;
+ return CHESS_RESULT_CONTINUE;
}
if ((style < 0x0c) && (style > 0x07))
- return -1 /* -style */ ;
- return 0;
+ return CHESS_RESULT_LOST;
+ return CHESS_RESULT_CONTINUE;
}
-static int getstyle(char ku[][BRDSIZ], int x, int y, int color, int limit);
+static int getstyle(board_t ku, int x, int y, int color, int limit);
/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; limit:1,0 ; dx,dy: 0,1 */
static int
-dirchk(char ku[][BRDSIZ], int x, int y, int color, int limit, int dx, int dy)
+dirchk(board_t ku, int x, int y, int color, int limit, int dx, int dy)
{
int le, ri, loc, style = 0;
@@ -77,7 +133,7 @@ dirchk(char ku[][BRDSIZ], int x, int y, int color, int limit, int dx, int dy)
loc = (le > ri) ? (((le * (le + 1)) >> 1) + ri) :
(((ri * (ri + 1)) >> 1) + le);
- style = pat[loc];
+ style = pat_gomoku[loc];
if (limit == 0)
return (style & 0x0f);
@@ -87,7 +143,7 @@ dirchk(char ku[][BRDSIZ], int x, int y, int color, int limit, int dx, int dy)
if ((style == 3) || (style == 2)) {
int i, n = 0, tmp, nx, ny;
- n = adv[loc / 2];
+ n = adv_gomoku[loc / 2];
if(loc%2==0)
n/=16;
@@ -118,7 +174,7 @@ dirchk(char ku[][BRDSIZ], int x, int y, int color, int limit, int dx, int dy)
/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; limit: 1,0 */
static int
-getstyle(char ku[][BRDSIZ], int x, int y, int color, int limit)
+getstyle(board_t ku, int x, int y, int color, int limit)
{
int i, j, dir[4], style;
@@ -148,673 +204,280 @@ getstyle(char ku[][BRDSIZ], int x, int y, int color, int limit)
return style;
}
-static void
-HO_init(char ku[][BRDSIZ], Horder_t *pool)
+static char*
+gomo_move_warn(int style, char buf[])
{
- memset(pool, 0, sizeof(Horder_t)*BRDSIZ*BRDSIZ);
- v = pool;
- pat = pat_gomoku;
- adv = adv_gomoku;
- memset(ku, 0, (BRDSIZ*BRDSIZ));
+ char *xtype[] = {
+ ANSI_COLOR(1;31) "跳三" ANSI_RESET,
+ ANSI_COLOR(1;31) "活三" ANSI_RESET,
+ ANSI_COLOR(1;31) "死四" ANSI_RESET,
+ ANSI_COLOR(1;31) "跳四" ANSI_RESET,
+ ANSI_COLOR(1;31) "活四" ANSI_RESET,
+ ANSI_COLOR(1;31) "四三" ANSI_RESET,
+ ANSI_COLOR(1;31) "雙三" ANSI_RESET,
+ ANSI_COLOR(1;31) "雙四" ANSI_RESET,
+ ANSI_COLOR(1;31) "雙四" ANSI_RESET,
+ ANSI_COLOR(1;31) "連六" ANSI_RESET,
+ ANSI_COLOR(1;31) "連五" ANSI_RESET
+ };
+ if (style > 1 && style < 13)
+ return strcpy(buf, xtype[style - 2]);
+ else
+ return NULL;
}
static void
-HO_add(Horder_t * mv)
+gomoku_usr_put(userec_t* userec, const ChessUser* user)
{
- *v++ = *mv;
+ userec->five_win = user->win;
+ userec->five_lose = user->lose;
+ userec->five_tie = user->tie;
}
-static void
-HO_undo(char ku[][BRDSIZ], Horder_t * mv)
+static char*
+gomo_getstep(const gomo_step_t* step, char buf[])
{
- char *str = "┌┬┐├┼┤└┴┘";
- int n1, n2, loc;
-
- *mv = *(--v);
- ku[(int)mv->x][(int)mv->y] = BBLANK;
- BGOTO(mv->x, mv->y);
- n1 = (mv->x == 0) ? 0 : (mv->x == 14) ? 2 : 1;
- n2 = (mv->y == 14) ? 0 : (mv->y == 0) ? 2 : 1;
- loc = 2 * (n2 * 3 + n1);
- prints("%.2s", str + loc);
- redoln();
+ const static char* const ColName = "ABCDEFGHIJKLMN";
+ const static char* const RawName = "123456789101112131415";
+ const static int ansi_length = sizeof(ANSI_COLOR(30;43));
+
+ strcpy(buf, turn_color[step->color]);
+ buf[ansi_length ] = ColName[step->loc.c * 2];
+ buf[ansi_length + 1] = ColName[step->loc.c * 2 + 1];
+ buf[ansi_length + 2] = RawName[step->loc.r * 2];
+ buf[ansi_length + 3] = RawName[step->loc.r * 2 + 1];
+ strcpy(buf + ansi_length + 4, ANSI_RESET);
+
+ return buf;
}
static void
-HO_log(Horder_t *pool, FILE* fp, char *mate)
+gomo_init_user(const userinfo_t* uinfo, ChessUser* user)
{
- int i;
- Horder_t *ptr = pool;
-
- for (i = 1; i < 18; i++)
- fprintf(fp, "%.*s\n", big_picture[i].len, big_picture[i].data);
-
- if (mate != NULL)
- fprintf(fp, "<gomokulog>\nblack:%s\nwhite:%s\n", cuser.userid, mate);
-
- i = 0;
- do {
- fprintf(fp, "[%2d]%s ==> %c%-5d", i + 1, bw_chess[i % 2],
- 'A' + ptr->x, ptr->y + 1);
- if (i % 2)
- fputc('\n', fp);
- i++;
- } while (++ptr < v);
-
- if (mate != NULL)
- fputs("\n</gomokulog>\n", fp);
+ strlcpy(user->userid, uinfo->userid, sizeof(user->userid));
+ user->win = uinfo->five_win;
+ user->lose = uinfo->five_lose;
+ user->tie = uinfo->five_tie;
}
static void
-HO_log_user(Horder_t* pool, char *mate)
+gomo_init_board(board_t board)
{
- char buf[200];
- fileheader_t mail_header;
- FILE* fp;
+ memset(board, 0xff, sizeof(board_t));
+}
- sethomepath(buf, cuser.userid);
- stampfile(buf, &mail_header);
+static void
+gomo_drawline(const ChessInfo* info, int line)
+{
+ const static char* const BoardPic[] = {
+ "┌", "┬", "┐",
+ "├", "┼", "┤",
+ "└", "┴", "┘"
+ };
+ const static int BoardPicIndex[] =
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
+
+ board_p board = (board_p) info->board;
+
+ move(line, 0);
+ clrtoeol();
+ 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 == 1) {
+ outs(" A B C D E F G H I J K L M N");
+ } else if (line >= 2 && line <= 16) {
+ const int board_line = line - 2;
+ const char* const* const pics =
+ board_line == 0 ? &BoardPic[0] :
+ board_line == 14 ? &BoardPic[6] : &BoardPic[3];
+ int i;
+
+ prints("%3d" ANSI_COLOR(30;43), 17 - line);
+
+ for (i = 0; i < 15; ++i)
+ if (board[board_line][i] == -1)
+ outs(pics[BoardPicIndex[i]]);
+ else
+ outs(bw_chess[(int) board[board_line][i]]);
- fp = fopen(buf, "w");
- if (fp != NULL) {
- HO_log(pool, fp, NULL);
- fclose(fp);
+ outs(ANSI_RESET);
+ } else if (line >= 17 && line <= 23)
+ prints("%33s", "");
- mail_header.filemode = FILE_READ;
- strlcpy(mail_header.owner, "[備.忘.錄]", sizeof(mail_header.owner));
- snprintf(mail_header.title, sizeof(mail_header.title),
- ANSI_COLOR(37;41) "棋譜" ANSI_RESET " %s VS %s", cuser.userid, mate);
+ ChessDrawExtraInfo(info, line);
+}
- sethomedir(buf, cuser.userid);
- append_record(buf, &mail_header, sizeof(mail_header));
- }
+static void
+gomo_movecur(int r, int c)
+{
+ move(r + 2, c * 2 + 3);
}
-#ifdef GLOBAL_FIVECHESS_LOG
static void
-HO_log_board(Horder_t* pool, char *mate)
+gomo_prepare_play(ChessInfo* info)
+{
+ if (!gomo_move_warn(*(int*) info->tag, info->warnmsg))
+ info->warnmsg[0] = 0;
+}
+
+static int
+gomo_select(ChessInfo* info, rc_t location, ChessGameResult* result)
{
- char buf[200];
- fileheader_t log_header;
- FILE* fp;
- int bid;
+ board_p board = (board_p) info->board;
+ gomo_step_t step;
+
+ if(board[location.r][location.c] != BBLANK)
+ return 0;
- if ((bid = getbnum(GLOBAL_FIVECHESS_LOG)) == 0)
- return;
+ *(int*) info->tag = getstyle(board, location.r, location.c,
+ info->turn, info->turn == BLK);
+ *result = chkwin(*(int*) info->tag, info->turn == BLK);
- setbpath(buf, GLOBAL_FIVECHESS_LOG);
- stampfile(buf, &log_header);
+ board[location.r][location.c] = info->turn;
- fp = fopen(buf, "w");
- if (fp != NULL) {
- HO_log(pool, fp, mate);
- fclose(fp);
+ step.type = CHESS_STEP_NORMAL;
+ step.color = info->turn;
+ step.loc = location;
+ gomo_getstep(&step, info->last_movestr);
- strlcpy(log_header.owner, "[棋譜機器人]", sizeof(log_header.owner));
- snprintf(log_header.title, sizeof(log_header.title),
- "[棋譜] %s VS %s", cuser.userid, mate);
+ ChessHistoryAppend(info, &step);
+ ChessStepSend(info, &step);
+ gomo_drawstep(info, &step);
- setbdir(buf, GLOBAL_FIVECHESS_LOG);
- append_record(buf, &log_header, sizeof(log_header));
+ return 1;
+}
- setbtotal(bid);
+static void
+gomo_prepare_step(ChessInfo* info, const gomo_step_t* step)
+{
+ if (step->type == CHESS_STEP_NORMAL) {
+ gomo_getstep(step, info->last_movestr);
+ *(int*) info->tag = getstyle(info->board, step->loc.r, step->loc.c,
+ step->color, step->color == BLK);
}
}
-#endif
static int
-countgomo(Horder_t *pool)
+gomo_apply_step(board_t board, const gomo_step_t* step)
{
- return v-pool;
+ int style;
+
+ style = getstyle(board, step->loc.r, step->loc.c,
+ step->color, step->color == BLK);
+ board[step->loc.r][step->loc.c] = step->color;
+ return (chkwin(style, step->color == BLK) != CHESS_RESULT_CONTINUE);
}
-static int
-chkmv(char ku[][BRDSIZ], Horder_t * mv, int color, int limit)
+static void
+gomo_drawstep(ChessInfo* info, const gomo_step_t* step)
{
- char *xtype[] = {ANSI_COLOR(1;31) "跳三" ANSI_RESET, ANSI_COLOR(1;31) "活三" ANSI_RESET,
- ANSI_COLOR(1;31) "死四" ANSI_RESET, ANSI_COLOR(1;31) "跳四" ANSI_RESET,
- ANSI_COLOR(1;31) "活四" ANSI_RESET, ANSI_COLOR(1;31) "四三" ANSI_RESET,
- ANSI_COLOR(1;31) "雙三" ANSI_RESET, ANSI_COLOR(1;31) "雙四" ANSI_RESET,
- ANSI_COLOR(1;31) "雙四" ANSI_RESET, ANSI_COLOR(1;31) "連六" ANSI_RESET,
- ANSI_COLOR(1;31) "連五" ANSI_RESET};
- int rule = getstyle(ku, mv->x, mv->y, color, limit);
- if (rule > 1 && rule < 13) {
- move(draw_photo ? 19 : 15, 40);
- outs(xtype[rule - 2]);
- bell();
- }
- return chkwin(rule, limit);
+ ChessDrawLine(info, BOARD_LINE_ON_SCREEN(step->loc.r));
}
-static int
-gomo_key(char ku[][BRDSIZ], int fd, int ch, Horder_t * mv)
+static void
+gomo_gameend(ChessInfo* info, ChessGameResult result)
{
- if (ch >= 'a' && ch <= 'o') {
- char pbuf[4], vx, vy;
-
- pbuf[0] = ch;
- pbuf[1] = '\0';
-
- if (fd)
- add_io(0, 0);
- oldgetdata(17, 0, "直接指定位置 :", pbuf, sizeof(pbuf), DOECHO);
- if (fd)
- add_io(fd, 0);
- vx = pbuf[0] - 'a';
- vy = atoi(pbuf + 1) - 1;
- if (vx >= 0 && vx < 15 && vy >= 0 && vy < 15 &&
- ku[(int)vx][(int)vy] == BBLANK) {
- mv->x = vx;
- mv->y = vy;
- return 1;
- }
- } else {
- switch (ch) {
- case KEY_RIGHT:
- if(mv->x<BRDSIZ-1)
- mv->x++;
- break;
- case KEY_LEFT:
- if(mv->x>0)
- mv->x--;
- break;
- case KEY_UP:
- if(mv->y<BRDSIZ-1)
- mv->y++;
- break;
- case KEY_DOWN:
- if(mv->y>0)
- mv->y--;
- break;
- case ' ':
- case '\r':
- if (ku[(int)mv->x][(int)mv->y] == BBLANK)
- return 1;
+ if (info->mode == CHESS_MODE_VERSUS) {
+ ChessUser* const user1 = &info->user1;
+ /* ChessUser* const user2 = &info->user2; */
+
+ user1->lose--;
+ if (result == CHESS_RESULT_WIN) {
+ user1->win++;
+ currutmp->five_win++;
+ } else if (result == CHESS_RESULT_LOST) {
+ user1->lose++;
+ currutmp->five_lose++;
+ } else {
+ user1->tie++;
+ currutmp->five_tie++;
}
- }
- return 0;
-}
-#define PASS_REQUEST -2
-#define PASS_REJECT -3
-#define UNDO_REQUEST -1
-#define UNDO_REJECT -4
+ cuser.five_win = user1->win;
+ cuser.five_lose = user1->lose;
+ cuser.five_tie = user1->tie;
-int
-gomoku(int fd)
-{
- Horder_t mv;
- int me, he, ch;
- char hewantpass, iwantpass, passrejected;
- char hewantundo, iwantundo, undorejected;
- userinfo_t *my = currutmp;
- Horder_t pool[BRDSIZ*BRDSIZ];
- int scr_need_redraw;
- char ku[BRDSIZ][BRDSIZ];
- char genbuf[200];
- userec_t xuser;
-
- HO_init(ku, pool);
- me = !(my->turn) + 1;
- he = my->turn + 1;
- tick = now + MAX_TIME;
- lastcount = MAX_TIME;
- setutmpmode(M_FIVE);
- clear();
-
- prints(ANSI_COLOR(1;46) " 五子棋對戰 " ANSI_COLOR(45) "%30s VS %-30s" ANSI_RESET,
- cuser.userid, my->mateid);
- //show_file("etc/@five", 1, -1, ONLY_COLOR);
- move(1, 0);
- outs(
- " A B C D E F G H I J K L M N\n"
- " 15" ANSI_COLOR(30;43) "┌┬┬┬┬┬┬┬┬┬┬┬┬┬┐" ANSI_RESET "\n"
- " 14" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 13" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 12" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 11" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 10" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 9" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 8" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 7" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 6" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 5" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 4" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 3" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 2" ANSI_COLOR(30;43) "├┼┼┼┼┼┼┼┼┼┼┼┼┼┤" ANSI_RESET "\n"
- " 1" ANSI_COLOR(30;43) "└┴┴┴┴┴┴┴┴┴┴┴┴┴┘" ANSI_RESET "\n"
- );
-
- draw_photo = 0;
- setuserfile(genbuf, "photo_fivechess");
- if (dashf(genbuf))
- draw_photo = 1;
- else {
- sethomefile(genbuf, my->mateid, "photo_fivechess");
- if (dashf(genbuf))
- draw_photo = 1;
+ passwd_update(usernum, &cuser);
}
+}
- getuser(my->mateid, &xuser);
- if (draw_photo) {
- int line;
- FILE* fp;
- static const char * const blank_photo[6] = {
- "┌──────┐",
- "│ 空 │",
- "│ 白 │",
- "│ 照 │",
- "│ 片│",
- "└──────┘"
- };
- char country[5], level[11];
-
- setuserfile(genbuf, "photo_fivechess");
- fp = fopen(genbuf, "r");
-
- if (fp == NULL) {
- strcpy(country, "無");
- level[0] = 0;
- } else {
- int i, j;
- for (line = 1; line < 8; ++line)
- fgets(genbuf, 200, fp);
-
- fgets(genbuf, 200, fp);
- chomp(genbuf);
- strip_ansi(genbuf + 11, genbuf + 11,
- STRIP_ALL); /* country name may have color */
- for (i = 11, j = 0; genbuf[i] && j < 4; ++i)
- if (genbuf[i] != ' ') /* and spaces */
- country[j++] = genbuf[i];
- country[j] = 0; /* two chinese words */
-
- fgets(genbuf, 200, fp);
- chomp(genbuf);
- strlcpy(level, genbuf + 11, 11); /* five chinese words*/
- rewind(fp);
- }
+static void
+gomo_genlog(ChessInfo* info, FILE* fp, ChessGameResult result)
+{
+ const int nStep = info->history.used;
+ int i;
- for (line = 2; line < 8; ++line) {
- move(line, 37);
- if (fp != NULL) {
- if (fgets(genbuf, 200, fp)) {
- chomp(genbuf);
- prints("%s ", genbuf);
- } else
- outs(" ");
- } else
- outs(blank_photo[line - 2]);
-
- switch (line - 2) {
- case 0: prints("<代號> %s", cuser.userid); break;
- case 1: prints("<暱稱> %.16s", cuser.nickname); break;
- case 2: prints("<上站> %d", cuser.numlogins); break;
- case 3: prints("<文章> %d", cuser.numposts); break;
- case 4: prints("<職位> %-4s %s", country, level); break;
- case 5: prints("<來源> %.16s", cuser.lasthost); break;
- }
- }
- if (fp != NULL)
- fclose(fp);
-
- move(8, 43);
- prints(ANSI_COLOR(7) "%s" ANSI_RESET, me == BBLACK ? "黑棋" : "白棋");
- move(9, 43);
- outs(" V.S ");
- move(10, 68);
- prints(ANSI_COLOR(7) "%s" ANSI_RESET, me == BBLACK ? "白棋" : "黑棋");
-
- sethomefile(genbuf, my->mateid, "photo_fivechess");
- fp = fopen(genbuf, "r");
-
- if (fp == NULL) {
- strcpy(country, "無");
- level[0] = 0;
- } else {
- int i, j;
- for (line = 1; line < 8; ++line)
- fgets(genbuf, 200, fp);
-
- fgets(genbuf, 200, fp);
- chomp(genbuf);
- strip_ansi(genbuf + 11, genbuf + 11,
- STRIP_ALL); /* country name may have color */
- for (i = 11, j = 0; genbuf[i] && j < 4; ++i)
- if (genbuf[i] != ' ') /* and spaces */
- country[j++] = genbuf[i];
- country[j] = 0; /* two chinese words */
-
- fgets(genbuf, 200, fp);
- chomp(genbuf);
- strlcpy(level, genbuf + 11, 11); /* five chinese words*/
- rewind(fp);
- }
+ for (i = 1; i < 18; i++)
+ fprintf(fp, "%.*s\n", big_picture[i].len, big_picture[i].data);
- for (line = 11; line < 17; ++line) {
- move(line, 37);
- switch (line - 11) {
- case 0: prints("<代號> %-16.16s ", xuser.userid); break;
- case 1: prints("<暱稱> %-16.16s ", xuser.nickname); break;
- case 2: prints("<上站> %-16d ", xuser.numlogins); break;
- case 3: prints("<文章> %-16d ", xuser.numposts); break;
- case 4: prints("<職位> %-4s %-10s ", country, level); break;
- case 5: prints("<來源> %-16.16s ", xuser.lasthost); break;
- }
+ fprintf(fp, "<gomokulog>\nblack:%s\nwhite:%s\n",
+ info->myturn ? info->user1.userid : info->user2.userid,
+ info->myturn ? info->user2.userid : info->user1.userid);
- if (fp != NULL) {
- if (fgets(genbuf, 200, fp)) {
- chomp(genbuf);
- outs(genbuf);
- } else
- outs(" ");
- } else
- outs(blank_photo[line - 11]);
- }
- if (fp != NULL)
- fclose(fp);
-
- move(18, 4);
- prints("我是 %s", me == BBLACK ? "先手 ●,有禁手" : "後手 ○");
- } else {
- move(3, 40); outs("[q] 認輸離開");
- move(4, 40); outs("[u] 悔棋");
- move(5, 40); outs("[p] 要求和棋");
- move(9, 39); outs("[歡迎到five_chess討論五子棋喔]");
-
- move(11, 40);
- prints("我是 %s", me == BBLACK ? "先手 ●, 有禁手" : "後手 ○");
- move(16, 40);
- prints(ANSI_COLOR(1;33) "%s", cuser.userid);
- move(17, 40);
- prints(ANSI_COLOR(1;33) "%s", my->mateid);
-
- move(16, 60);
- prints(ANSI_COLOR(1;31) "%d" ANSI_COLOR(37) "勝 " ANSI_COLOR(34) "%d" ANSI_COLOR(37) "敗 " ANSI_COLOR(36) "%d" ANSI_COLOR(37) "和"
- ANSI_RESET, cuser.five_win, cuser.five_lose, cuser.five_tie);
-
- move(17, 60);
- prints(ANSI_COLOR(1;31) "%d" ANSI_COLOR(37) "勝 " ANSI_COLOR(34) "%d" ANSI_COLOR(37) "敗 " ANSI_COLOR(36) "%d" ANSI_COLOR(37) ""
- "和" ANSI_RESET, xuser.five_win, xuser.five_lose, xuser.five_tie);
-
- move(18, 40);
- prints("%s時間還剩%d:%02d\n", my->turn ? "你的" : "對方",
- MAX_TIME / 60, MAX_TIME % 60);
+ for (i = 0; i < nStep; ++i) {
+ const gomo_step_t* const step =
+ (const gomo_step_t*) ChessHistoryRetrieve(info, i);
+ fprintf(fp, "[%2d]%s ==> %c%-5d", i + 1, bw_chess[i % 2],
+ 'A' + step->loc.c, step->loc.r + 1);
+ if (i % 2)
+ fputc('\n', fp);
}
- cuser.five_lose++;
- /* 一進來先加一場敗場, 贏了後再扣回去, 避免快輸了惡意斷線 */
- passwd_update(usernum, &cuser);
+ if (i % 2)
+ fputc('\n', fp);
+ fputs("</gomokulog>\n", fp);
+}
- add_io(fd, 0);
+void
+gomoku(int s, ChessGameMode mode)
+{
+ ChessInfo* info = NewChessInfo(&gomo_actions, &gomo_constants, s, mode);
+ board_t board;
+ int tag;
+
+ gomo_init_board(board);
+ tag = 0;
+
+ info->board = board;
+ info->tag = &tag;
+
+ if (info->mode == CHESS_MODE_VERSUS) {
+ /* Assume that info->user1 is me. */
+ info->user1.lose++;
+ passwd_query(usernum, &cuser);
+ gomoku_usr_put(&cuser, &info->user1);
+ passwd_update(usernum, &cuser);
+ }
- hewantpass = iwantpass = passrejected = 0;
- hewantundo = iwantundo = undorejected = 0;
- mv.x = mv.y = 7;
- scr_need_redraw = 1;
- for (;;) {
- if (scr_need_redraw){
- if (draw_photo)
- move(19, 4);
- else
- move(13, 40);
- outs(my->turn ? "輪到自己下了!" : "等待對方下子..");
- redoln();
+ if (mode == CHESS_MODE_WATCH)
+ setutmpmode(CHESSWATCHING);
+ else
+ setutmpmode(M_FIVE);
+ currutmp->sig = SIG_GOMO;
- outmsg(ANSI_COLOR(1;33;42) " 下五子棋 " ANSI_COLOR(;31;47) " (←↑↓→)" ANSI_COLOR(30) "移動 " ANSI_COLOR(31) "(空白鍵/ENTER)" ANSI_COLOR(30) "下子 " ANSI_COLOR(31) "(q)" ANSI_COLOR(30) "投降 " ANSI_COLOR(31) "(p)" ANSI_COLOR(30) "和棋 " ANSI_COLOR(31) "(u)" ANSI_COLOR(30) "悔棋 " ANSI_RESET);
- scr_need_redraw = 0;
- }
- if (lastcount != tick - now) {
- lastcount = tick - now;
- move(18, 40);
- prints("%s時間還剩%d:%02d\n", my->turn ? "你的" : "對方",
- lastcount / 60, lastcount % 60);
- if (lastcount <= 0 && my->turn) {
- move(19, 40);
- outs("時間已到, 你輸了");
- my->five_lose++;
- send(fd, '\0', 1, 0);
- break;
- }
- if (lastcount <= -5 && !my->turn) {
- move(19, 40);
- outs("對手太久沒下, 你贏了!");
- cuser.five_lose--;
- cuser.five_win++;
- my->five_win++;
- passwd_update(usernum, &cuser);
- mv.x = mv.y = -2;
- send(fd, &mv, sizeof(Horder_t), 0);
- mv = *(v - 1);
- break;
- }
- }
- move(draw_photo ? 20 : 14, 40);
- clrtoeol();
- if (hewantpass) {
- outs(ANSI_COLOR(1;32) "和棋要求!" ANSI_RESET);
- bell();
- } else if (iwantpass)
- outs(ANSI_COLOR(1;32) "提出和棋要求!" ANSI_RESET);
- else if (passrejected) {
- outs(ANSI_COLOR(1;32) "要求被拒!" ANSI_RESET);
- passrejected = 0;
- } else if (hewantundo) {
- outs(ANSI_COLOR(1;33) "悔棋要求! (按 u 接受, 任意鍵拒絕)" ANSI_RESET);
- bell();
- } else if (iwantundo)
- outs(ANSI_COLOR(1;33) "提出悔棋要求!" ANSI_RESET);
- else if (undorejected) {
- outs(ANSI_COLOR(1;33) "要求被拒!" ANSI_RESET);
- undorejected = 0;
- }
- BGOTOCUR(mv.x, mv.y);
- ch = igetch();
- if ((iwantpass || hewantpass) && ch != 'p' && ch != I_OTHERDATA) {
- mv.x = mv.y = PASS_REJECT;
- send(fd , &mv, sizeof(Horder_t), 0);
- mv = *(v - 1);
- iwantpass = 0;
- hewantpass = 0;
- continue;
- }
- if ((iwantundo || hewantundo) && ch != 'u' && ch != I_OTHERDATA) {
- mv.x = mv.y = UNDO_REJECT;
- send(fd , &mv, sizeof(Horder_t), 0);
- mv = *(v - 1);
- iwantundo = 0;
- hewantundo = 0;
- continue;
- }
- if (ch == 'q') {
- if (countgomo(pool) < 10) {
- cuser.five_lose--;
- passwd_update(usernum, &cuser);
- }
- send(fd, "", 1, 0);
- break;
- } else if (ch == 'u') {
- if (my->turn) {
- if (hewantundo) {
- mv.x = mv.y = UNDO_REQUEST;
- ch = send(fd, &mv, sizeof(Horder_t), 0);
- tick = hislasttick;
- HO_undo(ku, &mv);
- my->turn = 0;
- hewantundo = 0;
- scr_need_redraw = 1;
- }
- continue;
- }
- else if (v > pool) {
- mv.x = mv.y = UNDO_REQUEST;
- ch = send(fd, &mv, sizeof(Horder_t), 0);
- if (ch == sizeof(Horder_t)) {
- iwantundo = 1;
- continue;
- } else
- break;
- }
- }
- if (ch == 'p') {
- if (my->turn) {
- if (iwantpass == 0) {
- iwantpass = 1;
- mv.x = mv.y = PASS_REQUEST;
- send(fd, &mv, sizeof(Horder_t), 0);
- mv = *(v - 1);
- }
- continue;
- } else if (hewantpass) {
- cuser.five_lose--;
- cuser.five_tie++;
- my->five_tie++;
- passwd_update(usernum, &cuser);
- mv.x = mv.y = PASS_REQUEST;
- send(fd, &mv, sizeof(Horder_t), 0);
- mv = *(v - 1);
- break;
- }
- }
- if (ch == I_OTHERDATA) {
- ch = recv(fd, &mv, sizeof(Horder_t), 0);
- if (ch != sizeof(Horder_t)) {
- lastcount = tick - now;
- if (lastcount >= 0) {
- cuser.five_lose--;
- if (countgomo(pool) >= 10) {
- cuser.five_win++;
- my->five_win++;
- }
- passwd_update(usernum, &cuser);
- outmsg("對方認輸了!!");
- break;
- } else {
- outmsg("你超過時間未下子, 輸了!");
- my->five_lose++;
- break;
- }
- } else if (mv.x == PASS_REQUEST && mv.y == PASS_REQUEST) {
- if (iwantpass == 1) {
- cuser.five_lose--;
- cuser.five_tie++;
- my->five_tie++;
- passwd_update(usernum, &cuser);
- break;
- } else {
- hewantpass = 1;
- mv = *(v - 1);
- continue;
- }
- } else if (mv.x == PASS_REJECT && mv.y == PASS_REJECT) {
- if (iwantpass)
- passrejected = 1;
- iwantpass = 0;
- hewantpass = 0;
- mv = *(v - 1);
- continue;
- } else if (mv.x == UNDO_REJECT && mv.y == UNDO_REJECT) {
- if (iwantundo)
- undorejected = 1;
- iwantundo = 0;
- hewantundo = 0;
- mv = *(v - 1);
- continue;
- } else if (mv.x == UNDO_REQUEST && mv.y == UNDO_REQUEST) {
- if (!my->turn) {
- if (iwantundo) {
- HO_undo(ku, &mv);
- tick = mylasttick;
- my->turn = 1;
- iwantundo = hewantundo = 0;
- scr_need_redraw = 1;
- }
- /* else shouldn't happend */
- } else {
- hewantundo = 1;
- mv = *(v - 1);
- }
- continue;
- }
- if (!my->turn) {
- int win;
- win = chkmv(ku, &mv, he, he == BBLACK);
- HO_add(&mv);
- hislasttick = tick;
- tick = now + MAX_TIME;
- ku[(int)mv.x][(int)mv.y] = he;
- bell();
- BGOTO(mv.x, mv.y);
- outs(bw_chess[he - 1]);
- redoln();
-
- if (win) {
- outmsg(win == 1 ? "對方贏了!" : "對方禁手");
- if (win != 1) {
- cuser.five_lose--;
- cuser.five_win++;
- my->five_win++;
- passwd_update(usernum, &cuser);
- } else
- my->five_lose++;
- break;
- }
- my->turn = 1;
- }
- scr_need_redraw = 1;
- continue;
- }
- if (my->turn) {
- if (gomo_key(ku, fd, ch, &mv))
- my->turn = 0;
- else
- continue;
-
- if (!my->turn) {
- int win;
- HO_add(&mv);
- BGOTO(mv.x, mv.y);
- outs(bw_chess[me - 1]);
- redoln();
- win = chkmv(ku, &mv, me, me == BBLACK);
- ku[(int)mv.x][(int)mv.y] = me;
- mylasttick = tick;
- tick = now + MAX_TIME; /* 倒數 */
- lastcount = MAX_TIME;
- if (send(fd, &mv, sizeof(Horder_t), 0) != sizeof(Horder_t))
- break;
- if (win) {
- outmsg(win == 1 ? "我贏囉~~" : "禁手輸了");
- if (win == 1) {
- cuser.five_lose--;
- cuser.five_win++;
- my->five_win++;
- passwd_update(usernum, &cuser);
- } else
- my->five_lose++;
- break;
- }
- move(draw_photo ? 19 : 15, 40);
- clrtoeol();
- }
- scr_need_redraw = 1;
- }
- }
- add_io(0, 0);
- close(fd);
+ ChessPlay(info);
- igetch();
- if (v > pool) {
- char ans[4];
+ DeleteChessInfo(info);
+}
- getdata(19, 0, "要保留本局成棋譜嗎?(y/N)", ans, sizeof(ans), LCECHO);
- if (*ans == 'y')
- HO_log_user(pool, my->mateid);
+int
+gomoku_main(void)
+{
+ return ChessStartGame('f', SIG_GOMO, "五子棋");
+}
-#ifdef GLOBAL_FIVECHESS_LOG
- if (me == BBLACK)
- HO_log_board(pool, my->mateid);
-#endif
- }
+int
+gomoku_personal(void)
+{
+ gomoku(0, CHESS_MODE_PERSONAL);
return 0;
}
+
+int
+gomoku_watch(void)
+{
+ return ChessWatchGame(&gomoku, M_FIVE, "五子棋");
+}
diff --git a/mbbsd/menu.c b/mbbsd/menu.c
index 770cf71a..a613de8d 100644
--- a/mbbsd/menu.c
+++ b/mbbsd/menu.c
@@ -583,10 +583,13 @@ static const commands_t playlist[] = {
};
static const commands_t chesslist[] = {
- {chc_main, PERM_LOGINOK, "11ChessFight 【" ANSI_COLOR(1;33) " 象棋邀局 " ANSI_RESET "】"},
- {chc_personal, PERM_LOGINOK, "22SelfPlay 【" ANSI_COLOR(1;34) " 象棋打譜 " ANSI_RESET "】"},
- {chc_watch, PERM_LOGINOK, "33ChessWatch 【" ANSI_COLOR(1;35) " 象棋觀棋 " ANSI_RESET "】"},
- {GoBot, PERM_LOGINOK, "44GoBot 【" ANSI_COLOR(1;36) " 圍棋打譜 " ANSI_RESET "】"},
+ {chc_main, PERM_LOGINOK, "11CChessFight 【" ANSI_COLOR(1;33) " 象棋邀局 " ANSI_RESET "】"},
+ {chc_personal, PERM_LOGINOK, "22CChessSelf 【" ANSI_COLOR(1;34) " 象棋打譜 " ANSI_RESET "】"},
+ {chc_watch, PERM_LOGINOK, "33CChessWatch 【" ANSI_COLOR(1;35) " 象棋觀棋 " ANSI_RESET "】"},
+ {gomoku_main, PERM_LOGINOK, "44GomokuFight 【" ANSI_COLOR(1;33) "五子棋邀局" ANSI_RESET "】"},
+ {gomoku_personal, PERM_LOGINOK, "55GomokuSelf 【" ANSI_COLOR(1;34) "五子棋打譜" ANSI_RESET "】"},
+ {gomoku_watch, PERM_LOGINOK, "66GomokuWatch 【" ANSI_COLOR(1;35) "五子棋觀棋" ANSI_RESET "】"},
+ {GoBot, PERM_LOGINOK, "77GoBot 【" ANSI_COLOR(1;36) " 圍棋打譜 " ANSI_RESET "】"},
{NULL, 0, NULL}
};
diff --git a/mbbsd/talk.c b/mbbsd/talk.c
index bcf16cf0..920035e8 100644
--- a/mbbsd/talk.c
+++ b/mbbsd/talk.c
@@ -1429,7 +1429,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact)
ch == DARK || ch == GO || ch == CHESSWATCHING ||
(!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3)) ||
uin->lockmode == M_FIVE || uin->lockmode == CHC) {
- if (ch == CHC) {
+ if (ch == CHC || ch == M_FIVE || ch == CHESSWATCHING) {
kill(uin->pid, SIGUSR1);
sock = make_connection_to_somebody(uin, 20);
if (sock < 0)
@@ -1446,7 +1446,16 @@ my_talk(userinfo_t * uin, int fri_stat, char defact)
return;
}
strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
- chc(msgsock, CHESS_MODE_WATCH);
+
+ switch (uin->sig) {
+ case SIG_CHC:
+ chc(msgsock, CHESS_MODE_WATCH);
+ break;
+
+ case SIG_GOMO:
+ gomoku(msgsock, CHESS_MODE_WATCH);
+ break;
+ }
}
}
else
@@ -1547,7 +1556,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact)
close(sock);
currutmp->sockactive = NA;
- if (uin->sig == SIG_CHC)
+ if (uin->sig == SIG_CHC || uin->sig == SIG_GOMO)
ChessEstablishRequest(msgsock);
add_io(msgsock, 0);
@@ -1576,7 +1585,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact)
chickenpk(msgsock);
break;
case SIG_GOMO:
- gomoku(msgsock);
+ gomoku(msgsock, CHESS_MODE_VERSUS);
break;
case SIG_CHC:
chc(msgsock, CHESS_MODE_VERSUS);
@@ -2971,7 +2980,7 @@ talkreply(void)
currutmp->destuid = uip->uid;
currstat = REPLY; /* 避免出現動畫 */
- is_chess = (sig == SIG_CHC);
+ is_chess = (sig == SIG_CHC || sig == SIG_GOMO);
a = reply_connection_request(uip);
if (a < 0) {
@@ -3051,7 +3060,7 @@ talkreply(void)
chickenpk(a);
break;
case SIG_GOMO:
- gomoku(a);
+ gomoku(a, CHESS_MODE_VERSUS);
break;
case SIG_CHC:
chc(a, CHESS_MODE_VERSUS);
diff --git a/mbbsd/var.c b/mbbsd/var.c
index b6e50000..83ea9924 100644
--- a/mbbsd/var.c
+++ b/mbbsd/var.c
@@ -267,7 +267,7 @@ char * const ModeTypeTable[MAX_MODES] = {
"Ptt查榜系統", /* JCEE */
"重編文章", /* REEDIT */
"部落格", /* BLOGGING */
- "看象棋", /* CHESSWATCHING */
+ "看棋", /* CHESSWATCHING */
"下圍棋", /* GO */
"", /* for future usage */
"",
@@ -408,7 +408,7 @@ char roll = 0;
char msg_occupied = 0;
/* gomo.c */
-const char * const bw_chess[] = {"●", "○"};
+const char * const bw_chess[] = {"○", "●"};
unsigned char *pat, *adv;
unsigned char * const pat_gomoku /* [1954] */ =
/* 0 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"