summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvictor <victor@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2003-08-30 11:51:59 +0800
committervictor <victor@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2003-08-30 11:51:59 +0800
commitd86d4a7f970c61192ff9aa86a52bc57a5122de84 (patch)
treecb7c558670fd074cd79becfdb654357858b22647
parentd74a38bf714ecb672600885e40aca8844681230f (diff)
downloadpttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar.gz
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar.bz2
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar.lz
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar.xz
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.tar.zst
pttbbs-d86d4a7f970c61192ff9aa86a52bc57a5122de84.zip
chess-unstable
git-svn-id: http://opensvn.csie.org/pttbbs/branches/victor.bank@1141 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/include/bbs.h1
-rw-r--r--pttbbs/include/chc.h34
-rw-r--r--pttbbs/include/modes.h6
-rw-r--r--pttbbs/include/proto.h16
-rw-r--r--pttbbs/include/pttstruct.h16
-rw-r--r--pttbbs/mbbsd/Makefile3
-rw-r--r--pttbbs/mbbsd/chc_draw.c56
-rw-r--r--pttbbs/mbbsd/chc_log.c73
-rw-r--r--pttbbs/mbbsd/chc_net.c11
-rw-r--r--pttbbs/mbbsd/chc_play.c316
-rw-r--r--pttbbs/mbbsd/mbbsd.c2
-rw-r--r--pttbbs/mbbsd/menu.c13
-rw-r--r--pttbbs/mbbsd/talk.c65
-rw-r--r--pttbbs/mbbsd/var.c4
-rw-r--r--pttbbs/sample/etc/Makefile2
-rw-r--r--pttbbs/sample/etc/chess/1.poem10
-rw-r--r--pttbbs/sample/etc/chess/10.poem10
-rw-r--r--pttbbs/sample/etc/chess/11.poem6
-rw-r--r--pttbbs/sample/etc/chess/12.poem6
-rw-r--r--pttbbs/sample/etc/chess/13.poem6
-rw-r--r--pttbbs/sample/etc/chess/14.poem10
-rw-r--r--pttbbs/sample/etc/chess/15.poem2
-rw-r--r--pttbbs/sample/etc/chess/16.poem2
-rw-r--r--pttbbs/sample/etc/chess/2.poem10
-rw-r--r--pttbbs/sample/etc/chess/3.poem6
-rw-r--r--pttbbs/sample/etc/chess/4.poem10
-rw-r--r--pttbbs/sample/etc/chess/5.poem8
-rw-r--r--pttbbs/sample/etc/chess/6.poem6
-rw-r--r--pttbbs/sample/etc/chess/7.poem10
-rw-r--r--pttbbs/sample/etc/chess/8.poem10
-rw-r--r--pttbbs/sample/etc/chess/9.poem6
31 files changed, 547 insertions, 189 deletions
diff --git a/pttbbs/include/bbs.h b/pttbbs/include/bbs.h
index 71a3332f..666d30c7 100644
--- a/pttbbs/include/bbs.h
+++ b/pttbbs/include/bbs.h
@@ -60,6 +60,7 @@
#include "common.h"
#include "perm.h"
#include "modes.h"
+#include "chc.h"
#include "proto.h"
#include "gomo.h"
diff --git a/pttbbs/include/chc.h b/pttbbs/include/chc.h
new file mode 100644
index 00000000..66f1aacb
--- /dev/null
+++ b/pttbbs/include/chc.h
@@ -0,0 +1,34 @@
+/* 象棋 */
+#define SIDE_ROW 7
+#define TURN_ROW 8
+#define STEP_ROW 9
+#define TIME_ROW 10
+#define WARN_ROW 12
+#define MYWIN_ROW 17
+#define HISWIN_ROW 18
+
+#define CHC_VERSUS 1 /* 雙人 */
+#define CHC_WATCH 2 /* 觀棋 */
+#define CHC_PERSONAL 4 /* 打譜 */
+#define CHC_WATCH_PERSONAL 8 /* 觀人打譜 */
+
+#define BLACK_COLOR "\033[1;36m"
+#define RED_COLOR "\033[1;31m"
+#define BLACK_REVERSE "\033[1;37;46m"
+#define RED_REVERSE "\033[1;37;41m"
+#define TURN_COLOR "\033[1;33m"
+
+typedef struct chcusr_t{
+ char userid[IDLEN + 1];
+ int win;
+ int lose;
+ int tie;
+} chcusr_t;
+
+#define CHC_ACT_BOARD 0x1 /* set if transfered board to this sock */
+
+typedef struct chc_act_list{
+ int sock;
+ struct chc_act_list *next;
+} chc_act_list;
+
diff --git a/pttbbs/include/modes.h b/pttbbs/include/modes.h
index a70e7047..2ddf2b52 100644
--- a/pttbbs/include/modes.h
+++ b/pttbbs/include/modes.h
@@ -96,11 +96,7 @@
#define JCEE 78
#define REEDIT 79
#define BLOGGING 80
-
-/* 象棋 */
-#define CHC_VERSUS 0 /* 雙人 */
-#define CHC_WATCH 1 /* 觀棋 */
-#define CHC_PERSONAL 2 /* 打譜 */
+#define CHESS_MENU 81
/* menu.c 中的模式 */
#define QUIT 0x666 /* Return value to abort recursive functions */
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h
index d3b6058d..e11528a2 100644
--- a/pttbbs/include/proto.h
+++ b/pttbbs/include/proto.h
@@ -165,10 +165,18 @@ int card_99();
int t_chat();
/* chc_draw */
+char *getstep(board_t board, rc_t *from, rc_t *to);
void chc_drawline(board_t board, chcusr_t *user1, chcusr_t *user2, int line);
void chc_movecur(int r, int c);
void chc_redraw(chcusr_t *user1, chcusr_t *user2, board_t board);
+/* chc_log */
+int chc_log_open(chcusr_t *user1, chcusr_t *user2, char *file);
+int chc_log(char *step);
+void chc_log_close(void);
+int chc_log_step(board_t board, rc_t *from, rc_t *to);
+int chc_log_poem(void);
+
/* chc_net */
//void chc_sendmove(int s);
//int chc_recvmove(int s);
@@ -177,6 +185,9 @@ void chc_broadcast_send(chc_act_list *act_list, board_t board);
/* chc_play */
void chc(int s, int mode);
+int chc_main(void);
+int chc_personal(void);
+int chc_watch(void);
/* chc_rule */
void chc_movechess(board_t board);
@@ -260,6 +271,7 @@ int num_in_buf();
int ochar(int c);
int rget(int x,char *prompt);
char getans(char *prompt);
+int timeout_read(int fd, void *pointer, int size, int sec);
/* kaede */
int Rename(char* src, char* dst);
@@ -308,6 +320,8 @@ void show_last_call_in(int save);
int dosearchuser(char *userid);
void u_exit(char *mode);
void talk_request(int sig);
+int reply_connection_request(userinfo_t *uip);
+void my_talk(userinfo_t * uin, int fri_stat, char defact);
/* menu */
void showtitle(char *title, char *mid);
@@ -507,7 +521,7 @@ int login_friend_online();
int isvisible_uid(int tuid);
int friend_stat(userinfo_t *me, userinfo_t * ui);
int call_in(userinfo_t *uentp, int fri_stat);
-void chc_watch_request(int signo);
+int make_connection_to_somebody(userinfo_t *uin, int timeout);
/* tmpjack */
int reg_barbq();
diff --git a/pttbbs/include/pttstruct.h b/pttbbs/include/pttstruct.h
index a69ba30b..d598eab9 100644
--- a/pttbbs/include/pttstruct.h
+++ b/pttbbs/include/pttstruct.h
@@ -425,20 +425,4 @@ typedef struct
int recno;
} TagItem;
-/* 象棋 */
-typedef struct chcusr_t{
- char userid[IDLEN + 1];
- int uid;
- int win;
- int lose;
- int tie;
-} chcusr_t;
-
-#define CHC_ACT_BOARD 0x1 /* set if transfered board to this sock */
-
-typedef struct chc_act_list{
- int sock;
- char flag;
- struct chc_act_list *next;
-} chc_act_list;
#endif
diff --git a/pttbbs/mbbsd/Makefile b/pttbbs/mbbsd/Makefile
index b0c09c4a..1ac765f7 100644
--- a/pttbbs/mbbsd/Makefile
+++ b/pttbbs/mbbsd/Makefile
@@ -9,7 +9,8 @@ LDFLAGS+= -L/usr/local/lib/mysql -lmysqlclient
PROG= mbbsd
OBJS= admin.o announce.o args.o bbs.o board.o cache.o cal.o card.o\
- chat.o chc_draw.o chc_net.o chc_play.o chc_rule.o chicken.o dark.o\
+ chat.o chicken.o dark.o\
+ chc_draw.o chc_net.o chc_play.o chc_rule.o chc_log.o \
edit.o friend.o gamble.o gomo.o gomo1.o guess.o indict.o io.o\
kaede.o lovepaper.o mail.o mbbsd.o menu.o more.o name.o osdep.o\
othello.o page.o read.o record.o register.o screen.o stuff.o\
diff --git a/pttbbs/mbbsd/chc_draw.c b/pttbbs/mbbsd/chc_draw.c
index 2cca2f19..2c687c77 100644
--- a/pttbbs/mbbsd/chc_draw.c
+++ b/pttbbs/mbbsd/chc_draw.c
@@ -1,14 +1,6 @@
/* $Id$ */
#include "bbs.h"
-#define SIDE_ROW 10
-#define TURN_ROW 11
-#define STEP_ROW 12
-#define TIME_ROW 13
-#define WARN_ROW 15
-#define MYWIN_ROW 17
-#define HISWIN_ROW 18
-
static char *turn_str[2] = {"黑的", "紅的"};
static char *num_str[10] = {
@@ -57,39 +49,43 @@ chc_movecur(int r, int c)
move(r * 2 + 3, c * 4 + 4);
}
-#define BLACK_COLOR "\033[1;36m"
-#define RED_COLOR "\033[1;31m"
-#define BLACK_REVERSE "\033[1;37;46m"
-#define RED_REVERSE "\033[1;37;41m"
-#define TURN_COLOR "\033[1;33m"
-
-static void
-showstep(board_t board)
+char *
+getstep(board_t board, rc_t *from, rc_t *to)
{
- int turn, fc, tc, eatten;
+ int turn, fc, tc;
char *dir;
+ static char buf[80];
- turn = CHE_O(board[chc_from.r][chc_from.c]);
- fc = (turn == (chc_my ^ 1) ? chc_from.c + 1 : 9 - chc_from.c);
- tc = (turn == (chc_my ^ 1) ? chc_to.c + 1 : 9 - chc_to.c);
- if (chc_from.r == chc_to.r)
+ turn = CHE_O(board[from->r][from->c]);
+ fc = (turn == (chc_my ^ 1) ? from->c + 1 : 9 - from->c);
+ tc = (turn == (chc_my ^ 1) ? to->c + 1 : 9 - to->c);
+ if (from->r == to->r)
dir = "平";
else {
- if (chc_from.c == chc_to.c)
- tc = chc_from.r - chc_to.r;
+ if (from->c == to->c)
+ tc = from->r - to->r;
if (tc < 0)
tc = -tc;
- if ((turn == (chc_my ^ 1) && chc_to.r > chc_from.r) ||
- (turn == chc_my && chc_to.r < chc_from.r))
+ if ((turn == (chc_my ^ 1) && to->r > from->r) ||
+ (turn == chc_my && to->r < from->r))
dir = "進";
else
dir = "退";
}
- prints("%s%s%s%s%s",
- turn == 0 ? BLACK_COLOR : RED_COLOR,
- chess_str[turn][CHE_P(board[chc_from.r][chc_from.c])],
+ sprintf(buf, "%s%s%s%s",
+ chess_str[turn][CHE_P(board[from->r][from->c])],
num_str[fc], dir, num_str[tc]);
+ return buf;
+}
+
+static void
+showstep(board_t board)
+{
+ int eatten;
+
+ prints("%s%s", CHE_O(board[chc_from.r][chc_from.c]) == 0 ? BLACK_COLOR : RED_COLOR, getstep(board, &chc_from, &chc_to));
+
eatten = board[chc_to.r][chc_to.c];
if (eatten)
prints(": %s%s",
@@ -106,8 +102,8 @@ chc_drawline(board_t board, chcusr_t *user1, chcusr_t *user2, int line)
move(line, 0);
clrtoeol();
if (line == 0) {
- prints("\033[1;46m 象棋對戰 \033[45m%30s VS %-30s\033[m",
- user1->userid, user2->userid);
+ prints("\033[1;46m 象棋對戰 \033[45m%30s VS %-20s%10s\033[m",
+ user1->userid, user2->userid, chc_mode & CHC_WATCH ? "[觀棋模式]" : "");
} else if (line >= 3 && line <= 21) {
outs(" ");
for (i = 0; i < 9; i++) {
diff --git a/pttbbs/mbbsd/chc_log.c b/pttbbs/mbbsd/chc_log.c
new file mode 100644
index 00000000..cb464322
--- /dev/null
+++ b/pttbbs/mbbsd/chc_log.c
@@ -0,0 +1,73 @@
+#include "bbs.h"
+
+extern char * chc_getstep(board_t board);
+
+static FILE *fp = NULL;
+
+int
+chc_log_open(chcusr_t *user1, chcusr_t *user2, char *file)
+{
+ char buf[128];
+ if ((fp = fopen(file, "w")) == NULL)
+ return -1;
+ sprintf(buf, "%s V.S. %s\n", user1->userid, user2->userid);
+ fputs(buf, fp);
+ return 0;
+}
+
+void
+chc_log_close(void)
+{
+ if (fp)
+ fclose(fp);
+}
+
+int
+chc_log(char *desc)
+{
+ if (fp)
+ return fputs(desc, fp);
+ return NULL;
+}
+
+int
+chc_log_step(board_t board, rc_t *from, rc_t *to)
+{
+ char buf[80];
+ sprintf(buf, " %s%s\033[m\n", CHE_O(board[from->r][from->c]) == 0 ? BLACK_COLOR : RED_COLOR, getstep(board, from, to));
+ return chc_log(buf);
+}
+
+static int
+chc_filter(struct dirent *dir)
+{
+ if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0 )
+ return 0;
+ return strnstr(dir->d_name, ".poem", sizeof(dir->d_name)) != NULL;
+}
+
+int
+chc_log_poem(void)
+{
+ struct dirent **namelist;
+ int n;
+
+ n = scandir(BBSHOME"/etc/chess", &namelist, chc_filter, alphasort);
+ if (n < 0)
+ perror("scandir");
+ else {
+ char buf[80];
+ FILE *fp;
+ sprintf(buf, BBSHOME"/etc/chess/%s", namelist[rand() % n]->d_name);
+ if ((fp = fopen(buf, "r")) == NULL)
+ return -1;
+
+ while(fgets(buf, sizeof(buf), fp) != NULL)
+ chc_log(buf);
+ while(n--)
+ free(namelist[n]);
+ free(namelist);
+ fclose(fp);
+ }
+ return 0;
+}
diff --git a/pttbbs/mbbsd/chc_net.c b/pttbbs/mbbsd/chc_net.c
index d82066e7..4a780336 100644
--- a/pttbbs/mbbsd/chc_net.c
+++ b/pttbbs/mbbsd/chc_net.c
@@ -27,19 +27,8 @@ chc_sendmove(int s)
}
static void
-chc_send_status(int sock, board_t board){
- write(sock, &board, sizeof(board));
- /////// nessesery? correct?
- write(sock, &chc_turn, sizeof(chc_turn));
-}
-
-static void
chc_broadcast(chc_act_list *p, board_t board){
while(p){
- if (!(p->flag & CHC_ACT_BOARD)){
- chc_send_status(p->sock, board);
- p->flag |= CHC_ACT_BOARD;
- }
if (chc_sendmove(p->sock) < 0) {
if (p->next->next == NULL)
p = NULL;
diff --git a/pttbbs/mbbsd/chc_play.c b/pttbbs/mbbsd/chc_play.c
index 7efbaaca..b3053ea3 100644
--- a/pttbbs/mbbsd/chc_play.c
+++ b/pttbbs/mbbsd/chc_play.c
@@ -2,16 +2,12 @@
#include "bbs.h"
typedef int (*play_func_t) (int, chcusr_t *, chcusr_t *, board_t, board_t);
-static int chc_ipass = 0, chc_hepass = 0;
+static char chc_ipass = 0, chc_hepass = 0;
-#define CHC_TIMEOUT 300
-#define SIDE_ROW 10
-#define TURN_ROW 11
-#define STEP_ROW 12
-#define TIME_ROW 13
-#define WARN_ROW 15
-#define MYWIN_ROW 17
-#define HISWIN_ROW 18
+extern userinfo_t *uip;
+
+#define CHC_TIMEOUT 300
+#define CHC_LOG "chc_log"
static void
chcusr_put(userec_t *userec, chcusr_t *user)
@@ -72,14 +68,27 @@ hisplay(int s, chcusr_t *user1, chcusr_t *user2, board_t board, board_t tmpbrd)
strlcpy(chc_warnmsg, "\033[1;33m要求和局!\033[m", sizeof(chc_warnmsg));
chc_drawline(board, user1, user2, WARN_ROW);
} else {
- chc_from.r = 9 - chc_from.r, chc_from.c = 8 - chc_from.c;
- chc_to.r = 9 - chc_to.r, chc_to.c = 8 - chc_to.c;
+ /* 座標變換
+ * (CHC_WATCH_PERSONAL 設定時
+ * 表觀棋者看的棋局為單人打譜的棋局)
+ * 棋盤需倒置的清況才要轉換
+ */
+ if ( ((chc_mode & CHC_WATCH) && (chc_mode & CHC_WATCH_PERSONAL)) || /* 1.如果在觀棋 且棋局是別人在打譜 且輪到你 或*/
+ (chc_mode & CHC_PERSONAL) || /* 2.自己在打譜 */
+ ((chc_mode & CHC_WATCH) && !chc_turn)
+ )
+ ; // do nothing
+ else {
+ chc_from.r = 9 - chc_from.r, chc_from.c = 8 - chc_from.c;
+ chc_to.r = 9 - chc_to.r, chc_to.c = 8 - chc_to.c;
+ }
chc_cursor = chc_to;
if (CHE_P(board[chc_to.r][chc_to.c]) == 1)
endgame = 2;
endturn = 1;
chc_hepass = 0;
chc_drawline(board, user1, user2, STEP_ROW);
+ chc_log_step(board, &chc_from, &chc_to);
chc_movechess(board);
chc_drawline(board, user1, user2, LTR(chc_from.r));
chc_drawline(board, user1, user2, LTR(chc_to.r));
@@ -170,6 +179,7 @@ myplay(int s, chcusr_t *user1, chcusr_t *user2, board_t board, board_t tmpbrd)
}
if (endgame || !chc_iskfk(tmpbrd)) {
chc_drawline(board, user1, user2, STEP_ROW);
+ chc_log_step(board, &chc_from, &chc_to);
chc_movechess(board);
chc_broadcast_send(act_list, board);
chc_selected = 0;
@@ -198,15 +208,12 @@ static void
mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t play_func[2])
{
int endgame;
+ char buf[80];
board_t tmpbrd;
- play_func[chc_my] = myplay;
- if(s != 0)
- play_func[chc_my ^ 1] = hisplay;
- else /* 跟自己下棋 */
- play_func[chc_my ^ 1] = myplay;
-
- for (chc_turn = 1, endgame = 0; !endgame; chc_turn ^= 1) {
+ if (!(chc_mode & CHC_WATCH))
+ chc_turn = 1;
+ for (endgame = 0; !endgame; chc_turn ^= 1) {
chc_firststep = 0;
chc_drawline(board, user1, user2, TURN_ROW);
if (chc_ischeck(board, chc_turn)) {
@@ -218,7 +225,7 @@ mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t pla
endgame = play_func[chc_turn] (s, user1, user2, board, tmpbrd);
}
- if (s != 0) {
+ if (chc_mode & CHC_VERSUS) {
if (endgame == 1) {
strlcpy(chc_warnmsg, "對方認輸了!", sizeof(chc_warnmsg));
user1->win++;
@@ -232,113 +239,258 @@ mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t pla
user1->tie++;
currutmp->chc_tie++;
}
+ user1->lose--;
+ chcusr_put(&cuser, user1);
+ passwd_update(usernum, &cuser);
+ }
+ else if (chc_mode & CHC_WATCH) {
+ strlcpy(chc_warnmsg, "結束觀棋", sizeof(chc_warnmsg));
}
else {
strlcpy(chc_warnmsg, "結束打譜", sizeof(chc_warnmsg));
}
- user1->lose--;
- // if not watching
- chcusr_put(&cuser, user1);
- passwd_update(usernum, &cuser);
+ chc_log("=> ");
+ if (endgame == 3)
+ chc_log("和局");
+ else{
+ sprintf(buf, "%s勝\n", chc_my && endgame == 1 ? "紅" : "黑");
+ chc_log(buf);
+ }
+
chc_drawline(board, user1, user2, WARN_ROW);
bell();
oflush();
}
static void
-chc_init(int s, chcusr_t *user1, chcusr_t *user2, board_t board)
+chc_init_play_func(chcusr_t *user1, chcusr_t *user2, play_func_t play_func[2])
+{
+ char userid[2][IDLEN + 1];
+
+ if (chc_mode & CHC_PERSONAL) {
+ strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
+ strlcpy(userid[1], cuser.userid, sizeof(userid[1]));
+ play_func[0] = play_func[1] = myplay;
+ }
+ else if (chc_mode & CHC_WATCH) {
+ userinfo_t *uinfo = search_ulist_userid(currutmp->mateid);
+ strlcpy(userid[0], uinfo->userid, sizeof(userid[0]));
+ strlcpy(userid[1], uinfo->mateid, sizeof(userid[1]));
+ play_func[0] = play_func[1] = hisplay;
+ }
+ else {
+ strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
+ strlcpy(userid[1], currutmp->mateid, sizeof(userid[1]));
+ play_func[chc_my] = myplay;
+ play_func[chc_my ^ 1] = hisplay;
+ }
+
+ getuser(userid[0]);
+ chcusr_get(&xuser, user1);
+ getuser(userid[1]);
+ chcusr_get(&xuser, user2);
+}
+
+static void
+chc_watch_request(int signo)
+{
+ if (!(currstat & CHC))
+ return;
+ chc_act_list *tmp;
+ for(tmp = act_list; tmp->next != NULL; tmp = tmp->next);
+ tmp->next = (chc_act_list *)malloc(sizeof(chc_act_list));
+ tmp = tmp->next;
+ tmp->sock = reply_connection_request(uip);
+ if (tmp->sock < 0)
+ return;
+ tmp->next = NULL;
+ write(tmp->sock, chc_bp, sizeof(board_t));
+ write(tmp->sock, &chc_my, sizeof(chc_my));
+ write(tmp->sock, &chc_turn, sizeof(chc_turn));
+ write(tmp->sock, &currutmp->turn, sizeof(currutmp->turn));
+ write(tmp->sock, &chc_firststep, sizeof(chc_firststep));
+ write(tmp->sock, &chc_mode, sizeof(chc_mode));
+}
+
+static void
+chc_init(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t play_func[2])
{
userinfo_t *my = currutmp;
setutmpmode(CHC);
clear();
chc_warnmsg[0] = 0;
- if(s != 0){ // XXX mateid -> user2
- chc_my = my->turn;
- chc_mateid = my->mateid;
+
+ /* 從不同來源初始化各個變數 */
+ if (!(chc_mode & CHC_WATCH)) {
+ if (chc_mode & CHC_PERSONAL)
+ chc_my = 1;
+ else
+ chc_my = my->turn;
+ chc_firststep = 1;
+ chc_init_board(board);
+ chc_cursor.r = 9, chc_cursor.c = 0;
}
- else{
- chc_my = 1;
- chc_mateid = cuser.userid;
+ else {
+ char mode;
+ read(s, board, sizeof(board_t));
+ read(s, &chc_my, sizeof(chc_my));
+ read(s, &chc_turn, sizeof(chc_turn));
+ read(s, &my->turn, sizeof(my->turn));
+ read(s, &chc_firststep, sizeof(chc_firststep));
+ read(s, &mode, sizeof(mode));
+ if (mode & CHC_PERSONAL)
+ chc_mode |= CHC_WATCH_PERSONAL;
}
- chc_firststep = 1;
- chc_init_board(board);
+
+ act_list = (chc_act_list *)malloc(sizeof(*act_list));
+ act_list->sock = s;
+ act_list->next = 0;
+
+ chc_init_play_func(user1, user2, play_func);
+
chc_redraw(user1, user2, board);
- chc_cursor.r = 9, chc_cursor.c = 0;
add_io(s, 0);
- if (my->turn)
+ signal(SIGUSR1, chc_watch_request);
+
+ if (my->turn && !(chc_mode & CHC_WATCH))
chc_broadcast_recv(act_list, board);
user1->lose++;
- // if not watching
- passwd_query(usernum, &xuser);
- chcusr_put(&xuser, user1);
- passwd_update(usernum, &xuser);
+
+ if (chc_mode & CHC_VERSUS) {
+ passwd_query(usernum, &xuser);
+ chcusr_put(&xuser, user1);
+ passwd_update(usernum, &xuser);
+ }
if (!my->turn) {
- chc_broadcast_send(act_list, board);
- user2->lose++;
+ if (!(chc_mode & CHC_WATCH))
+ chc_broadcast_send(act_list, board);
+ user2->lose++;
}
chc_redraw(user1, user2, board);
}
void
-chc(int s, int type)
+chc(int s, int mode)
{
- char userid[2][IDLEN + 1];
- board_t board;
chcusr_t user1, user2;
play_func_t play_func[2];
+ board_t board;
+ char mode0 = currutmp->mode;
+ char file[80];
- signal(SIGUSR1, chc_watch_request);
+ signal(SIGUSR1, SIG_IGN);
- if (type == CHC_PERSONAL) {
- strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
- strlcpy(userid[1], cuser.userid, sizeof(userid[1]));
- play_func[0] = play_func[1] = myplay;
- }
- else if (type == CHC_WATCH) {
- userinfo_t *uinfo = search_ulist_userid(cuser.userid);
- strlcpy(userid[0], uinfo->userid, sizeof(userid[0]));
- strlcpy(userid[1], uinfo->mateid, sizeof(userid[1]));
- play_func[0] = play_func[1] = hisplay;
- timeout_read(s, 60);
- read(s, &board, sizeof(board));
- /////// nessesery? correct?
- read(s, &chc_turn, sizeof(chc_turn));
- }
- else {
- strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
- strlcpy(userid[1], currutmp->mateid, sizeof(userid[1]));
- play_func[0] = myplay;
- play_func[1] = hisplay;
- }
-
- if (type != CHC_WATCH) {
- act_list = (chc_act_list *)malloc(sizeof(*act_list));
- act_list->sock = s;
- act_list->next = 0;
- }
+ chc_mode = mode;
+ chc_bp = &board;
- getuser(userid[0]);
- chcusr_get(&xuser, &user1);
- getuser(userid[1]);
- chcusr_get(&xuser, &user2);
-
- chc_init(s, &user1, &user2, board);
+ chc_init(s, &user1, &user2, board, play_func);
+
+ setuserfile(file, CHC_LOG);
+ if (chc_log_open(&user1, &user2, file) < 0)
+ vmsg("無法紀錄棋局");
+
mainloop(s, &user1, &user2, board, play_func);
- if (type == CHC_VERSUS) {
- while(act_list){
- close(act_list->sock);
- act_list = act_list->next;
- }
+ /* close these fd */
+ if (chc_mode & CHC_PERSONAL)
+ act_list = act_list->next;
+ while(act_list){
+ close(act_list->sock);
+ act_list = act_list->next;
}
+
add_io(0, 0);
if (chc_my)
pressanykey();
+ currutmp->mode = mode0;
+
+ if (getans("是否將棋譜寄回信箱?[N/y]") == 'y') {
+ char title[80];
+ sprintf(title, "%s V.S. %s", user1.userid, user2.userid);
+ chc_log("\n--\n\n");
+ chc_log_poem();
+ chc_log_close();
+ mail_id(cuser.userid, title, file, "[楚河漢界]");
+ }
+ else
+ chc_log_close();
signal(SIGUSR1, talk_request);
}
+
+static userinfo_t *
+chc_init_utmp(void)
+{
+ char uident[16];
+ userinfo_t *uin;
+
+ stand_title("楚河漢界之爭");
+ generalnamecomplete(msg_uid, uident, sizeof(uident),
+ SHM->UTMPnumber,
+ completeutmp_compar,
+ completeutmp_permission,
+ completeutmp_getname);
+ if (uident[0] == '\0')
+ return NULL;
+
+ if ((uin = search_ulist_userid(uident)) == NULL)
+ return NULL;
+
+ uin->sig = SIG_CHC;
+ return uin;
+}
+
+int
+chc_main(void)
+{
+ userinfo_t *uin;
+
+ if ((uin = chc_init_utmp()) == NULL)
+ return -1;
+ uin->turn = 1;
+ currutmp->turn = 0;
+ strlcpy(uin->mateid, currutmp->userid, sizeof(uin->mateid));
+ strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
+
+ my_talk(uin, friend_stat(currutmp, uin), 'c');
+ return 0;
+}
+
+int
+chc_personal(void)
+{
+ chc(0, CHC_PERSONAL);
+ return 0;
+}
+
+int
+chc_watch(void)
+{
+ int sock, msgsock;
+ userinfo_t *uin;
+
+ if ((uin = chc_init_utmp()) == NULL)
+ return -1;
+
+ if (uin->uid == currutmp->uid)
+ return -1;
+
+ if ((sock = make_connection_to_somebody(uin, 10)) < 0) {
+ vmsg("無法建立連線");
+ return -1;
+ }
+ msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0);
+ close(sock);
+ if (msgsock < 0)
+ return -1;
+
+ strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
+ chc(msgsock, CHC_WATCH);
+ close(msgsock);
+ return 0;
+}
diff --git a/pttbbs/mbbsd/mbbsd.c b/pttbbs/mbbsd/mbbsd.c
index 2e0794dd..4fc5ac54 100644
--- a/pttbbs/mbbsd/mbbsd.c
+++ b/pttbbs/mbbsd/mbbsd.c
@@ -25,7 +25,7 @@ signal_restart(int signum, void (*handler) (int))
struct sigaction act;
act.sa_handler = handler;
memset(&(act.sa_mask), 0, sizeof(sigset_t));
- act.sa_flags = 0;
+ act.sa_flags = SA_NODEFER;
sigaction(signum, &act, NULL);
}
diff --git a/pttbbs/mbbsd/menu.c b/pttbbs/mbbsd/menu.c
index ca5b480f..ef978a94 100644
--- a/pttbbs/mbbsd/menu.c
+++ b/pttbbs/mbbsd/menu.c
@@ -467,6 +467,18 @@ static int m_jcee() {
static int forsearch();
static int playground();
+static commands_t chesslist[] = {
+ {chc_main, PERM_LOGINOK, "11Play 【 邀棋 】"},
+ {chc_personal, PERM_LOGINOK, "22Self-Play 【 打譜 】"},
+ {chc_watch, PERM_LOGINOK, "33CHCWatch 【 觀棋 】"},
+ {NULL, 0, NULL}
+};
+
+static int chessroom() {
+ domenu(CHESS_MENU, "Ptt棋奕館", '1', chesslist);
+ return 0;
+}
+
/* Ptt Play menu */
static commands_t playlist[] = {
#if 0
@@ -484,6 +496,7 @@ static commands_t playlist[] = {
{chicken_main,PERM_LOGINOK, "CChicken "
"【\033[1;34m Ptt養雞場 \033[m】"},
{playground,PERM_LOGINOK, "AAmusement 【\033[1;33m Ptt遊樂場 \033[m】"},
+ {chessroom,PERM_LOGINOK, "BChessroom 【\033[1;34m Ptt棋奕館 \033[m】"},
{NULL, 0, NULL}
};
diff --git a/pttbbs/mbbsd/talk.c b/pttbbs/mbbsd/talk.c
index 72a51131..42cae53b 100644
--- a/pttbbs/mbbsd/talk.c
+++ b/pttbbs/mbbsd/talk.c
@@ -42,7 +42,8 @@ static char save_page_requestor[40];
static char page_requestor[40];
static char description[30];
static FILE *flog;
-static userinfo_t *uip;
+
+userinfo_t *uip;
int
iswritable_stat(userinfo_t * uentp, int fri_stat)
@@ -1155,6 +1156,8 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){
(!ch && (uin->chatid[0] == 1 ||
uin->chatid[0] == 3))) {
add_io(0, 0);
+ if (ch == CHC)
+ break;
close(sock);
currutmp->sockactive = currutmp->destuid = 0;
outmsg("人家在忙啦");
@@ -1197,8 +1200,8 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){
return sock;
}
-static void
-my_talk(userinfo_t * uin, int fri_stat)
+void
+my_talk(userinfo_t * uin, int fri_stat, char defact)
{
int sock, msgsock, error = 0, ch;
pid_t pid;
@@ -1207,6 +1210,7 @@ my_talk(userinfo_t * uin, int fri_stat)
unsigned char mode0 = currutmp->mode;
+ genbuf[0] = defact;
ch = uin->mode;
strlcpy(currauthor, uin->userid, sizeof(currauthor));
@@ -1215,12 +1219,16 @@ my_talk(userinfo_t * uin, int fri_stat)
(!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3)) ||
uin->lockmode == M_FIVE || uin->lockmode == CHC) {
if (ch == CHC) {
- kill(uin->pid, SIGUSR1);
- if ((sock = make_connection_to_somebody(uin, 20)) < 0)
+ if ((sock = make_connection_to_somebody(uin, 10)) < 0)
vmsg("無法建立連線");
else {
- strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
- chc(sock, CHC_WATCH);
+ int msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0);
+ close(sock);
+ if (msgsock >= 0) {
+ strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
+ chc(msgsock, CHC_WATCH);
+ close(msgsock);
+ }
}
}
else
@@ -1240,7 +1248,8 @@ my_talk(userinfo_t * uin, int fri_stat)
outs(msg_usr_left);
} else {
showplans(uin->userid);
- getdata(2, 0, "要和他(她) (T)談天(F)下五子棋(P)鬥寵物"
+ if (!genbuf[0])
+ getdata(2, 0, "要和他(她) (T)談天(F)下五子棋(P)鬥寵物"
"(C)下象棋(D)下暗棋(N)沒事找錯人了?[N] ", genbuf, 4, LCECHO);
switch (*genbuf) {
case 'y':
@@ -1365,13 +1374,6 @@ my_talk(userinfo_t * uin, int fri_stat)
pressanykey();
}
-static void
-self_play(userinfo_t * uin, int fri_stat)
-{
- if (getans("[象棋] 你確定要打譜嗎?[N/y]") == 'y')
- chc(0, CHC_PERSONAL);
-}
-
/* 選單式聊天介面 */
#define US_PICKUP 1234
#define US_RESORT 1233
@@ -2222,17 +2224,14 @@ userlist(void)
case 't':
if (HAS_PERM(PERM_LOGINOK)) {
- move(1, 0);
- clrtobot();
- move(3, 0);
if (uentp->pid != currpid &&
strcmp(uentp->userid, cuser.userid) != 0) {
- my_talk(uentp, fri_stat);
- }
- else{
- self_play(uentp, fri_stat);
+ move(1, 0);
+ clrtobot();
+ move(3, 0);
+ my_talk(uentp, fri_stat, 0);
+ redrawall = redraw = 1;
}
- redrawall = redraw = 1;
}
break;
case 'K':
@@ -2539,12 +2538,12 @@ t_talk()
}
if ((uentp = (userinfo_t *) search_ulistn(tuid, unum)))
- my_talk(uentp, friend_stat(currutmp, uentp));
+ my_talk(uentp, friend_stat(currutmp, uentp), 0);
return 0;
}
-static int
+int
reply_connection_request(userinfo_t *uip)
{
int a;
@@ -2554,7 +2553,7 @@ reply_connection_request(userinfo_t *uip)
uip = &SHM->uinfo[currutmp->destuip];
- if (uip->mode != PAGE) {
+ if (uip->mode != PAGE && uip->mode != CHC) {
snprintf(genbuf, sizeof(genbuf),
"%s已停止呼叫,按Enter繼續...", page_requestor);
getdata(0, 0, genbuf, buf, sizeof(buf), LCECHO);
@@ -2572,7 +2571,6 @@ reply_connection_request(userinfo_t *uip)
memcpy(&sin.sin_addr, h->h_addr, h->h_length);
sin.sin_port = uip->sockaddr;
a = socket(sin.sin_family, SOCK_STREAM, 0);
- ///////////////
if ((connect(a, (struct sockaddr *) & sin, sizeof(sin)))) {
perror("connect err");
return -1;
@@ -2580,19 +2578,6 @@ reply_connection_request(userinfo_t *uip)
return a;
}
-void
-chc_watch_request(int signo)
-{
- if (!(currstat & CHC))
- return;
- chc_act_list *tmp;
- for(tmp = act_list; tmp->next != NULL; tmp = tmp->next);
- tmp->next = (chc_act_list *)malloc(sizeof(chc_act_list));
- tmp = tmp->next;
- tmp->sock = reply_connection_request(uip);
- tmp->next = NULL;
-}
-
/* 有人來串門子了,回應呼叫器 */
void
talkreply(void)
diff --git a/pttbbs/mbbsd/var.c b/pttbbs/mbbsd/var.c
index 1d2eac31..aae2fd8c 100644
--- a/pttbbs/mbbsd/var.c
+++ b/pttbbs/mbbsd/var.c
@@ -389,8 +389,10 @@ char trans_buffer[256];
rc_t chc_from, chc_to, chc_select, chc_cursor;
int chc_lefttime;
int chc_my, chc_turn, chc_selected, chc_firststep;
-char chc_warnmsg[64], *chc_mateid;
+char chc_mode;
+char chc_warnmsg[64];
chc_act_list *act_list = NULL;
+board_t *chc_bp;
/* screen.c */
screenline_t *big_picture = NULL;
diff --git a/pttbbs/sample/etc/Makefile b/pttbbs/sample/etc/Makefile
index 6a2755ef..2f2753eb 100644
--- a/pttbbs/sample/etc/Makefile
+++ b/pttbbs/sample/etc/Makefile
@@ -1,4 +1,4 @@
-SUBDIR=chickens
+SUBDIR=chickens chess
BBSHOME?=$(HOME)
TARGET=$(BBSHOME)/etc/
FILES= @five Welcome register today_boring \
diff --git a/pttbbs/sample/etc/chess/1.poem b/pttbbs/sample/etc/chess/1.poem
new file mode 100644
index 00000000..f50247ab
--- /dev/null
+++ b/pttbbs/sample/etc/chess/1.poem
@@ -0,0 +1,10 @@
+象弈 南宋 劉克莊
+
+ 或遲如圍莒,或速如入蔡。
+
+ 遠炮勿虛發,冗卒要精汰。
+
+ 負非由寡少,勝豈繫強大?
+
+ 昆陽以象奔,陳濤以車敗。
+
diff --git a/pttbbs/sample/etc/chess/10.poem b/pttbbs/sample/etc/chess/10.poem
new file mode 100644
index 00000000..b9dc2107
--- /dev/null
+++ b/pttbbs/sample/etc/chess/10.poem
@@ -0,0 +1,10 @@
+無題 明 明太子朱高熾
+
+ 二國爭強各用兵,擺成隊伍定輸贏。
+
+ 馬行曲路當先道,將守深宮戒遠征。
+
+ 乘險出車收敗卒,隔河飛炮下重城。
+
+ 等閒識得軍情事,一著功成見太平。
+
diff --git a/pttbbs/sample/etc/chess/11.poem b/pttbbs/sample/etc/chess/11.poem
new file mode 100644
index 00000000..01331372
--- /dev/null
+++ b/pttbbs/sample/etc/chess/11.poem
@@ -0,0 +1,6 @@
+無題 不明
+
+ 清風明月之夜,詩歌唱詠;
+
+ 古松流水之間,敲棋品茗。
+
diff --git a/pttbbs/sample/etc/chess/12.poem b/pttbbs/sample/etc/chess/12.poem
new file mode 100644
index 00000000..53a68b72
--- /dev/null
+++ b/pttbbs/sample/etc/chess/12.poem
@@ -0,0 +1,6 @@
+諷宋薛昂處士負棋作詩 不明
+
+ 好笑當年薛乞兒,荊公座上賭新詩,
+
+ 而今又向江東去,奉勸先生莫下棋。
+
diff --git a/pttbbs/sample/etc/chess/13.poem b/pttbbs/sample/etc/chess/13.poem
new file mode 100644
index 00000000..01331372
--- /dev/null
+++ b/pttbbs/sample/etc/chess/13.poem
@@ -0,0 +1,6 @@
+無題 不明
+
+ 清風明月之夜,詩歌唱詠;
+
+ 古松流水之間,敲棋品茗。
+
diff --git a/pttbbs/sample/etc/chess/14.poem b/pttbbs/sample/etc/chess/14.poem
new file mode 100644
index 00000000..d41950e8
--- /dev/null
+++ b/pttbbs/sample/etc/chess/14.poem
@@ -0,0 +1,10 @@
+無題 明 明象棋高手李開先 村翁
+
+ 小有兼逢大有年,田家多穫即為賢。
+
+ 有時撒網為漁父,日常登床作睡仙。
+
+ 破局棋堆隨手應,無弦琴不用音傳。
+
+ 一身之外無所慕,下有青山上碧天。
+
diff --git a/pttbbs/sample/etc/chess/15.poem b/pttbbs/sample/etc/chess/15.poem
new file mode 100644
index 00000000..139597f9
--- /dev/null
+++ b/pttbbs/sample/etc/chess/15.poem
@@ -0,0 +1,2 @@
+
+
diff --git a/pttbbs/sample/etc/chess/16.poem b/pttbbs/sample/etc/chess/16.poem
new file mode 100644
index 00000000..139597f9
--- /dev/null
+++ b/pttbbs/sample/etc/chess/16.poem
@@ -0,0 +1,2 @@
+
+
diff --git a/pttbbs/sample/etc/chess/2.poem b/pttbbs/sample/etc/chess/2.poem
new file mode 100644
index 00000000..119e98ae
--- /dev/null
+++ b/pttbbs/sample/etc/chess/2.poem
@@ -0,0 +1,10 @@
+棋詩 明 曾子棨
+
+ 兩軍對敵立雙營,坐運神機決死生。
+
+ 千里封疆馳鐵馬,一川波浪動金兵。
+
+ 虞姬歌舞悲垓下,反將旌旗逼楚城。
+
+ 興盡計窮征戰罷,松蔭花影滿棋秤。
+
diff --git a/pttbbs/sample/etc/chess/3.poem b/pttbbs/sample/etc/chess/3.poem
new file mode 100644
index 00000000..d69636b7
--- /dev/null
+++ b/pttbbs/sample/etc/chess/3.poem
@@ -0,0 +1,6 @@
+觀棋 清 袁枚
+
+ 攏袖觀棋有所思,分明楚漢兩軍峙。
+
+ 非常喜歡非常惱,不著棋人總不如。
+
diff --git a/pttbbs/sample/etc/chess/4.poem b/pttbbs/sample/etc/chess/4.poem
new file mode 100644
index 00000000..f86edc12
--- /dev/null
+++ b/pttbbs/sample/etc/chess/4.poem
@@ -0,0 +1,10 @@
+和春深 唐 白居易
+
+ 何處深為好,春到博弈家。
+
+ 一先爭破眼,六聚斗成花,
+
+ 鼓應投壹馬,兵沖象戲車。
+
+ 評棋局上事,最妙是長斜。
+
diff --git a/pttbbs/sample/etc/chess/5.poem b/pttbbs/sample/etc/chess/5.poem
new file mode 100644
index 00000000..cffd55e1
--- /dev/null
+++ b/pttbbs/sample/etc/chess/5.poem
@@ -0,0 +1,8 @@
+無題 宋 王安石
+
+ 飄飄凌雲志,強御莫能懾;
+
+ 忘情塞上馬,適志夢中蝶;
+
+ 經論安所施,有寓聊自愜。
+
diff --git a/pttbbs/sample/etc/chess/6.poem b/pttbbs/sample/etc/chess/6.poem
new file mode 100644
index 00000000..00c4cff8
--- /dev/null
+++ b/pttbbs/sample/etc/chess/6.poem
@@ -0,0 +1,6 @@
+無題 呂洞賓
+
+ 教著殘局山月曉,
+
+ 一聲長嘯海天秋。
+
diff --git a/pttbbs/sample/etc/chess/7.poem b/pttbbs/sample/etc/chess/7.poem
new file mode 100644
index 00000000..b525cba0
--- /dev/null
+++ b/pttbbs/sample/etc/chess/7.poem
@@ -0,0 +1,10 @@
+吊棋 明 錢鶴灘
+
+ 敲棋終日與偏幽,誰道今朝結父仇。
+
+ 兵足下河車不救,將軍落水士難留。
+
+ 馬行千里隨波去,象渡三江逐淚流。
+
+ 炮響一聲驚霹靂,臥龍投起碧雲浮。
+
diff --git a/pttbbs/sample/etc/chess/8.poem b/pttbbs/sample/etc/chess/8.poem
new file mode 100644
index 00000000..01360b29
--- /dev/null
+++ b/pttbbs/sample/etc/chess/8.poem
@@ -0,0 +1,10 @@
+詠象戲 北宋 程顥
+
+ 大都博弈皆戲劇,象戲翻能學用兵。
+
+ 車馬尚存周戰法,偏裨兼備漢官名。
+
+ 中軍八面將軍重,河外尖斜步卒輕。
+
+ 卻憑紋楸聊自笑,雄如劉項亦間爭。
+
diff --git a/pttbbs/sample/etc/chess/9.poem b/pttbbs/sample/etc/chess/9.poem
new file mode 100644
index 00000000..01331372
--- /dev/null
+++ b/pttbbs/sample/etc/chess/9.poem
@@ -0,0 +1,6 @@
+無題 不明
+
+ 清風明月之夜,詩歌唱詠;
+
+ 古松流水之間,敲棋品茗。
+