1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/* $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 */
|