-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathPgnToBook.cpp
324 lines (218 loc) · 5.39 KB
/
PgnToBook.cpp
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#include "stdafx.h"
#include "data.h"
#include "chess.h"
#include "Resource.h"
#include "pregen.h"
#include <sys/stat.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
//查看一下,PGN 棋步在不在当前可走的棋步中
int getMoveFormPgnStr(dispboard_t* pDis, char* pgnStr){
position_t *pos = pDis->pos;
gen_legal_moves(pos);
while(pos->pMend > pos->all_move){
pos->pMend--;
if(pos->His[pos->curStep].ischeck == FALSE){
if(move_is_legal(pos,pos->pMend->move) == FALSE){
continue;
}
}
//pos->pMend--;
//得到走步的名称
GetMoveName(pDis,pos,pos->pMend->move, appData.moveType);
char* szStepName = pDis->moveListName[pos->curStep] + 4; //加上前面的编号哇
//if(string_start_with(pgnStr,szStepName)){
// return pos->pMend->move;
//}
//看前面8个字符是不是一样
BOOL find = TRUE;
for(int i = 0; i < 8; i++){
if(szStepName[i] != pgnStr[i]){
find= FALSE;
break;
}
}
if(find == TRUE){
return pos->pMend->move;
}
}
return 0;
}
BOOL ReadPgnToPos (dispboard_t* pDis, char* pgnFname, pgn_file_t* PGN){
char pgnBuf[4096];
//memset(pgnBuf,0, sizeof(pgnBuf));
//char buf[512];
//char intbuf[32];
int pFile;
//int i;
//将PGN清空一下
memset(PGN,0,sizeof(pgn_file_t));
sprintf_s(PGN->pgn_format,sizeof(PGN->pgn_format),"pgn");
errno_t err = _sopen_s(&pFile, pgnFname, _O_RDONLY, _SH_DENYNO,
_S_IREAD | _S_IWRITE);
if(err != 0){
LogOut(pgnFname);
LogOut("\nPGN 文件不存在,或打不开!!\n");
return FALSE;
}
//将文件全部读入BUF
int bytesRead = _read(pFile, pgnBuf, sizeof(pgnBuf));
if(bytesRead <= 0){
LogOut(pgnFname);
LogOut("\nPGN 文件不存在,或打不开!!\n");
_close(pFile);
return FALSE;
}
_close(pFile);
if(bytesRead < 20){
LogOut(pgnFname);
LogOut("\nPGN 文件内容太少!!\n");
return FALSE;
}
//Returns a pointer to the first occurrence of strSearch in str,
//or NULL if strSearch does not appear in str.
//If strSearch points to a string of zero length, the function returns str.
char* ps;
int len = (int)strlen(pgnBuf);
char* pend = pgnBuf + len;
*pend = 0;
*(pend-1) = 0;
//*(pend-1) = 0; //加上一个结尾
//ps = strstr(pgnBuf,"Round");
//if(ps == NULL){
// LogOut(pgnFname);
// LogOut("\nPGN 在PGN文件中没有发现 Round项 !!\n");
// return FALSE;
//}
ps = pgnBuf;
int ply = 1; //PGN文件1开头
char str_num[32];
while(ps < pend){
if((pend - ps) < 7){
goto PGN_RET; //没有棋步了
}
sprintf_s(str_num,sizeof(str_num),"%d. ",ply);
ps = strstr(ps,str_num);
if(ps != NULL){ //这儿可能有两步
ps = strstr(ps," "); //找到第一个空格
if(ps == NULL){
goto PGN_RET; //没有棋步了
}
while(ps < pend && *(++ps) == ' '){ //跳过后面的空格
}
if(ps > pend){
goto PGN_RET; //没有棋步了
}
if((pend - ps) < 7){
goto PGN_RET; //没有棋步了
}
int move = getMoveFormPgnStr(pDis,ps);
if(move == 0){
goto PGN_RET; //没有棋步了
}
//直接走步了
UserMoveEvent(pDis,
StoX(FROM(move)) - 3,
StoY(FROM(move)) - 3,
StoX(TO(move)) - 3,
StoY(TO(move)) - 3, 0);
if((pend - ps) < 7){
goto PGN_RET; //没有棋步了
}
ps = strstr(ps, " ");
if(ps == NULL){
goto PGN_RET; //没有棋步了
}
while(ps < pend && *(++ps) == ' '){ //跳过后面的空格
}
if(ps > pend){
goto PGN_RET; //没有棋步了
}
if((pend - ps) < 7){
goto PGN_RET; //没有棋步了
}
move = getMoveFormPgnStr(pDis,ps);
if(move == 0){
goto PGN_RET; //没有棋步了
}
//直接走步了
UserMoveEvent(pDis,
StoX(FROM(move)) - 3,
StoY(FROM(move)) - 3,
StoX(TO(move)) - 3,
StoY(TO(move)) - 3, 0);
ply++;
}
else{
goto PGN_RET; //没有棋步了
}
}
PGN_RET:
if( (pend-ps) > 7){
LogOut(pgnFname);
LogOut("\n还有棋步没有解析哇!!\n");
LogOut(pgnBuf);
LogOut("\n棋步编号:");
LogOut(str_num);
}
if(ply > 1){
//设为允许使用
//CheckDlgItem(
LogOut(pgnBuf);
LogOut("\n成功读入了一局PGN文件到内存!\n");
return TRUE;
}
else{
return FALSE;
}
}
//将目录下的PGN文件都一个一个读入开局库
BOOL PgnFileCatToBook(char* pgnRoot){
//char pgnPath[MAX_PATH];
//sprintf_s(pgnPath,MAX_PATH,"%s%s",installDir,"pgn\\");
BOOL havePgn = FALSE;
char filename[MAX_PATH*2];
BOOL isFind = FALSE;
char dir[MAX_PATH];
char pre_name[MAX_PATH*2];
char new_name[MAX_PATH*2];
char ok_dir[MAX_PATH];
int ok_num = 0;
dispboard_t *pDis = OBS[0];
pgn_file_t PGN[1];
ResetGameEvent(pDis);
sprintf_s(ok_dir,sizeof(ok_dir),"%s%s",pgnRoot,"_ok");
CreateDirectory(ok_dir,NULL); //建立转换成功的目录
do{ //打开一个pgn文件
OpenAllCatFileOnebyOne(&isFind,pgnRoot,"*.pgn","_ok",dir,filename);
if(isFind){
sprintf_s(pre_name,sizeof(pre_name),"%s%s",dir,filename);
if(ReadPgnToPos(pDis,pre_name,PGN)){
//读入成功了,就移动到_ok目录下
sprintf_s(new_name,sizeof(new_name),"%s%s%s",ok_dir,"\\",filename);
if(FALSE == MoveFileEx(pre_name,new_name,MOVEFILE_REPLACE_EXISTING)){
LogOut(pre_name);
LogOut("\n不能移动或改名到_ok目录!!\n");
LogOut(new_name);
break;
}
LogOut("\n成功读入一局PGN文件!\n");
LogOut(pre_name);
havePgn = TRUE;
}
else{
//不能正确读入PGN文件
LogOut(pre_name);
LogOut("读入PGN文件错误,请检查PGN格式!!\n");
break;
}
isFind = FALSE;
}
else{
LogOut(pgnRoot);
LogOut("\n对不起,没有在以上目录下找到有效的PGN文件\n");
}
}while(false);
return havePgn;
}