Rev 1805 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4652 | ashmew2 | 1 | |
2 | |||
3 | #endif |
||
4 | |||
5 | #ifndef __MENUET__ |
||
6 | |||
7 | #include |
||
8 | |||
9 | #include |
||
1805 | yogev_ezra | 10 | #include |
11 | #else |
||
12 | #include |
||
13 | #include |
||
14 | using namespace Menuet; |
||
15 | #define strlen StrLen |
||
16 | #define strcpy StrCopy |
||
17 | #define memcpy MemCopy |
||
18 | #include |
||
19 | const unsigned dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, |
||
20 | 10000, 1000, 100, 10, 0 }; |
||
21 | int sprintf( char *Str, char* Format, ... ) |
||
22 | { |
||
23 | int i, fmtlinesize, j, k, flag; |
||
24 | unsigned head, tail; |
||
25 | char c; |
||
26 | va_list arglist; |
||
27 | // |
||
28 | va_start(arglist, Format); |
||
29 | |||
30 | // |
||
31 | fmtlinesize = strlen( Format ); |
||
32 | // |
||
33 | if( fmtlinesize == 0 ) return 0; |
||
34 | |||
35 | // |
||
36 | for( i = 0, j = 0; i < fmtlinesize; i++ ) |
||
37 | { |
||
38 | // |
||
39 | |||
40 | // |
||
41 | if( c != '%' ) |
||
42 | { |
||
43 | Str[j++] = c; |
||
44 | continue; |
||
45 | } |
||
46 | // |
||
47 | i++; |
||
48 | // |
||
49 | if( i >= fmtlinesize ) break; |
||
50 | |||
51 | // |
||
52 | flag = 0; |
||
53 | // |
||
54 | c = Format[i]; |
||
55 | |||
56 | // |
||
57 | switch( c ) |
||
58 | { |
||
59 | // |
||
60 | case '%': |
||
61 | Str[j++] = c; |
||
62 | break; |
||
63 | // |
||
64 | case 's': |
||
65 | char* str; |
||
66 | str = va_arg(arglist, char*); |
||
67 | for( k = 0; ( c = str[k] ) != 0; k++ ) |
||
68 | { |
||
69 | Str[j++] = c; |
||
70 | } |
||
71 | break; |
||
72 | // |
||
73 | case 'c': |
||
74 | Str[j++] = va_arg(arglist, int) & 0xFF; |
||
75 | break; |
||
76 | // |
||
77 | case 'u': |
||
78 | case 'd': |
||
79 | head = va_arg(arglist, unsigned); |
||
80 | for( k = 0; dectab[k] != 0; k++ ) |
||
81 | { |
||
82 | tail = head % dectab[k]; |
||
83 | head /= dectab[k]; |
||
84 | c = head + '0'; |
||
85 | if( c == '0' ) |
||
86 | { |
||
87 | if( flag ) Str[j++] = c; |
||
88 | } |
||
89 | else |
||
90 | { |
||
91 | flag++; |
||
92 | Str[j++] = c; |
||
93 | } |
||
94 | // |
||
95 | head = tail; |
||
96 | } |
||
97 | // |
||
98 | c = head + '0'; |
||
99 | Str[j++] = c; |
||
100 | break; |
||
101 | default: |
||
102 | break; |
||
103 | } |
||
104 | } |
||
105 | // |
||
106 | Str[j] = 0; |
||
107 | return j; |
||
108 | } |
||
109 | int isdigit(int c) |
||
110 | { |
||
111 | return (c>='0' && c<='9'); |
||
112 | } |
||
113 | int atoi(const char* string) |
||
114 | { |
||
115 | int res=0; |
||
116 | int sign=0; |
||
117 | const char* ptr; |
||
118 | for (ptr=string; *ptr && *ptr<=' ';ptr++); |
||
119 | if (*ptr=='-') {sign=1;++ptr;} |
||
120 | while (*ptr >= '0' && *ptr <= '9') |
||
121 | { |
||
122 | res = res*10 + *ptr++ - '0'; |
||
123 | } |
||
124 | if (sign) res = -res; |
||
125 | return res; |
||
126 | } |
||
127 | int islower(int c) |
||
128 | { |
||
129 | return (c>='a' && c<='z'); |
||
130 | } |
||
131 | int abs(int n) |
||
132 | { |
||
133 | return (n<0)?-n:n; |
||
134 | } |
||
135 | int memcmp(const void* buf1, const void* buf2, unsigned count) |
||
136 | { |
||
137 | const char* ptr1 = (const char*)buf1; |
||
138 | const char* ptr2 = (const char*)buf2; |
||
139 | unsigned i=0; |
||
140 | while (i |
||
141 | if (i==count) |
||
142 | return 0; |
||
143 | else if (*ptr1<*ptr2) |
||
144 | return -1; |
||
145 | else |
||
146 | return 1; |
||
147 | } |
||
148 | void strncpy(char* dest, const char* source, unsigned len) |
||
149 | { |
||
150 | char* ptr1 = dest; |
||
151 | const char *ptr2 = source; |
||
152 | for (;len-- && *ptr2; *ptr1++=*ptr2++) ; |
||
153 | } |
||
154 | unsigned int rand_data[4]; |
||
155 | |||
156 | void randomize() |
||
157 | { |
||
158 | rand_data[0] = (unsigned int)Clock(); |
||
159 | rand_data[1] = (unsigned int)GetPackedTime(); |
||
160 | |||
161 | rand_data[3] = (unsigned int)0xA3901BD2 ^ GetPid(); |
||
162 | } |
||
163 | |||
164 | unsigned int rand() |
||
165 | { |
||
166 | rand_data[0] ^= _HashDword(rand_data[3] + 0x2835C013U); |
||
167 | rand_data[1] += _HashDword(rand_data[0]); |
||
168 | |||
169 | rand_data[3] ^= _HashDword(rand_data[2]); |
||
170 | return rand_data[3]; |
||
171 | } |
||
172 | |||
173 | #define random(k) (rand() % (k)) |
||
174 | #define floor Floor |
||
175 | double fabs(double x) |
||
176 | { |
||
177 | |||
178 | __asm fabs |
||
179 | } |
||
180 | #define M_PI 3.14159265358979323846 |
||
181 | double cos(double x) |
||
182 | { |
||
183 | __asm fld x |
||
184 | __asm fcos |
||
185 | } |
||
186 | double sin(double x) |
||
187 | { |
||
188 | __asm fld x |
||
189 | __asm fsin |
||
190 | } |
||
191 | /*inline void printf(const char* format, ...) |
||
192 | {}*/ |
||
193 | #define printf /* nothing */ |
||
194 | inline void strcat(char* str1, const char* str2) |
||
195 | {strcpy(str1+strlen(str1),str2);} |
||
196 | int strncmp(const char* str1, const char* str2, unsigned len) |
||
197 | { |
||
198 | for (;len--;) |
||
199 | { |
||
200 | if (*str1 != *str2) break; |
||
201 | if (*str1 == 0) |
||
202 | return 0; |
||
203 | ++str1;++str2; |
||
204 | } |
||
205 | if (len==(unsigned)-1) |
||
206 | return 0; |
||
207 | if (*str1 < *str2) |
||
208 | return -1; |
||
209 | return 1; |
||
210 | } |
||
211 | #define clock Clock |
||
212 | typedef unsigned int clock_t; |
||
213 | #define CLOCKS_PER_SEC 100 |
||
214 | #define XK_Left 0xB0 |
||
215 | #define XK_Right 0xB3 |
||
216 | #define XK_Up 0xB2 |
||
217 | #define XK_Down 0xB1 |
||
218 | #define XK_Return 0x0D |
||
219 | #define XK_space 0x20 |
||
220 | #define XK_Escape 0x1B |
||
221 | #define XK_less '<' |
||
222 | #define XK_comma ',' |
||
223 | #define XK_period '.' |
||
224 | #define XK_greater '>' |
||
225 | #define XK_minus '-' |
||
226 | #define XK_equal '=' |
||
227 | #define XK_underscore '_' |
||
228 | #define XK_plus '+' |
||
229 | #define XK_Delete 0xB6 |
||
230 | #define XK_F8 0x39 |
||
231 | #define XK_l 'l' |
||
232 | #define XK_L 'L' |
||
233 | #define XK_F2 0x33 |
||
234 | #define XK_s 's' |
||
235 | #define XK_S 'S' |
||
236 | #define XK_slash '/' |
||
237 | #define XK_question '?' |
||
238 | #define XK_n 'n' |
||
239 | #define XK_N 'N' |
||
240 | #define XK_t 't' |
||
241 | #define XK_T 'T' |
||
242 | #define XK_r 'r' |
||
243 | #define XK_R 'R' |
||
244 | #define XK_b 'b' |
||
245 | #define XK_B 'B' |
||
246 | #define XK_f 'f' |
||
247 | #define XK_F 'F' |
||
248 | #define assert(a) /* nothing */ |
||
249 | #include "qsort.c" |
||
250 | #endif |
||
251 | #include "gr-draw.h" |
||
252 | #include "board.h" |
||
253 | #include "player.h" |
||
254 | #include "buttons.h" |
||
255 | #include "sysproc.h" |
||
256 | |||
257 | char *strskipref(char *s1, char *s2) |
||
258 | { |
||
259 | int L = strlen(s2); |
||
260 | if (strncmp(s1, s2, L) == 0) return s1 + L; |
||
261 | |||
262 | } |
||
263 | |||
264 | class TPlayArray |
||
265 | { |
||
266 | public: |
||
267 | TPlayArray(int d = 10) : play(0), nplay(0), mplay(0) {} |
||
268 | |||
269 | |||
270 | void Clear(); |
||
271 | void Add(const PlayWrite &pl); |
||
272 | PlayWrite &operator[](int i) {return play[i];} |
||
273 | int GetNPlay() const {return nplay;} |
||
274 | |||
275 | int OpenFile(const char *name, int kind); |
||
276 | int MsgOpenFile(const char *name, int kind); |
||
277 | int SaveFile(const char *name, int num, int kind); |
||
278 | int MsgSaveFile(const char *name, int num, int kind); |
||
279 | #endif |
||
280 | void Del(int n); |
||
281 | protected: |
||
282 | void Extend(int n = -1); |
||
283 | |||
284 | PlayWrite *play; |
||
285 | int nplay, mplay; |
||
286 | protected: |
||
287 | #ifndef __MENUET__ |
||
288 | |||
289 | static int AnalizeKind(FILE *f, const int w[], const char *smb = 0); |
||
290 | static int ReadFileTo(FILE *f, char c); |
||
291 | static int ReadFileTo(FILE *f, const char *c); |
||
292 | static int ReadTheText(FILE *f, const char *s); |
||
293 | #endif |
||
294 | }; |
||
295 | |||
296 | #ifndef __MENUET__ |
||
297 | #if LANG_RUS //Pending Russian Translations |
||
298 | #define CHECKERS_CANT_OPEN_STR "\n誨: 䠩 \"%s\".\n" |
||
299 | #define CHECKERS_FILE_EMPTY_STR "\n誨: \"%s\" .\n" |
||
300 | |||
301 | #define FILE_WRONG_TYPE_STR "\n誨: \"%s\" ⨯.\n" |
||
4652 | ashmew2 | 302 | #define ERROR_OPENING_FILE_STR "\n誨: 訡 䠩 \"%s\".\n" |
303 | #define FILE_HAS_NO_GAMES_STR "\n誨: \"%s\" ᮤন .\n" |
||
304 | #define CANT_OPEN_FILE_STR "\n誨: 䠩 \"%s\" .\n" |
||
305 | #define CHECKERS_STR "誨" |
||
306 | #define FILE_SAVED_STR "\n誨: \"%s\" ࠭.\n" |
||
307 | #define ERROR_SAVING_FILE_STR "\n誨: 訡 ࠭ 䠩 \"%s\".\n" |
||
308 | #define NOT_ENOUGH_MEM_STR "\n誨: 筮 ࠭ 䠩 \"%s\".\n" |
||
309 | #define KIND_EQ2 "kind = 2\n" |
||
310 | #define END_STR "[end]" |
||
311 | #define PLAYV11_STR "[play_v1.1]" |
||
312 | #define CHECKERS_PLAY_STR "checkers-play:text\n" |
||
313 | #define CHECKERS_BIN_STR "checkers-play:bin_1.0\n" |
||
314 | #define BLUE_STR "blue: " |
||
315 | #define RED_STR "red: " |
||
316 | #define INPUT_STR "input" |
||
317 | #define COMPUTER_STR "computer" |
||
318 | #define NEW_GAME_STR "new game" |
||
319 | #define LIST_STR "list" |
||
320 | #define DELETE_STR "delete" |
||
321 | #define CLEAR_STR "clear" |
||
322 | #define SAVE_STR "save" |
||
323 | #define ROTATE_BOARD_STR "rotate board" |
||
324 | #define EXIT_STR "exit" |
||
325 | #define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n" |
||
326 | |||
327 | const char *const TPlayArray::search[] = |
||
328 | {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"}; |
||
329 | |||
330 | #else /*For all other languages except RUS*/ |
||
331 | |||
1805 | yogev_ezra | 332 | #define CHECKERS_FILE_EMPTY_STR "\nCheckers: The file \"%s\" is empty.\n" |
4652 | ashmew2 | 333 | #define CHECKERS_INVALID_FILE_STR "\nCheckers: Invalid file \"%s\".\n" |
334 | |||
335 | #define ERROR_OPENING_FILE_STR "\nCheckers: Error opening the file \"%s\".\n" |
||
336 | #define FILE_HAS_NO_GAMES_STR "\nCheckers: File \"%s\" doesn't contain games.\n" |
||
337 | #define CANT_OPEN_FILE_STR "\nCheckers: Can't open the file \"%s\" to write.\n" |
||
338 | #define NOT_ENOUGH_MEM_STR "\nCheckers: Not enough memory to save the file \"%s\".\n" |
||
339 | #define ERROR_SAVING_FILE_STR "\nCheckers: Error saving the file \"%s\".\n" |
||
340 | #define FILE_SAVED_STR "\nCheckers: File \"%s\" saved.\n" |
||
341 | #define CHECKERS_STR "Checkers" |
||
342 | #define KIND_EQ2 "kind = 2\n" |
||
343 | #define END_STR "[end]" |
||
344 | #define PLAYV11_STR "[Play_v1.1]" |
||
345 | #define CHECKERS_PLAY_STR "checkers-play:text\n" |
||
346 | #define CHECKERS_BIN_STR "checkers-play:bin_1.0\n" |
||
347 | #define BLUE_STR "blue: " |
||
348 | #define RED_STR "red: " |
||
349 | #define INPUT_STR "input" |
||
350 | #define COMPUTER_STR "computer" |
||
351 | #define NEW_GAME_STR "new game" |
||
352 | #define LIST_STR "list" |
||
353 | #define DELETE_STR "delete" |
||
354 | #define CLEAR_STR "clear" |
||
355 | #define SAVE_STR "save" |
||
356 | #define ROTATE_BOARD_STR "rotate board" |
||
357 | #define EXIT_STR "exit" |
||
358 | #define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n" |
||
359 | const char *const TPlayArray::search[] = |
||
360 | {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"}; |
||
361 | |||
362 | #endif |
||
363 | #endif |
||
364 | void TPlayArray::Clear() |
||
1805 | yogev_ezra | 365 | { |
4652 | ashmew2 | 366 | |
1805 | yogev_ezra | 367 | play = 0; nplay = 0; mplay = 0; |
4652 | ashmew2 | 368 | } |
1805 | yogev_ezra | 369 | |
370 | void TPlayArray::Extend(int n) |
||
371 | { |
||
372 | if (n < 0) n = nplay + 1; |
||
373 | if (mplay < n) |
||
374 | |||
375 | PlayWrite *p_old = play; |
||
376 | int m_old = mplay; |
||
377 | mplay = n * 2; |
||
378 | play = new PlayWrite[mplay]; |
||
379 | if (p_old) |
||
380 | { |
||
381 | for (int i = 0; i < m_old; i++) play[i] = p_old[i]; |
||
382 | delete[] p_old; |
||
383 | } |
||
384 | } |
||
385 | } |
||
386 | |||
387 | void TPlayArray::Add(const PlayWrite &pl) |
||
388 | { |
||
389 | Extend(); |
||
390 | play[nplay] = pl; |
||
391 | |||
392 | } |
||
393 | |||
394 | #ifndef __MENUET__ |
||
395 | int TPlayArray::AnalizeKind(FILE *f, const int w[], const char *smb) |
||
396 | { |
||
397 | int i, L, was1 = 1; |
||
398 | |||
399 | int fnd[NELEM(search)]; |
||
400 | for (i = 0; i < NELEM(search); i++) fnd[i] = 1; |
||
401 | for (L = 0; was1; L++) |
||
402 | { |
||
403 | was1 = 0; |
||
404 | if (fread(&ch, 1, 1, f) != 1) return (L == 0) ? -2 : -1; |
||
405 | for (i = 0; w[i] >= 0; i++) if (fnd[i]) |
||
406 | { |
||
407 | if (tolower(ch) != tolower(search[w[i]][L])) fnd[i] = 0; |
||
408 | else |
||
409 | { |
||
410 | was1 = 1; |
||
411 | if (search[w[i]][L+1] == 0) |
||
412 | { |
||
413 | if (smb && smb[0] && fread(&ch, 1, 1, f) == 1) |
||
414 | { |
||
415 | ungetc(ch, f); |
||
416 | if (strchr(smb, tolower(ch)) || isalpha(ch) && strchr(smb, toupper(ch))) |
||
417 | { |
||
418 | break; |
||
419 | } |
||
420 | } |
||
421 | return i; |
||
422 | } |
||
423 | } |
||
424 | } |
||
425 | } |
||
426 | return -10 - L; |
||
427 | } |
||
428 | |||
429 | int TPlayArray::ReadFileTo(FILE *f, char c) |
||
430 | { |
||
431 | char ch; |
||
432 | do |
||
433 | |||
434 | if (fread(&ch, 1, 1, f) != 1) return 0; |
||
435 | } |
||
436 | while(ch != c); |
||
437 | return 1; |
||
438 | } |
||
439 | |||
440 | int TPlayArray::ReadFileTo(FILE *f, const char *c) |
||
441 | { |
||
442 | char ch; |
||
443 | do |
||
444 | |||
445 | if (fread(&ch, 1, 1, f) != 1) return 0; |
||
446 | } |
||
447 | while(!strchr(c, ch)); |
||
448 | return 1; |
||
449 | } |
||
450 | |||
451 | int TPlayArray::ReadTheText(FILE *f, const char *s) |
||
452 | { |
||
453 | char ch; |
||
454 | while (*s) |
||
455 | |||
456 | if (fread(&ch, 1, 1, f) != 1 || ch != *s) return 0; |
||
457 | s++; |
||
458 | } |
||
459 | return 1; |
||
460 | } |
||
461 | |||
462 | int TPlayArray::OpenFile(const char *name, int kind) |
||
463 | { |
||
464 | int k_fnd = 0; |
||
465 | FILE *f = fopen(name, "rb"); |
||
466 | |||
467 | if (kind == -1) |
||
468 | { |
||
469 | const int w[] = {0, -1}; |
||
470 | int r = AnalizeKind(f, w); |
||
471 | if (r >= 0) {kind = w[r]; k_fnd = 1;} |
||
472 | else if (r == -11) {kind = 3; k_fnd = 3;} |
||
473 | else {fclose(f); return (kind == -2) ? -2 : -10;} |
||
474 | } |
||
475 | if (kind == 0) |
||
476 | { |
||
477 | if (k_fnd < 1 && !ReadFileTo(f, '-')) {fclose(f); return -10;} |
||
478 | k_fnd = 1; |
||
479 | const int w[] = {1, 4, -1}; |
||
480 | int r = AnalizeKind(f, w); |
||
481 | if (r >= 0) {kind = w[r]; k_fnd = 2;} |
||
482 | else {fclose(f); return -10;} |
||
483 | } |
||
484 | if (kind == 1) |
||
485 | { |
||
486 | if (k_fnd < 2 && !ReadFileTo(f, ':')) {fclose(f); return -10;} |
||
487 | k_fnd = 2; |
||
488 | const int w[] = {2, 3, -1}; |
||
489 | int r = AnalizeKind(f, w); |
||
490 | if (r >= 0) {kind = w[r]; k_fnd = 3;} |
||
491 | else {fclose(f); return -10;} |
||
492 | } |
||
493 | if (kind == 4) |
||
494 | { |
||
495 | if (k_fnd < 2 && !ReadFileTo(f, '_')) {fclose(f); return -10;} |
||
496 | k_fnd = 2; |
||
497 | const int w[] = {5, 6, -1}; |
||
498 | int r = AnalizeKind(f, w, ".1234567890"); |
||
499 | if (r >= 0) {kind = w[r]; k_fnd = 3;} |
||
500 | else {fclose(f); return -10;} |
||
501 | } |
||
502 | if (kind == 5) {kind = 3; k_fnd = 0;} |
||
503 | if (kind == 6) |
||
504 | { |
||
505 | if (!ReadFileTo(f, "\n\r")) {fclose(f); return -4;} |
||
506 | k_fnd = 3; |
||
507 | PlayWrite *pl = 0; |
||
508 | int np = THistory::HRead(f, pl); |
||
509 | if (np > 0 && pl) |
||
510 | { |
||
511 | int i; |
||
512 | Extend(nplay + np); |
||
513 | for (i = 0; i < np; i++) |
||
514 | { |
||
515 | if (pl[i].GetN() >= 3) play[nplay++] = pl[i]; |
||
516 | } |
||
517 | } |
||
518 | if (pl) delete[] pl; |
||
519 | fclose(f); |
||
520 | return 1; |
||
521 | } |
||
522 | if (kind == 2) |
||
523 | { |
||
524 | printf(KIND_EQ2); |
||
525 | unsigned char ch; |
||
526 | do |
||
527 | { |
||
528 | if (fread(&ch, 1, 1, f) != 1) {fclose(f); return -10;} |
||
4652 | ashmew2 | 529 | } |
1805 | yogev_ezra | 530 | while(!isspace(ch)); |
531 | PlayWrite pl; |
||
532 | char word[101]; |
||
533 | int i, kind = 0; |
||
534 | for (;;) |
||
535 | { |
||
536 | do |
||
537 | { |
||
538 | if (fread(&ch, 1, 1, f) != 1) break; |
||
539 | } |
||
540 | while(ch == 0 || isspace(ch)); |
||
541 | if (feof(f)) strcpy(word, END_STR); |
||
542 | else |
||
543 | { |
||
544 | i = 0; |
||
545 | while(ch != 0 && !isspace(ch)) |
||
4652 | ashmew2 | 546 | { |
1805 | yogev_ezra | 547 | if (i < 100) word[i++] = ch; |
548 | if (fread(&ch, 1, 1, f) != 1) break; |
||
549 | } |
||
550 | word[i] = 0; |
||
551 | } |
||
552 | if (word[0] != '[') |
||
553 | { |
||
554 | if (kind == 1) |
||
555 | { |
||
556 | if (word[0] != '#' && word[0] != '$' && word[0] != '%') |
||
557 | { |
||
558 | Position pos; |
||
559 | pos.Read(word, 1); |
||
560 | pl.Clear(); |
||
561 | pl.Add(0, pos); |
||
562 | kind = 2; |
||
563 | } |
||
564 | } |
||
565 | else if (kind == 2) |
||
566 | { |
||
567 | if (word[0] != '#' && word[0] != '$' && word[0] != '%') |
||
568 | { |
||
569 | for (i = 0; word[i] && word[i] != '.' && word[i] != ','; i++) |
||
570 | { |
||
571 | if (!isdigit((unsigned char)word[i])) {i = -1; break;} |
||
572 | } |
||
573 | if (i == -1) |
||
574 | { |
||
575 | PlayWrite::PMv pmv; |
||
576 | if (pl.GetPosL(pmv.pos) < 0) kind = 3; |
||
577 | else if (!pmv.pos.ReadMv(pmv.mv, word, 1)) kind = 3; |
||
578 | else if (pl.Add(pmv.mv) != 0) kind = 3; |
||
579 | } |
||
580 | } |
||
581 | } |
||
582 | } |
||
583 | else |
||
584 | { |
||
585 | char end_literal[] = END_STR; |
||
586 | char playv11_literal[] = PLAYV11_STR; |
||
587 | |||
588 | if (kind == 2 || kind == 3) |
||
589 | { |
||
4652 | ashmew2 | 590 | if (pl.GetN() > 0) Add(pl); |
591 | pl.Clear(); |
||
592 | |||
1805 | yogev_ezra | 593 | kind = 0; |
594 | for (i = 0; word[i]; i++) |
||
595 | { |
||
596 | word[i] = (char)tolower((unsigned char)word[i]); |
||
597 | } |
||
598 | if (strskipref(word, end_literal)) break; |
||
599 | else if (strskipref(word, playv11_literal)) kind = 1; |
||
600 | } |
||
601 | } |
||
602 | fclose(f); |
||
4652 | ashmew2 | 603 | return 1; |
604 | } |
||
1805 | yogev_ezra | 605 | if (kind == 3) |
606 | { |
||
607 | char ch[LEN_WPOS]; |
||
608 | if (k_fnd < 3 && !ReadFileTo(f, '\n')) {fclose(f); return -10;} |
||
609 | k_fnd = 3; |
||
610 | do |
||
611 | { |
||
612 | PlayWrite pl; |
||
613 | for (;;) |
||
614 | { |
||
615 | int i; |
||
616 | for (i = 0; i < LEN_WPOS; i++) |
||
617 | { |
||
618 | if (fread(ch + i, 1, 1, f) != 1 || ch[i] < 0) break; |
||
619 | } |
||
620 | if (i < LEN_WPOS) break; |
||
621 | PlayWrite::PMv pmv0, pmv1; |
||
622 | pmv1.pos.Read(ch); |
||
623 | pmv1.pos.Reverse(); |
||
624 | if (pl.GetPMvL(pmv0) >= 0) |
||
625 | { |
||
626 | TComputerPlayer::Z z; |
||
627 | z.FindAllMoves(pmv0); |
||
628 | int r; |
||
629 | for (r = 0; r < z.narr; r++) |
||
630 | { |
||
631 | if (memcmp(z.array[r].pos.SH, pmv1.pos.SH, sizeof(pmv1.pos.SH)) == 0) |
||
632 | { |
||
633 | pmv1 = z.array[r]; |
||
634 | break; |
||
635 | } |
||
636 | } |
||
637 | if (r < z.narr) pl.Add(pmv1); |
||
638 | else {fclose(f); return -3;} |
||
639 | } |
||
640 | else pl.Add(0, pmv1.pos); |
||
641 | } |
||
642 | if (pl.GetN() > 0) Add(pl); |
||
643 | } |
||
644 | while(!feof(f)); |
||
645 | fclose(f); |
||
646 | return 1; |
||
647 | } |
||
648 | fclose(f); |
||
649 | return -10; |
||
650 | } |
||
651 | |||
652 | int TPlayArray::MsgOpenFile(const char *name, int kind) |
||
653 | { |
||
654 | int n0 = nplay, no_games = 0; |
||
655 | int r = OpenFile(name, kind); |
||
656 | |||
657 | { |
||
658 | if (r == -1) |
||
659 | { |
||
660 | printf(CHECKERS_CANT_OPEN_STR, name); |
||
661 | return 0; |
||
662 | } |
||
663 | else if (r == -2) |
||
664 | { |
||
4652 | ashmew2 | 665 | printf(CHECKERS_FILE_EMPTY_STR, name); |
1805 | yogev_ezra | 666 | return 0; |
667 | } |
||
668 | else if (r == -3) |
||
669 | { |
||
4652 | ashmew2 | 670 | printf(CHECKERS_INVALID_FILE_STR, name); |
1805 | yogev_ezra | 671 | return 0; |
672 | } |
||
673 | else if (r == -4) no_games = 1; |
||
674 | else if (r == -10) |
||
4652 | ashmew2 | 675 | { |
1805 | yogev_ezra | 676 | printf(FILE_WRONG_TYPE_STR, name); |
677 | return 0; |
||
678 | } |
||
679 | else |
||
680 | { |
||
4652 | ashmew2 | 681 | printf(ERROR_OPENING_FILE_STR, name); |
1805 | yogev_ezra | 682 | return 0; |
683 | } |
||
684 | } |
||
685 | if (!no_games && nplay > n0) return 1; |
||
4652 | ashmew2 | 686 | else |
1805 | yogev_ezra | 687 | { |
688 | printf(FILE_HAS_NO_GAMES_STR, name); |
||
689 | return 0; |
||
690 | } |
||
691 | } |
||
692 | |||
4652 | ashmew2 | 693 | int TPlayArray::SaveFile(const char *name, int num, int kind) |
1805 | yogev_ezra | 694 | { |
695 | FILE *f = 0; |
||
696 | if (kind == 0 || kind == 1 || kind == 2) |
||
697 | |||
698 | f = fopen(name, "wt"); |
||
699 | if (!f) return -1; |
||
700 | |||
701 | fprintf(f, CHECKERS_PLAY_STR); |
||
702 | int i0 = num, i; |
||
703 | if (num < 0) {i0 = 0; num = nplay-1;} |
||
704 | for (i = i0; i <= num; i++) if (play[i].GetN() > 0) |
||
4652 | ashmew2 | 705 | |
706 | PlayWrite::PMv pmv; |
||
1805 | yogev_ezra | 707 | if (play[i].GetPos(pmv.pos, 0) < 0) return -9; |
708 | char *str = new char[10 + NUM_CELL]; |
||
709 | if (!str) return -5; |
||
710 | pmv.pos.Write(str, 1); |
||
711 | fprintf(f, "\n"PLAYV11_STR"#%d %s\n", i - i0 + 1, str); |
||
712 | delete[] str; |
||
713 | int j; |
||
714 | for (j = 1; j < play[i].GetN(); j++) |
||
715 | { |
||
4652 | ashmew2 | 716 | if (play[i].GetPos(pmv.pos, j - 1) < 0) return -9; |
1805 | yogev_ezra | 717 | if (play[i].GetMove(pmv.mv, j) < 0) return -9; |
718 | str = new char[pmv.pos.GetLenMvEx(pmv.mv, 11)]; |
||
719 | if (!str) return -5; |
||
720 | pmv.pos.WriteMvEx(pmv.mv, str, 11); |
||
721 | if (j % 2 == 1) |
||
722 | { |
||
723 | int nbytes = fprintf(f, "%d. ", (j + 1) / 2); |
||
724 | while(nbytes++ < 5) fprintf(f, " "); |
||
725 | } |
||
726 | fprintf(f, "%s", str); |
||
727 | if (j % 2 == 0 || j == play[i].GetN() - 1) fprintf(f, "\n"); |
||
728 | else fprintf(f, " ,\t"); |
||
729 | delete[] str; |
||
730 | } |
||
731 | } |
||
732 | fclose(f); |
||
733 | return 1; |
||
734 | } |
||
735 | else if (kind == -1 || kind == 3) |
||
736 | { |
||
737 | f = fopen(name, "wb"); |
||
738 | if (!f) return -1; |
||
739 | if (kind == 3) fprintf(f, CHECKERS_BIN_STR); |
||
740 | |||
741 | int i = num; |
||
742 | if (num < 0) {i = 0; num = nplay-1;} |
||
743 | for (; i <= num; i++) |
||
4652 | ashmew2 | 744 | { |
745 | |||
1805 | yogev_ezra | 746 | Position pos; |
747 | play[i].GetPosL(pos); |
||
748 | if (!pos.AllCanEat() && !pos.AllCanMove()) |
||
749 | { |
||
750 | ch[0] = (pos.wmove == 0) ? char(-3) : char(-1); |
||
751 | } |
||
752 | else ch[0] = char(-2); |
||
753 | fwrite(ch, 1, 1, f); |
||
754 | int j; |
||
755 | for (j = 0; j < play[i].GetN(); j++) |
||
756 | { |
||
757 | Position pos; |
||
758 | play[i].GetPos(pos, j); |
||
759 | pos.Reverse(); |
||
760 | pos.Write(ch); |
||
761 | fwrite(ch, LEN_WPOS, 1, f); |
||
762 | } |
||
763 | } |
||
764 | fclose(f); |
||
765 | return 1; |
||
766 | } |
||
767 | if (f) fclose(f); |
||
768 | return -10; |
||
769 | } |
||
770 | |||
771 | int TPlayArray::MsgSaveFile(const char *name, int num, int kind) |
||
772 | { |
||
773 | int r = SaveFile(name, num, kind); |
||
774 | if (r <= 0) |
||
775 | |||
776 | if (r == -1) |
||
777 | { |
||
778 | printf(CANT_OPEN_FILE_STR, name); |
||
779 | } |
||
780 | else if (r == -5) |
||
781 | { |
||
782 | printf(NOT_ENOUGH_MEM_STR, name); |
||
4652 | ashmew2 | 783 | } |
1805 | yogev_ezra | 784 | else if (r == -10) |
785 | { |
||
786 | printf(FILE_WRONG_TYPE_STR, name); |
||
4652 | ashmew2 | 787 | } |
1805 | yogev_ezra | 788 | else |
789 | { |
||
790 | printf(ERROR_SAVING_FILE_STR, name); |
||
4652 | ashmew2 | 791 | } |
1805 | yogev_ezra | 792 | return 0; |
793 | } |
||
794 | else |
||
4652 | ashmew2 | 795 | { |
1805 | yogev_ezra | 796 | printf(FILE_SAVED_STR, name); |
797 | return 1; |
||
798 | } |
||
799 | } |
||
800 | #endif |
||
4652 | ashmew2 | 801 | |
1805 | yogev_ezra | 802 | void TPlayArray::Del(int n) |
803 | { |
||
804 | if (!play || n < 0 || n >= nplay) return; |
||
805 | else if (nplay <= 1) {Clear(); return;} |
||
806 | |||
807 | for (i = n; i < nplay - 1; i++) play[i] = play[i+1]; |
||
808 | play[nplay - 1].Clear(); |
||
809 | nplay--; |
||
810 | } |
||
811 | |||
812 | |||
813 | void SetPlayerString(char *str, int c, TChPlayer *p) |
||
814 | { |
||
815 | strcpy(str, c ? BLUE_STR : RED_STR); |
||
816 | |||
817 | |||
818 | } |
||
819 | |||
4652 | ashmew2 | 820 | class TMainDraw : public TSomeDraw |
821 | { |
||
822 | public: |
||
1805 | yogev_ezra | 823 | |
824 | |||
825 | def_savefile("save.che"), def_savekind(2) {InitButton();} |
||
826 | |||
827 | virtual void Draw(TGraphDraw *drw, int w, int h) |
||
4652 | ashmew2 | 828 | |
1805 | yogev_ezra | 829 | int d = button.GetDelt(); |
830 | int hh = button.GetHeight(w - 2*d); |
||
4652 | ashmew2 | 831 | |
1805 | yogev_ezra | 832 | drw->SetColor(drw->GetBlackColor()); |
833 | button.Draw(drw, d, h - hh, w - 2*d); |
||
834 | } |
||
835 | |||
836 | virtual void DrawB(TGraphDraw *drw, TChBoard &board) |
||
837 | { |
||
838 | int urt = (board.GetCurMoveN() <= 0) + |
||
839 | 2*(board.GetCurMoveN() >= board.GetNumMove()); |
||
840 | |||
841 | Draw(drw, board.GetW(), board.GetH()); |
||
842 | } |
||
843 | |||
844 | virtual TIntPoint GetDSize(int w, int h) |
||
845 | { |
||
846 | int d = button.GetDelt(); |
||
847 | int hh = button.GetHeight(w - 2*d); |
||
848 | |||
849 | return TIntPoint(0, hh); |
||
850 | } |
||
851 | |||
852 | virtual int ButtonPnt(int xp, int yp, int w, int h, int &n, int k = 0) |
||
853 | { |
||
854 | int d = button.GetDelt(); |
||
855 | int hh = button.GetHeight(w - 2*d); |
||
856 | |||
857 | return button.ButtonPnt(xp - d, yp - (h - hh), w - 2*d, n, k); |
||
858 | } |
||
859 | |||
860 | void InitButton(); |
||
861 | void SetButtonKind(const TChBoard &board); |
||
862 | void PressUR(int n, TChBoard &board, TGraphDraw *drw); |
||
863 | void PressLS(int n, TChBoard &board, TGraphDraw *drw); |
||
864 | |||
865 | { |
||
866 | if (cur_play < 0 || cur_play >= play.GetNPlay()) cur_play = 0; |
||
867 | } |
||
868 | |||
869 | TXButtonArray button; |
||
870 | TMultiButton *undo_redo, *play_list; |
||
871 | char player_str[2][50], play_num[2][10]; |
||
872 | TPlayArray play; |
||
873 | |||
874 | char *def_savefile; |
||
875 | int def_savekind; |
||
876 | protected: |
||
877 | int ur_type; |
||
878 | }; |
||
879 | |||
880 | void TMainDraw::InitButton() |
||
881 | { |
||
882 | char newgame_literal[] = NEW_GAME_STR; |
||
883 | char list_literal[] = LIST_STR; |
||
884 | |||
885 | char clear_literal[] = CLEAR_STR; |
||
886 | char save_literal[] = SAVE_STR; |
||
4652 | ashmew2 | 887 | char rotateboard_literal[] = ROTATE_BOARD_STR; |
888 | char exit_literal[] = EXIT_STR; |
||
889 | |||
890 | char one_literal[] = "1"; |
||
891 | char dash_literal[] = "-"; |
||
892 | char plus_literal[] = "+"; |
||
893 | char leftshift_literal[] = "<<"; |
||
894 | |||
895 | char lessthan_literal[] = "<"; |
||
896 | char greaterthan_literal[] = ">"; |
||
897 | char xor_literal[] = "^"; |
||
898 | |||
899 | button.Add(1, 80, 22, newgame_literal); |
||
900 | button.Add(6, 60, 22, list_literal); |
||
901 | button.Add(7, 60, 22, delete_literal); |
||
902 | play_list = new TMultiButton(20); |
||
903 | |||
904 | play_list->a.Add(21, 20, 22, dash_literal); |
||
905 | play_list->a.Add(23, 37, 22, play_num[0], -2); |
||
906 | play_list->a.Add(22, 20, 22, plus_literal); |
||
1805 | yogev_ezra | 907 | play_list->a.Add(27, 37, 22, play_num[1]); |
4652 | ashmew2 | 908 | play_list->SetDefW(); |
909 | button.Add(play_list); |
||
1805 | yogev_ezra | 910 | button.Add(24, 50, 22, clear_literal); |
4652 | ashmew2 | 911 | #ifndef __MENUET__ |
1805 | yogev_ezra | 912 | button.Add(25, 50, 22, save_literal); |
913 | #endif |
||
914 | button.Add(2, 120, 22, player_str[0]); |
||
4652 | ashmew2 | 915 | button.Add(3, 120, 22, player_str[1]); |
1805 | yogev_ezra | 916 | button.Add(4, 110, 22, rotateboard_literal); |
4652 | ashmew2 | 917 | undo_redo = new TMultiButton(10); |
1805 | yogev_ezra | 918 | undo_redo->a.Add(11, 27, 22, leftshift_literal); |
919 | undo_redo->a.Add(12, 20, 22, lessthan_literal); |
||
920 | undo_redo->a.Add(15, 20, 22, xor_literal); |
||
4652 | ashmew2 | 921 | undo_redo->a.Add(13, 20, 22, greaterthan_literal); |
1805 | yogev_ezra | 922 | undo_redo->a.Add(14, 27, 22, rightshift_literal); |
4652 | ashmew2 | 923 | undo_redo->SetDefW(); |
924 | button.Add(undo_redo); |
||
925 | button.Add(5, 60, 22, exit_literal); |
||
926 | } |
||
927 | |||
1805 | yogev_ezra | 928 | void TMainDraw::SetButtonKind(const TChBoard &board) |
929 | { |
||
4652 | ashmew2 | 930 | int thick; |
1805 | yogev_ezra | 931 | TextButton *txb; |
932 | |||
933 | ur_type = 0; |
||
934 | SetPlayerString(player_str[0], 0, board.GetPlayer(0)); |
||
935 | SetPlayerString(player_str[1], 1, board.GetPlayer(1)); |
||
936 | int is_drw = !board.GetPViewStatus(); |
||
937 | bt1 = button.GetButton(2); |
||
938 | if (bt1) bt1->drw = is_drw; |
||
939 | bt1 = button.GetButton(3); |
||
940 | if (bt1) bt1->drw = is_drw; |
||
941 | if (board.GetCurMoveN() <= 0) {ur_type++; thick = 0;} |
||
942 | else thick = 3; |
||
943 | // txb = dynamic_cast |
||
944 | // if (txb) txb->thick = thick; |
||
945 | // txb = dynamic_cast |
||
946 | // if (txb) txb->thick = thick; |
||
947 | // we can use simple static cast |
||
948 | ((TextButton*)(undo_redo->a.GetButton(11)))->thick = thick; |
||
949 | ((TextButton*)(undo_redo->a.GetButton(12)))->thick = thick; |
||
950 | if (board.GetCurMoveN() >= board.GetNumMove()) {ur_type += 2; thick = 0;} |
||
951 | else thick = 3; |
||
952 | // txb = dynamic_cast |
||
953 | // if (txb) txb->thick = thick; |
||
954 | // txb = dynamic_cast |
||
955 | // if (txb) txb->thick = thick; |
||
956 | ((TextButton*)(undo_redo->a.GetButton(13)))->thick = thick; |
||
957 | ((TextButton*)(undo_redo->a.GetButton(14)))->thick = thick; |
||
958 | if (board.GetCurMoveN() < board.GetNumMove() || |
||
959 | (board.GetPViewStatus() && board.GetGameEnd() <= 0)) |
||
960 | { |
||
961 | thick = 3; |
||
962 | } |
||
963 | else thick = 0; |
||
964 | // txb = dynamic_cast |
||
965 | // if (txb) txb->thick = thick; |
||
966 | ((TextButton*)(undo_redo->a.GetButton(15)))->thick = thick; |
||
967 | if (play.GetNPlay() == 0) is_drw = 1; |
||
968 | bt1 = button.GetButton(6); |
||
969 | if (bt1) bt1->drw = is_drw; |
||
970 | bt1 = button.GetButton(7); |
||
971 | if (bt1) bt1->drw = !is_drw; |
||
972 | #ifndef __MENUET__ |
||
973 | bt1 = button.GetButton(25); |
||
974 | if (bt1) bt1->drw = !is_drw; |
||
975 | #endif |
||
976 | is_drw = board.GetPViewStatus() && play.GetNPlay() > 1; |
||
977 | bt1 = button.GetButton(20); |
||
978 | if (bt1) bt1->drw = is_drw; |
||
979 | bt1 = button.GetButton(24); |
||
980 | if (bt1) bt1->drw = is_drw; |
||
981 | if (is_drw) |
||
982 | { |
||
983 | play_num[0][0] = 0; play_num[1][0] = 0; |
||
984 | if (cur_play >= 0) sprintf(play_num[0], "%d", cur_play + 1); |
||
985 | sprintf(play_num[1], "%d", play.GetNPlay()); |
||
986 | thick = (cur_play <= 0) ? 0 : 3; |
||
987 | #define dynamic_cast static_cast |
||
988 | txb = dynamic_cast |
||
989 | if (txb) txb->thick = thick; |
||
990 | txb = dynamic_cast |
||
991 | if (txb) txb->thick = thick; |
||
992 | thick = (cur_play >= play.GetNPlay() - 1) ? 0 : 3; |
||
993 | txb = dynamic_cast |
||
994 | if (txb) txb->thick = thick; |
||
995 | txb = dynamic_cast |
||
996 | if (txb) txb->thick = thick; |
||
997 | #undef dynamic_cast |
||
998 | } |
||
999 | } |
||
1000 | |||
1001 | void TMainDraw::PressUR(int n, TChBoard &board, TGraphDraw *drw) |
||
1002 | { |
||
1003 | int mv; |
||
1004 | if (n == 11) mv = 0; |
||
1005 | |||
1006 | else if (n == 13) mv = board.GetCurMoveN() + 1; |
||
1007 | else mv = board.GetNumMove(); |
||
1008 | if (board.SetCurMoveN(mv)) |
||
1009 | { |
||
1010 | SetButtonKind(board); |
||
1011 | if (drw && drw->IsDraw()) |
||
1012 | { |
||
1013 | drw->DrawClear(); |
||
1014 | board.Draw(drw); |
||
1015 | } |
||
1016 | } |
||
1017 | else Draw(drw, board.GetW(), board.GetH()); |
||
1018 | } |
||
1019 | |||
1020 | void TMainDraw::PressLS(int n, TChBoard &board, TGraphDraw *drw) |
||
1021 | { |
||
1022 | int need_redraw = 0; |
||
1023 | if (n == 6) |
||
1024 | |||
1025 | if (!board.GetPViewStatus() || play.GetNPlay() == 0) |
||
1026 | { |
||
1027 | PlayWrite cur_pw = board.GetPlay(); |
||
1028 | if (cur_pw.GetN() > 2 || play.GetNPlay() == 0) play.Add(board.GetPlay()); |
||
1029 | cur_play = play.GetNPlay() - 1; |
||
1030 | board.SetPlay(play[cur_play]); |
||
1031 | need_redraw = 1; |
||
1032 | } |
||
1033 | } |
||
1034 | else if (n == 7) |
||
1035 | { |
||
1036 | if (board.GetPViewStatus() && play.GetNPlay() != 0) |
||
1037 | { |
||
1038 | play.Del(cur_play); |
||
1039 | if (play.GetNPlay() >= 1) |
||
1040 | { |
||
1041 | if (cur_play >= play.GetNPlay()) cur_play--; |
||
1042 | board.SetPlay(play[cur_play]); |
||
1043 | } |
||
1044 | need_redraw = 1; |
||
1045 | } |
||
1046 | } |
||
1047 | else if (n == 21) |
||
1048 | { |
||
1049 | if (cur_play > 0) {board.SetPlay(play[--cur_play]); need_redraw = 1;} |
||
1050 | } |
||
1051 | else if (n == 22) |
||
1052 | { |
||
1053 | if (cur_play < play.GetNPlay() - 1) |
||
1054 | { |
||
1055 | board.SetPlay(play[++cur_play]); need_redraw = 1; |
||
1056 | } |
||
1057 | } |
||
1058 | else if (n == 26) |
||
1059 | { |
||
1060 | if (cur_play > 0) |
||
1061 | { |
||
1062 | cur_play = 0; |
||
1063 | board.SetPlay(play[cur_play]); need_redraw = 1; |
||
1064 | } |
||
1065 | } |
||
1066 | else if (n == 27) |
||
1067 | { |
||
1068 | if (cur_play < play.GetNPlay() - 1) |
||
1069 | { |
||
1070 | cur_play = play.GetNPlay() - 1; |
||
1071 | board.SetPlay(play[cur_play]); need_redraw = 1; |
||
1072 | } |
||
1073 | } |
||
1074 | else if (n == 24) {play.Clear(); cur_play = 0; need_redraw = 1;} |
||
1075 | #ifndef __MENUET__ |
||
1076 | else if (n == 25) |
||
1077 | { |
||
1078 | if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, -1, def_savekind); |
||
1079 | } |
||
1080 | else if (n == 28) |
||
1081 | { |
||
1082 | if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, cur_play, def_savekind); |
||
1083 | } |
||
1084 | #endif |
||
1085 | if (need_redraw) |
||
1086 | { |
||
1087 | SetButtonKind(board); |
||
1088 | if (drw && drw->IsDraw()) |
||
1089 | { |
||
1090 | drw->DrawClear(); |
||
1091 | board.Draw(drw); |
||
1092 | } |
||
1093 | } |
||
1094 | else Draw(drw, board.GetW(), board.GetH()); |
||
1095 | } |
||
1096 | |||
1097 | struct TTimerDraw |
||
1098 | { |
||
1099 | TTimerDraw(TChBoard *brd, TGraphDraw *drw) : brd(brd), drw(drw) {} |
||
1100 | |||
1101 | |||
1102 | clock_t st, ut, dt; |
||
1103 | double x0; |
||
1104 | TGraphDraw *drw; |
||
1105 | |||
1106 | static void draw(void *v, int k = 0); |
||
1107 | }; |
||
1108 | |||
1109 | void TTimerDraw::draw(void *v, int k) |
||
1110 | |||
1111 | TTimerDraw &d = *(TTimerDraw*)v; |
||
1112 | clock_t t = clock(); |
||
1113 | |||
1114 | if (k > 0) |
||
1115 | { |
||
1116 | d.st = t; |
||
1117 | if (!d.drw || !d.drw->IsDraw()) return; |
||
1118 | d.drw->DrawClear(); |
||
1119 | d.brd->Draw(d.drw); |
||
1120 | d.dt = t; |
||
1121 | } |
||
1122 | else if (!d.drw || !d.drw->IsDraw()) return; |
||
1123 | double xold = d.x0; |
||
1124 | if (k >= 0) |
||
1125 | { |
||
1126 | d.x0 = (1 - cos(2.0 * (t - d.st) / CLOCKS_PER_SEC)) / 2; |
||
1127 | d.brd->DrawTimer(d.drw, d.x0, 0); |
||
1128 | d.ut = t; |
||
1129 | if (k == 0 && t - d.dt > CLOCKS_PER_SEC * 0.5) |
||
1130 | { |
||
1131 | d.brd->Draw(d.drw); |
||
1132 | d.dt = t; |
||
1133 | } |
||
1134 | } |
||
1135 | if (k <= 0) d.brd->DrawTimer(d.drw, xold, 1); |
||
1136 | } |
||
1137 | |||
1138 | |||
1139 | struct TMainData |
||
1140 | { |
||
1141 | TChBoard board; |
||
1142 | |||
1143 | |||
1144 | |||
1145 | TMainData(int id = 0); |
||
1146 | void InitDef(); |
||
1147 | static int EventFunction(const TGraphDraw::event &ev); |
||
1148 | void NewGame(TGraphDraw *drw); |
||
1149 | |||
1150 | void PlayerPress(int np, TGraphDraw *drw); |
||
1151 | void GoToCurMove(TGraphDraw *drw); |
||
1152 | }; |
||
1153 | |||
1154 | TMainData::TMainData(int id) : board(id) |
||
1155 | { |
||
1156 | board.SetCheckResize(1); |
||
1157 | board.SetPlayer(1, &player); |
||
1158 | |||
1159 | board.SetSomeDraw(&main_draw); |
||
1160 | board.SetMinWSize(90, 140); |
||
1161 | } |
||
1162 | |||
1163 | void TMainData::InitDef() |
||
1164 | { |
||
1165 | if (main_draw.play.GetNPlay() > 0) |
||
1166 | { |
||
1167 | |||
1168 | board.SetPlay(main_draw.play[main_draw.cur_play]); |
||
1169 | } |
||
1170 | main_draw.SetButtonKind(board); |
||
1171 | } |
||
1172 | |||
1173 | void TMainData::NewGame(TGraphDraw *drw) |
||
1174 | { |
||
1175 | board.NewGame(); |
||
1176 | main_draw.SetButtonKind(board); |
||
1177 | |||
1178 | } |
||
1179 | |||
1180 | void TMainData::RotateBoard(TGraphDraw *drw) |
||
1181 | { |
||
1182 | board.SetBottomColor(3 - board.GetBottomColor()); |
||
1183 | if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} |
||
1184 | |||
1185 | |||
1186 | void TMainData::PlayerPress(int np, TGraphDraw *drw) |
||
1187 | { |
||
1188 | if (np != 0 && np != 1) return; |
||
1189 | if (board.GetPlayer(np)) board.SetPlayer(np, 0); |
||
1190 | |||
1191 | if (board.GetPlayer(0) && !board.GetPlayer(1)) |
||
1192 | { |
||
1193 | board.SetBottomColor(1); |
||
1194 | } |
||
1195 | if (board.GetPlayer(1) && !board.GetPlayer(0)) |
||
1196 | { |
||
1197 | board.SetBottomColor(0); |
||
1198 | } |
||
1199 | main_draw.SetButtonKind(board); |
||
1200 | if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} |
||
1201 | } |
||
1202 | |||
1203 | void TMainData::GoToCurMove(TGraphDraw *drw) |
||
1204 | { |
||
1205 | board.GoToCurMove(); |
||
1206 | main_draw.SetButtonKind(board); |
||
1207 | |||
1208 | } |
||
1209 | |||
1210 | int TMainData::EventFunction(const TGraphDraw::event &ev) |
||
1211 | { |
||
1212 | if (!ev.any.drw->data) return -100; |
||
1213 | TMainData &data = *(TMainData*)ev.any.drw->data; |
||
1214 | |||
1215 | switch(ev.type) |
||
1216 | { |
||
1217 | case TGraphDraw::event::button_down: |
||
1218 | if (ev.button.n != 1) break; |
||
1219 | ev.button.drw->OpenDraw(); |
||
1220 | if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, |
||
1221 | data.board.GetW(), data.board.GetH(), nbutton, 1) > 0) |
||
1222 | { |
||
1223 | data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); |
||
1224 | ret |= TGraphDraw::ret_setcapture; |
||
1225 | } |
||
1226 | else data.board.MouseClick(ev.button.drw, ev.button.x, ev.button.y); |
||
1227 | ev.button.drw->CloseDraw(); |
||
1228 | break; |
||
1229 | case TGraphDraw::event::mouse_move: |
||
1230 | if (ev.button.n >= 0 && ev.button.n != 1) break; |
||
1231 | ev.button.drw->OpenDraw(); |
||
1232 | if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, |
||
1233 | data.board.GetW(), data.board.GetH(), nbutton, 2) >= 1000) |
||
1234 | { |
||
1235 | data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); |
||
1236 | } |
||
1237 | ev.button.drw->CloseDraw(); |
||
1238 | break; |
||
1239 | case TGraphDraw::event::button_up: |
||
1240 | if (ev.button.n != 1) break; |
||
1241 | ev.button.drw->OpenDraw(); |
||
1242 | if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, |
||
1243 | data.board.GetW(), data.board.GetH(), nbutton, 3) > 0) |
||
1244 | { |
||
1245 | switch(nbutton) |
||
1246 | { |
||
1247 | case 1: |
||
1248 | data.NewGame(ev.button.drw); |
||
1249 | break; |
||
1250 | case 2: |
||
1251 | case 3: |
||
1252 | data.PlayerPress(nbutton - 2, ev.button.drw); |
||
1253 | break; |
||
1254 | case 4: |
||
1255 | data.RotateBoard(ev.button.drw); |
||
1256 | break; |
||
1257 | case 5: |
||
1258 | data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); |
||
1259 | ev.button.drw->Quit(); |
||
1260 | break; |
||
1261 | case 11: |
||
1262 | case 12: |
||
1263 | case 13: |
||
1264 | case 14: |
||
1265 | data.main_draw.PressUR(nbutton, data.board, ev.button.drw); |
||
1266 | break; |
||
1267 | case 15: |
||
1268 | data.GoToCurMove(ev.button.drw); |
||
1269 | break; |
||
1270 | case 6: |
||
1271 | case 7: |
||
1272 | case 21: |
||
1273 | case 22: |
||
1274 | case 23: |
||
1275 | case 24: |
||
1276 | case 25: |
||
1277 | case 26: |
||
1278 | case 27: |
||
1279 | data.main_draw.PressLS(nbutton, data.board, ev.button.drw); |
||
1280 | break; |
||
1281 | default: |
||
1282 | data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); |
||
1283 | break; |
||
1284 | } |
||
1285 | } |
||
1286 | ev.button.drw->CloseDraw(); |
||
1287 | break; |
||
1288 | case TGraphDraw::event::draw: |
||
1289 | ev.button.drw->OpenDraw(); |
||
1290 | data.board.Draw(ev.button.drw); |
||
1291 | ev.button.drw->CloseDraw(); |
||
1292 | break; |
||
1293 | case TGraphDraw::event::key_down: |
||
1294 | ev.button.drw->OpenDraw(); |
||
1295 | if (ev.key.k == XK_Left) data.board.PKeyEvent(ev.button.drw, TChBoard::PLeft); |
||
1296 | else if (ev.key.k == XK_Right) data.board.PKeyEvent(ev.button.drw, TChBoard::PRight); |
||
1297 | else if (ev.key.k == XK_Up) data.board.PKeyEvent(ev.button.drw, TChBoard::PUp); |
||
1298 | else if (ev.key.k == XK_Down) data.board.PKeyEvent(ev.button.drw, TChBoard::PDown); |
||
1299 | else if (ev.key.k == XK_Return || ev.key.k == XK_space) |
||
1300 | { |
||
1301 | data.board.PKeyEvent(ev.button.drw, TChBoard::PEnter); |
||
1302 | } |
||
1303 | else if (ev.key.k == XK_Escape) ev.button.drw->Quit(); |
||
1304 | else if (ev.key.k == XK_less) data.main_draw.PressUR(11, data.board, ev.button.drw); |
||
1305 | else if (ev.key.k == XK_comma) data.main_draw.PressUR(12, data.board, ev.button.drw); |
||
1306 | else if (ev.key.k == XK_period) data.main_draw.PressUR(13, data.board, ev.button.drw); |
||
1307 | else if (ev.key.k == XK_greater) data.main_draw.PressUR(14, data.board, ev.button.drw); |
||
1308 | else if (ev.key.k == XK_minus) data.main_draw.PressLS(21, data.board, ev.button.drw); |
||
1309 | else if (ev.key.k == XK_equal) data.main_draw.PressLS(22, data.board, ev.button.drw); |
||
1310 | else if (ev.key.k == XK_underscore) data.main_draw.PressLS(26, data.board, ev.button.drw); |
||
1311 | else if (ev.key.k == XK_plus) data.main_draw.PressLS(27, data.board, ev.button.drw); |
||
1312 | else if (ev.key.k == XK_Delete) data.main_draw.PressLS(7, data.board, ev.button.drw); |
||
1313 | else if (ev.key.k == XK_F8) data.main_draw.PressLS(24, data.board, ev.button.drw); |
||
1314 | else if (ev.key.k == XK_l || ev.key.k == XK_L) data.main_draw.PressLS(6, data.board, ev.button.drw); |
||
1315 | #ifndef __MENUET__ |
||
1316 | else if (ev.key.k == XK_F2) data.main_draw.PressLS(25, data.board, ev.button.drw); |
||
1317 | #endif |
||
1318 | else if (ev.key.k == XK_s || ev.key.k == XK_S) data.main_draw.PressLS(28, data.board, ev.button.drw); |
||
1319 | else if (ev.key.k == XK_slash || ev.key.k == XK_question) data.GoToCurMove(ev.button.drw); |
||
1320 | else if (ev.key.k == XK_n || ev.key.k == XK_N) data.NewGame(ev.button.drw); |
||
1321 | else if (ev.key.k == XK_t || ev.key.k == XK_T) data.RotateBoard(ev.button.drw); |
||
1322 | else if (ev.key.k == XK_r || ev.key.k == XK_R) data.PlayerPress(0, ev.button.drw); |
||
1323 | else if (ev.key.k == XK_b || ev.key.k == XK_B) data.PlayerPress(1, ev.button.drw); |
||
1324 | else if (ev.key.k == XK_f || ev.key.k == XK_F) |
||
1325 | { |
||
1326 | int w, h; |
||
1327 | ev.button.drw->GetSize(w, h); |
||
1328 | ev.button.drw->CloseDraw(); |
||
1329 | if (DuplicateProcess() == 0) |
||
1330 | { |
||
1331 | ev.button.drw->ResReinit(w, h); |
||
1332 | data.board.EraseHistory(); |
||
1333 | } |
||
1334 | } |
||
1335 | ev.button.drw->CloseDraw(); |
||
1336 | break; |
||
1337 | case TGraphDraw::event::close: |
||
1338 | ret = 1; |
||
1339 | break; |
||
1340 | } |
||
1341 | return ret; |
||
1342 | } |
||
1343 | |||
1344 | #ifndef __MENUET__ |
||
1345 | int main(int argc, char **argv) |
||
1346 | { |
||
1347 | randomize(); |
||
1348 | |||
1349 | TMainData data(-1); |
||
1350 | if (argv && argc >= 2) |
||
1351 | { |
||
1352 | int i, kx = 1; |
||
1353 | for (i = 1; i < argc; i++) |
||
1354 | { |
||
1355 | if (kx == 1 && argv[i][0] == '-') |
||
1356 | { |
||
1357 | if (strcmp(argv[i], "--") == 0) kx = 0; |
||
1358 | else if (strcmp(argv[i], "-ssf") == 0) ssf = 1; |
||
1359 | else if (strncmp(argv[i], "-save", 5) == 0) |
||
1360 | { |
||
1361 | int j = 5; |
||
1362 | if (argv[i][j]) |
||
1363 | { |
||
1364 | if (argv[i][j] != '=' || !argv[i][j+1]) |
||
1365 | { |
||
1366 | data.main_draw.def_savekind = atoi(argv[i] + j); |
||
1367 | while (argv[i][j] && argv[i][j] != '=') j++; |
||
1368 | if (argv[i][j] != '=' || !argv[i][j+1]) continue; |
||
1369 | } |
||
1370 | data.main_draw.def_savefile = argv[i] + j + 1; |
||
1371 | } |
||
1372 | } |
||
1373 | |||
1374 | else printf(CHECKERS_INVALID_STR, argv[i]); |
||
1375 | } |
||
1376 | else if (kx == 0 || kx == 1) |
||
1377 | { |
||
4652 | ashmew2 | 1378 | |
1379 | } |
||
1805 | yogev_ezra | 1380 | } |
1381 | } |
||
1382 | data.InitDef(); |
||
1383 | TMainGraphDraw graph(CHECKERS_STR); |
||
1384 | TTimerDraw timer_draw(&data.board, &graph); |
||
1385 | data.player.draw = TTimerDraw::draw; data.player.data = &timer_draw; |
||
1386 | graph.evfunc = TMainData::EventFunction; graph.data = &data; |
||
1387 | graph.SetAboutInfo(1); |
||
4652 | ashmew2 | 1388 | graph.Run(TGraphDraw::button_down_mask | TGraphDraw::button_up_mask | |
1805 | yogev_ezra | 1389 | TGraphDraw::key_down_mask | TGraphDraw::mouse_drag_mask, |
1390 | 450 + 100 * ssf, 528); |
||
1391 | return 0; |
||
1392 | } |
||
1393 | #else |
||
1394 | |||
1395 | TMainData* mdata; |
||
1396 | TMainGraphDraw* graph; |
||
1397 | |||
1398 | bool MenuetOnStart(TStartData &me_start, TThreadData) |
||
1399 | |||
1400 | mdata = new TMainData(-1); |
||
1401 | graph = new TMainGraphDraw; |
||
1402 | |||
1403 | mdata->InitDef(); |
||
1404 | static TTimerDraw timer_draw(&mdata->board, graph); |
||
1405 | mdata->player.draw = TTimerDraw::draw; mdata->player.data = &timer_draw; |
||
1406 | graph->data = mdata; |
||
1407 | me_start.WinData.Title = CHECKERS_STR; |
||
1408 | me_start.Width = 450 + 100*ssf; |
||
1409 | me_start.Height = 528; |
||
1410 | return true; |
||
1411 | } |
||
4652 | ashmew2 | 1412 | bool MenuetOnClose(TThreadData) |
1805 | yogev_ezra | 1413 | { |
1414 | delete mdata; |
||
1415 | delete graph; |
||
1416 | return true; |
||
1417 | } |
||
1418 | int MenuetOnIdle(TThreadData) |
||
1419 | {return -1;} |
||
1420 | void MenuetOnSize(int window_rect[], TThreadData) |
||
1421 | {mdata->board.Resize(window_rect[2]-window_rect[0], window_rect[3]-window_rect[1]);} |
||
1422 | void MenuetOnKeyPress(TThreadData) |
||
1423 | { |
||
1424 | TGraphDraw::event ev; |
||
1425 | ev.type = TGraphDraw::event::key_down; |
||
1426 | ev.any.drw = graph; |
||
1427 | ev.key.k = GetKey(); |
||
1428 | mdata->EventFunction(ev); |
||
1429 | } |
||
1430 | void MenuetOnDraw(void) |
||
1431 | { |
||
1432 | TGraphDraw::event ev; |
||
1433 | ev.type = TGraphDraw::event::draw; |
||
1434 | ev.any.drw = graph; |
||
1435 | mdata->EventFunction(ev); |
||
1436 | } |
||
1437 | void MenuetOnMouse(TThreadData) |
||
1438 | { |
||
1439 | short x,y; |
||
1440 | GetMousePosition(x,y); |
||
1441 | int m = GetMouseButton() & 1; |
||
1442 | static int mprev = 0; |
||
1443 | if (m == mprev) |
||
1444 | return; |
||
1445 | mprev = m; |
||
1446 | TGraphDraw::event ev; |
||
1447 | ev.type = m ? TGraphDraw::event::button_down : TGraphDraw::event::button_up; |
||
1448 | ev.any.drw = graph; |
||
1449 | ev.button.n = 1; |
||
1450 | ev.button.x = x; |
||
1451 | ev.button.y = y; |
||
1452 | mdata->EventFunction(ev); |
||
1453 | } |
||
1454 | #endif>=>>>>=>=>>=>"; |
||
1455 | >"; |
||
1456 | ><"; |
||
1457 | >>=>>=>>=>>=>>>>>>>=>>=>>>>>>>>>>>>>>>>>' |
||
1458 | #define>>*ptr2) |
||
1459 | >0)?-n:n; |