/* $Id$ */ #ifndef INCLUDE_CHESS_H #define INCLUDE_CHESS_H #define CHESS_DRAWING_TIME_ROW 128 #define CHESS_DRAWING_TURN_ROW 129 #define CHESS_DRAWING_WARN_ROW 130 #define CHESS_DRAWING_STEP_ROW 131 #define CHESS_DRAWING_HELP_ROW 132 #define CHESS_PHOTO_LINE 15 #define CHESS_PHOTO_COLUMN (256 + 25) struct ChessBroadcastList; struct ChessActions; struct ChessConstants; #define const #define static #define private typedef struct { char userid[IDLEN + 1]; int win; int lose; int tie; unsigned short rating; unsigned short orig_rating; // 原始 rating, 因為遊戲開始先算輸一場, rating 值就跑掉了 } ChessUser; private typedef struct { int used; int size; void *body; } ChessHistory; /* 棋類觀戰 * * 雙人對戰時,雙方都會有一個 broadcast_list 的 linked-list,紀錄著每下一 * 步棋,必須將這個訊息丟給那些人(sock)。 * 每當一個觀棋者加入(觀棋可以從紅方或黑方的觀點進行),其中一方的下棋者 * 的 broadcast_list 就會多一筆記錄,之後就會將下的或收到對方下的每一步棋 * 傳給 broadcast_list 中所有需要的人,達到觀棋的效果。 */ private typedef struct ChessBroadcastListNode { int sock; struct ChessBroadcastListNode *next; } ChessBroadcastListNode; private typedef struct ChessBroadcastList { struct ChessBroadcastListNode head; /* dummy node */ } ChessBroadcastList; typedef struct { int limit_hand; int limit_time; int free_time; enum { CHESS_TIMEMODE_MULTIHAND, /* 限時限步 */ CHESS_TIMEMODE_COUNTING /* 讀秒 */ } time_mode; } ChessTimeLimit; typedef enum { CHESS_MODE_VERSUS, /* 對奕 */ CHESS_MODE_WATCH, /* 觀棋 */ CHESS_MODE_PERSONAL, /* 打譜 */ CHESS_MODE_REPLAY /* 看譜 */ } ChessGameMode; typedef enum { CHESS_RESULT_CONTINUE, CHESS_RESULT_WIN, CHESS_RESULT_LOST, CHESS_RESULT_TIE, CHESS_RESULT_END /* watching or replaying */ } ChessGameResult; typedef struct ChessInfo { private const static struct ChessActions* actions; /* vtable */ private const static struct ChessConstants* constants; rc_t cursor; /* 計時用, [0] = mine, [1] = his */ int lefttime[2]; int lefthand[2]; /* 限時限步時用, = 0 表為自由時間或非限時限步模式 */ const ChessTimeLimit* timelimit; const ChessGameMode mode; const ChessUser user1; const ChessUser user2; const char myturn; /* 我方顏色 */ char turn; char pass[2]; char warnmsg[64]; char last_movestr[36]; char *photo; void *board; void *tag; private int sock; private ChessHistory history; private ChessBroadcastList broadcast_list; private ChessGameResult (*play_func[2])(struct ChessInfo* info); private int current_step; /* used by watch and replay */ private char step_tmp[0]; } ChessInfo; #undef const #undef static #undef private typedef struct ChessActions { /* initial */ void (*init_user) (const userinfo_t* uinfo, ChessUser* user); void (*init_user_rec)(const userec_t* uinfo, ChessUser* user); void (*init_board) (void* board); /* playing */ void (*drawline) (const ChessInfo* info, int line); void (*movecur) (int r, int c); int (*prepare_play)(ChessInfo* info); int (*process_key) (ChessInfo* info, int key, ChessGameResult* result); int (*select) (ChessInfo* info, rc_t location, ChessGameResult* result); void (*prepare_step)(ChessInfo* info, const void* step); ChessGameResult (*apply_step)(void* board, const void* step); void (*drawstep) (ChessInfo* info, const void* step); ChessGameResult (*post_game)(ChessInfo* info); /* ending */ void (*gameend) (ChessInfo* info, ChessGameResult result); void (*genlog) (ChessInfo* info, FILE* fp, ChessGameResult result); } ChessActions; typedef struct ChessConstants { int step_entry_size; int traditional_timeout; int board_height; int board_width; int pass_is_step; const char *chess_name; const char *photo_file_name; const char *log_board; const char *turn_color[2]; const char *turn_str[2]; } ChessConstants; typedef enum { CHESS_STEP_NORMAL, CHESS_STEP_PASS, CHESS_STEP_DROP, CHESS_STEP_FAILURE, CHESS_STEP_SPECIAL, /* chesses' special steps */ CHESS_STEP_NOP, /* for wake up */ CHESS_STEP_TIE, /* tie request */ CHESS_STEP_TIE_ACC, /* accept */ CHESS_STEP_TIE_REJ, /* reject */ CHESS_STEP_UNDO, /* undo request */ CHESS_STEP_UNDO_ACC, /* accept */ CHESS_STEP_UNDO_REJ, /* reject */ } ChessStepType; int ChessTimeCountDown(ChessInfo* info, int who, int length); void ChessStepMade(ChessInfo* info, int who); ChessStepType ChessStepReceive(ChessInfo* info, void* step); /* should this be public? */ int ChessStepSend(ChessInfo* info, const void* step); int ChessMessageSend(ChessInfo* info, ChessStepType type); void ChessHistoryAppend(ChessInfo* info, void* step); const void* ChessHistoryRetrieve(ChessInfo* info, int n); void ChessPlay(ChessInfo* info); int ChessStartGame(char func_char, int sig, const char* title); int ChessWatchGame(void (*play)(int, ChessGameMode), int game, const char* title); int ChessReplayGame(const char* fname); ChessInfo* NewChessInfo(const ChessActions* actions, const ChessConstants* constants, int sock, ChessGameMode mode); void DeleteChessInfo(ChessInfo* info); void ChessEstablishRequest(int sock); void ChessAcceptingRequest(int sock); void ChessShowRequest(void); void ChessRedraw(const ChessInfo* info); void ChessDrawLine(const ChessInfo* info, int line); void ChessDrawExtraInfo(const ChessInfo* info, int line, int space); #endif /* INCLUDE_CHESS_H */