2 Copyright (c) 1993 Richard V. Nash.
3 Copyright (c) 2000 Dan Papasian
4 Copyright (C) Andrew Tridgell 2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 const char *wpstring[] = {" ", "P", "N", "B", "R", "Q", "K"};
27 static const char *bpstring[] = {" ", "p", "n", "b", "r", "q", "k"};
29 static int pieceValues[7] = {0, 1, 3, 3, 5, 9, 0};
31 static const int mach_type = (1<<7) | (1<<8) | (1<<9) | (1<<10) | (1<<11);
32 #define IsMachineStyle(n) (((1<<(n)) & mach_type) != 0)
34 static char bstring[MAX_BOARD_STRING_LEGTH];
36 static int board_read_file(char *category, char *gname, struct game_state_t *gs);
37 static void wild_update(int style);
39 static int style1(struct game_state_t *b, struct move_t *ml);
40 static int style2(struct game_state_t *b, struct move_t *ml);
41 static int style3(struct game_state_t *b, struct move_t *ml);
42 static int style4(struct game_state_t *b, struct move_t *ml);
43 static int style5(struct game_state_t *b, struct move_t *ml);
44 static int style6(struct game_state_t *b, struct move_t *ml);
45 static int style7(struct game_state_t *b, struct move_t *ml);
46 static int style8(struct game_state_t *b, struct move_t *ml);
47 static int style9(struct game_state_t *b, struct move_t *ml);
48 static int style10(struct game_state_t *b, struct move_t *ml);
49 static int style11(struct game_state_t *b, struct move_t *ml);
50 static int style12(struct game_state_t *b, struct move_t *ml);
51 static int style13(struct game_state_t *b, struct move_t *ml);
53 static int (*styleFuncs[MAX_STYLES])() = {
70 static void reset_board_vars(struct game_state_t *gs)
74 for (f = 0; f < 2; f++) {
75 for (r = 0; r < 8; r++)
76 gs->ep_possible[f][r] = 0;
77 for (r = PAWN; r <= QUEEN; r++)
78 gs->holding[f][r-PAWN] = 0;
80 gs->wkmoved = gs->wqrmoved = gs->wkrmoved = 0;
81 gs->bkmoved = gs->bqrmoved = gs->bkrmoved = 0;
84 gs->lastIrreversable = -1;
88 void board_clear(struct game_state_t *gs)
92 for (f = 0; f < 8; f++)
93 for (r = 0; r < 8; r++)
94 gs->board[f][r] = NOPIECE;
98 void board_standard(struct game_state_t *gs)
102 for (f = 0; f < 8; f++)
103 for (r = 2; r < 6; r++)
104 gs->board[f][r] = NOPIECE;
105 for (f = 0; f < 8; f++)
106 gs->board[f][1] = W_PAWN;
107 for (f = 0; f < 8; f++)
108 gs->board[f][6] = B_PAWN;
109 gs->board[0][0] = W_ROOK;
110 gs->board[1][0] = W_KNIGHT;
111 gs->board[2][0] = W_BISHOP;
112 gs->board[3][0] = W_QUEEN;
113 gs->board[4][0] = W_KING;
114 gs->board[5][0] = W_BISHOP;
115 gs->board[6][0] = W_KNIGHT;
116 gs->board[7][0] = W_ROOK;
117 gs->board[0][7] = B_ROOK;
118 gs->board[1][7] = B_KNIGHT;
119 gs->board[2][7] = B_BISHOP;
120 gs->board[3][7] = B_QUEEN;
121 gs->board[4][7] = B_KING;
122 gs->board[5][7] = B_BISHOP;
123 gs->board[6][7] = B_KNIGHT;
124 gs->board[7][7] = B_ROOK;
125 reset_board_vars(gs);
128 int board_init(int g,struct game_state_t *b, char *category, char *board)
133 if (!category || !board || !category[0] || !board[0])
134 /* accounts for bughouse too */
137 if (!strcmp(category, "wild")) {
138 if (sscanf(board, "%d", &wval) == 1 && wval >= 1 && wval <= 4)
141 retval = board_read_file(category, board, b);
143 MakeFENpos(g, game_globals.garray[g].FENstartPos);
147 void board_calc_strength(struct game_state_t *b, int *ws, int *bs)
153 for (f = 0; f < 8; f++) {
154 for (r = 0; r < 8; r++) {
155 if (colorval(b->board[r][f]) == WHITE)
159 *p += pieceValues[piecetype(b->board[r][f])];
162 for (r = PAWN; r <= QUEEN; r++) {
163 *ws += b->holding[0][r-1] * pieceValues[r];
164 *bs += b->holding[1][r-1] * pieceValues[r];
168 static char *holding_str(int *holding)
174 for (p = PAWN; p <= QUEEN; p++) {
175 for (j = 0; j < holding[p-1]; j++) {
176 tmp[i++] = wpstring[p][0];
183 static char *append_holding_machine(char *buf, int g, int c, int p)
185 struct game_state_t *gs = &game_globals.garray[g].game_state;
188 sprintf(tmp, "<b1> game %d white [%s] black [", g+1, holding_str(gs->holding[0]));
189 strcat(tmp, holding_str(gs->holding[1]));
192 sprintf(tmp, "] <- %c%s\n", "WB"[c], wpstring[p]);
199 static char *append_holding_display(char *buf, struct game_state_t *gs, int white)
202 strcat(buf, "White holding: [");
204 strcat(buf, "Black holding: [");
205 strcat(buf, holding_str(gs->holding[white ? 0 : 1]));
210 void update_holding(int g, int pieceCaptured)
212 int p = piecetype(pieceCaptured);
213 int c = colorval(pieceCaptured);
214 struct game_state_t *gs = &game_globals.garray[g].game_state;
216 char tmp1[80], tmp2[80];
220 pp = game_globals.garray[g].white;
223 pp = game_globals.garray[g].black;
225 gs->holding[c][p-1]++;
227 append_holding_machine(tmp1, g, c, p);
228 sprintf(tmp2, "Game %d %s received: %s -> [%s]\n", g+1,
229 player_globals.parray[pp].name, wpstring[p], holding_str(gs->holding[c]));
230 for (pl = 0; pl < player_globals.p_num; pl++) {
231 if (player_globals.parray[pl].status == PLAYER_EMPTY)
233 if (player_is_observe(pl, g) || (player_globals.parray[pl].game == g)) {
234 pprintf_prompt(pl, IsMachineStyle(player_globals.parray[pl].style) ? tmp1 : tmp2);
240 /* Globals used for each board */
241 static int wTime, bTime;
243 static int forPlayer;
244 static int myTurn; /* 1 = my turn, 0 = observe, -1 = other turn */
245 /* 2 = examiner, -2 = observing examiner */
246 /* -3 = just send position (spos/refresh) */
248 char *board_to_string(char *wn, char *bn,
250 struct game_state_t *b, struct move_t *ml, int style,
251 int orientation, int relation,
254 int bh = (b->gameNum >= 0 && game_globals.garray[b->gameNum].link >= 0);
255 orient = orientation;
261 /* when examining we calculate times based on the time left when the
262 move happened, not current time */
263 if (game_globals.garray[b->gameNum].status == GAME_EXAMINE) {
264 unsigned nhm = game_globals.garray[b->gameNum].numHalfMoves;
266 wTime = ml[nhm - 1].wTime;
267 bTime = ml[nhm - 1].bTime;
269 wTime = game_globals.garray[b->gameNum].wInitTime;
270 bTime = game_globals.garray[b->gameNum].bInitTime;
274 /* cope with old stored games */
275 if (wTime == 0) wTime = wt;
276 if (bTime == 0) bTime = bt;
279 if ((style < 0) || (style >= MAX_STYLES))
282 if (style != 11) { /* game header */
283 sprintf(bstring, "Game %d (%s vs. %s)\n\n",
285 game_globals.garray[b->gameNum].white_name,
286 game_globals.garray[b->gameNum].black_name);
289 if (bh && !IsMachineStyle(style))
290 append_holding_display(bstring, b, orientation==BLACK);
291 if (styleFuncs[style] (b, ml))
294 if (IsMachineStyle(style))
295 append_holding_machine(bstring, b->gameNum, 0, 0);
297 append_holding_display(bstring, b, orientation==WHITE);
302 char *move_and_time(struct move_t *m)
305 sprintf(tmp, "%-7s (%s)", m->algString, tenth_str(m->tookTime, 0));
309 /* The following take the game state and whole move list */
311 static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[], const char *bp[],
312 const char *wsqr, const char *bsqr,
313 const char *top, const char *mid, const char *start, const char *end,
314 const char *label,const char *blabel)
318 int first, last, inc;
321 board_calc_strength(b, &ws, &bs);
322 if (orient == WHITE) {
331 strcat(bstring, top);
332 for (f = first, count = 7; f != last + inc; f += inc, count--) {
333 sprintf(tmp, " %d %s", f + 1, start);
334 strcat(bstring, tmp);
335 for (r = last; r != first - inc; r = r - inc) {
336 if (square_color(r, f) == WHITE)
337 strcat(bstring, wsqr);
339 strcat(bstring, bsqr);
340 if (piecetype(b->board[r][f]) == NOPIECE) {
341 if (square_color(r, f) == WHITE)
342 strcat(bstring, bp[0]);
344 strcat(bstring, wp[0]);
346 if (colorval(b->board[r][f]) == WHITE)
347 strcat(bstring, wp[piecetype(b->board[r][f])]);
349 strcat(bstring, bp[piecetype(b->board[r][f])]);
352 sprintf(tmp, "%s", end);
353 strcat(bstring, tmp);
356 sprintf(tmp, " Move # : %d (%s)", b->moveNum, CString(b->onMove));
357 strcat(bstring, tmp);
360 /* if ((b->moveNum > 1) || (b->onMove == BLACK)) { */
361 /* The change from the above line to the one below is a kludge by hersco. */
362 if (game_globals.garray[b->gameNum].numHalfMoves > 0) {
363 /* loon: think this fixes the crashing ascii board on takeback bug */
364 sprintf(tmp, " %s Moves : '%s'", CString(CToggle(b->onMove)),
365 move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));
366 strcat(bstring, tmp);
372 sprintf(tmp, " Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));
373 strcat(bstring, tmp);
376 sprintf(tmp, " White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));
377 strcat(bstring, tmp);
380 sprintf(tmp, " Black Strength : %d", bs);
381 strcat(bstring, tmp);
384 sprintf(tmp, " White Strength : %d", ws);
385 strcat(bstring, tmp);
390 strcat(bstring, "\n");
392 strcat(bstring, mid);
394 strcat(bstring, top);
397 strcat(bstring, label);
399 strcat(bstring, blabel);
403 /* Experimental ANSI board for colour representation */
404 static int style13(struct game_state_t *b, struct move_t *ml)
406 static const char *wp[] = {" ", "\033[37m\033[1m P ", "\033[37m\033[1m N ", "\033[37m\033[1m B ", "\033[37m\033[1m R ", "\033[37m\033[1m Q ", "\033[37m\033[1m K "};
407 static const char *bp[] = {" ", "\033[21m\033[37m P ", "\033[21m\033[37m N ", "\033[21m\033[37m B ", "\033[21m\033[37m R ", "\033[21m\033[37m Q ", "\033[21m\033[37m K "};
408 static const char *wsqr = "\033[40m";
409 static const char *bsqr = "\033[45m";
410 static const char *top = "\t+------------------------+\n";
411 static const char *mid = "";
412 static const char *start = "|";
413 static const char *end = "\033[0m|";
414 static const char *label = "\t a b c d e f g h\n";
415 static const char *blabel = "\t h g f e d c b a\n";
417 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
421 static int style1(struct game_state_t *b, struct move_t *ml)
423 static const char *wp[] = {" |", " P |", " N |", " B |", " R |", " Q |", " K |"};
424 static const char *bp[] = {" |", " *P|", " *N|", " *B|", " *R|", " *Q|", " *K|"};
425 static char *wsqr = "";
426 static char *bsqr = "";
427 static char *top = "\t---------------------------------\n";
428 static char *mid = "\t|---+---+---+---+---+---+---+---|\n";
429 static char *start = "|";
430 static char *end = "";
431 static char *label = "\t a b c d e f g h\n";
432 static char *blabel = "\t h g f e d c b a\n";
434 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
437 /* USA-Today Sports Center-style board */
438 static int style2(struct game_state_t *b, struct move_t *ml)
440 static const char *wp[] = {"+ ", "P ", "N ", "B ", "R ", "Q ", "K "};
441 static const char *bp[] = {"- ", "p' ", "n' ", "b' ", "r' ", "q' ", "k' "};
442 static char *wsqr = "";
443 static char *bsqr = "";
444 static char *top = "";
445 static char *mid = "";
446 static char *start = "";
447 static char *end = "";
448 static char *label = "\ta b c d e f g h\n";
449 static char *blabel = "\th g f e d c b a\n";
451 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
454 /* Experimental vt-100 ANSI board for dark backgrounds */
455 static int style3(struct game_state_t *b, struct move_t *ml)
457 static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
458 static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
459 static char *wsqr = "\033[0m";
460 static char *bsqr = "\033[7m";
461 static char *top = "\t+------------------------+\n";
462 static char *mid = "";
463 static char *start = "|";
464 static char *end = "\033[0m|";
465 static char *label = "\t a b c d e f g h\n";
466 static char *blabel = "\t h g f e d c b a\n";
468 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
471 /* Experimental vt-100 ANSI board for light backgrounds */
472 static int style4(struct game_state_t *b, struct move_t *ml)
474 static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
475 static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
476 static char *wsqr = "\033[7m";
477 static char *bsqr = "\033[0m";
478 static char *top = "\t+------------------------+\n";
479 static char *mid = "";
480 static char *start = "|";
481 static char *end = "\033[0m|";
482 static char *label = "\t a b c d e f g h\n";
483 static char *blabel = "\t h g f e d c b a\n";
485 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
488 /* Style suggested by ajpierce@med.unc.edu */
489 static int style5(struct game_state_t *b, struct move_t *ml)
491 static const char *wp[] = {" ", " o ", " :N:", " <B>", " |R|", " {Q}", " =K="};
492 static const char *bp[] = {" ", " p ", " :n:", " <b>", " |r|", " {q}", " =k="};
493 static char *wsqr = "";
494 static char *bsqr = "";
495 static char *top = " . . . . . . . . .\n";
496 static char *mid = " . . . . . . . . .\n";
497 static char *start = "";
498 static char *end = "";
499 static char *label = "\t a b c d e f g h\n";
500 static char *blabel = "\t h g f e d c b a\n";
502 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
505 /* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */
506 static int style6(struct game_state_t *b, struct move_t *ml)
508 static const char *wp[] = {" |", " wp |", " WN |", " WB |", " WR |", " WQ |", " WK |"};
509 static const char *bp[] = {" |", " bp |", " BN |", " BB |", " BR |", " BQ |", " BK |"};
510 static char *wsqr = "";
511 static char *bsqr = "";
512 static char *top = "\t-----------------------------------------\n";
513 static char *mid = "\t-----------------------------------------\n";
514 static char *start = "|";
515 static char *end = "";
516 static char *label = "\t A B C D E F G H\n";
517 static char *blabel = "\t H G F E D C B A\n";
519 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
522 /* Miniature board */
523 static int style7(struct game_state_t *b, struct move_t *ml)
525 static const char *wp[] = {" ", " P", " N", " B", " R", " Q", " K"};
526 static const char *bp[] = {" -", " p", " n", " b", " r", " q", " k"};
527 static char *wsqr = "";
528 static char *bsqr = "";
529 static char *top = "\t:::::::::::::::::::::\n";
530 static char *mid = "";
531 static char *start = "..";
532 static char *end = " ..";
533 static char *label = "\t a b c d e f g h\n";
534 static char *blabel = "\t h g f e d c b a\n";
536 return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
539 /* ICS interface maker board-- raw data dump */
540 static int style8(struct game_state_t *b, struct move_t *ml)
546 board_calc_strength(b, &ws, &bs);
547 sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,
548 game_globals.garray[b->gameNum].white_name,
549 (orient == WHITE) ? "*" : ":",
550 game_globals.garray[b->gameNum].black_name,
551 (orient == WHITE) ? ":" : "*");
552 strcat(bstring, tmp);
553 for (r = 0; r < 8; r++) {
554 for (f = 0; f < 8; f++) {
555 if (b->board[f][r] == NOPIECE) {
556 strcat(bstring, " ");
558 if (colorval(b->board[f][r]) == WHITE)
559 strcat(bstring, wpstring[piecetype(b->board[f][r])]);
561 strcat(bstring, bpstring[piecetype(b->board[f][r])]);
565 sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
566 game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
567 (b->onMove == WHITE) ? "W" : "B",
572 game_globals.garray[b->gameNum].numHalfMoves ?
573 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
575 game_globals.garray[b->gameNum].numHalfMoves ?
576 tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
578 strcat(bstring, tmp);
582 /* last 2 moves only (previous non-verbose mode) */
583 static int style9(struct game_state_t *b, struct move_t *ml)
589 sprintf(tmp, "\nMove %-23s%s\n",
590 game_globals.garray[b->gameNum].white_name,
591 game_globals.garray[b->gameNum].black_name);
592 strcat(bstring, tmp);
593 sprintf(tmp, "---- -------------- --------------\n");
594 strcat(bstring, tmp);
595 startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;
598 for (i = startmove, count = 0;
599 i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;
602 sprintf(tmp, " %2d ", i / 2 + 1);
603 strcat(bstring, tmp);
605 sprintf(tmp, "%-23s", move_and_time(&ml[i]));
606 strcat(bstring, tmp);
608 strcat(bstring, "\n");
611 strcat(bstring, "\n");
615 /* Sleator's 'new and improved' raw dump format... */
616 static int style10(struct game_state_t *b, struct move_t *ml)
622 board_calc_strength(b, &ws, &bs);
623 sprintf(tmp, "<10>\n");
624 strcat(bstring, tmp);
625 for (r = 7; r >= 0; r--) {
626 strcat(bstring, "|");
627 for (f = 0; f < 8; f++) {
628 if (b->board[f][r] == NOPIECE) {
629 strcat(bstring, " ");
631 if (colorval(b->board[f][r]) == WHITE)
632 strcat(bstring, wpstring[piecetype(b->board[f][r])]);
634 strcat(bstring, bpstring[piecetype(b->board[f][r])]);
637 strcat(bstring, "|\n");
639 strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
640 if (game_globals.garray[b->gameNum].numHalfMoves) {
642 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
646 strcat(bstring, tmp);
647 sprintf(tmp, "%d %d %d %d %d\n",
648 !(b->wkmoved || b->wkrmoved),
649 !(b->wkmoved || b->wqrmoved),
650 !(b->bkmoved || b->bkrmoved),
651 !(b->bkmoved || b->bqrmoved),
652 (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :
653 b->lastIrreversable)));
654 strcat(bstring, tmp);
655 sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",
657 game_globals.garray[b->gameNum].white_name,
658 game_globals.garray[b->gameNum].black_name,
660 game_globals.garray[b->gameNum].wInitTime / 600,
661 game_globals.garray[b->gameNum].wIncrement / 10,
666 game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
667 game_globals.garray[b->gameNum].numHalfMoves ?
668 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
670 game_globals.garray[b->gameNum].numHalfMoves ?
671 tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
673 game_globals.garray[b->gameNum].numHalfMoves ?
674 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
676 (orient == WHITE) ? 0 : 1);
677 strcat(bstring, tmp);
678 sprintf(tmp, ">10<\n");
679 strcat(bstring, tmp);
683 /* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */
684 static int style11(struct game_state_t *b, struct move_t *ml)
690 board_calc_strength(b, &ws, &bs);
691 sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,
692 game_globals.garray[b->gameNum].white_name,
693 (orient == WHITE) ? "*" : ":",
694 game_globals.garray[b->gameNum].black_name,
695 (orient == WHITE) ? ":" : "*");
696 strcat(bstring, tmp);
697 for (r = 0; r < 8; r++) {
698 for (f = 0; f < 8; f++) {
699 if (b->board[f][r] == NOPIECE) {
700 strcat(bstring, " ");
702 if (colorval(b->board[f][r]) == WHITE)
703 strcat(bstring, wpstring[piecetype(b->board[f][r])]);
705 strcat(bstring, bpstring[piecetype(b->board[f][r])]);
709 sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
710 game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
711 (b->onMove == WHITE) ? "W" : "B",
716 game_globals.garray[b->gameNum].numHalfMoves ?
717 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
719 game_globals.garray[b->gameNum].numHalfMoves ?
720 tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
722 strcat(bstring, tmp);
726 /* Similar to style 10. See the "style12" help file for information */
727 static int style12(struct game_state_t *b, struct move_t *ml)
733 board_calc_strength(b, &ws, &bs);
734 sprintf(bstring, "<12> ");
735 for (r = 7; r >= 0; r--) {
736 for (f = 0; f < 8; f++) {
737 if (b->board[f][r] == NOPIECE) {
738 strcat(bstring, "-");
740 if (colorval(b->board[f][r]) == WHITE)
741 strcat(bstring, wpstring[piecetype(b->board[f][r])]);
743 strcat(bstring, bpstring[piecetype(b->board[f][r])]);
746 strcat(bstring, " ");
748 strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
749 if (game_globals.garray[b->gameNum].numHalfMoves) {
751 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
755 strcat(bstring, tmp);
756 sprintf(tmp, "%d %d %d %d %d ",
757 !(b->wkmoved || b->wkrmoved),
758 !(b->wkmoved || b->wqrmoved),
759 !(b->bkmoved || b->bkrmoved),
760 !(b->bkmoved || b->bqrmoved),
761 (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));
762 strcat(bstring, tmp);
763 sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n",
765 game_globals.garray[b->gameNum].white_name,
766 game_globals.garray[b->gameNum].black_name,
768 game_globals.garray[b->gameNum].wInitTime / 600,
769 game_globals.garray[b->gameNum].wIncrement / 10,
774 game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
775 game_globals.garray[b->gameNum].numHalfMoves ?
776 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
778 game_globals.garray[b->gameNum].numHalfMoves ?
779 tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
781 game_globals.garray[b->gameNum].numHalfMoves ?
782 ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
783 "none", (orient == WHITE) ? 0 : 1,
784 b->moveNum > 1 ? 1 : 0); /* ticking */
786 strcat(bstring, tmp);
790 static int board_read_file(char *category, char *gname, struct game_state_t *gs)
800 fp = fopen_p("%s/%s/%s", "r", BOARD_DIR, category, gname);
812 } else if (c == 'B') {
816 } else if (c == '#') {
817 while (!feof(fp) && c != '\n')
818 c = fgetc(fp); /* Comment line */
820 } else { /* Skip any line we don't understand */
821 while (!feof(fp) && c != '\n')
866 if (onFile >= 0 && onColor >= 0 && onPiece >= 0)
867 gs->board[onFile][onRank] = onPiece | onColor;
870 while (!feof(fp) && c != '\n')
871 c = fgetc(fp); /* Comment line */
888 #define WHITE_SQUARE 1
889 #define BLACK_SQUARE 0
890 #define ANY_SQUARE -1
891 #define SquareColor(f, r) ((f ^ r) & 1)
893 static void place_piece(board_t b, int piece, int squareColor)
898 if (iscolor(piece, BLACK))
904 if (squareColor == ANY_SQUARE) {
907 f = (random() % 4) * 2;
908 if (SquareColor(f, r) != squareColor)
911 if ((b)[f][r] == NOPIECE) {
918 static void wild_update(int style)
923 for (f = 0; f < 8; f++)
924 for (r = 0; r < 8; r++)
926 for (f = 0; f < 8; f++) {
932 if (random() & 0x01) {
939 if (random() & 0x01) {
946 b[0][0] = b[7][0] = W_ROOK;
947 b[0][7] = b[7][7] = B_ROOK;
948 /* Must do bishops before knights to be sure opposite colored squares are
950 place_piece(b, W_BISHOP, WHITE_SQUARE);
951 place_piece(b, W_BISHOP, BLACK_SQUARE);
952 place_piece(b, W_KNIGHT, ANY_SQUARE);
953 place_piece(b, W_KNIGHT, ANY_SQUARE);
954 place_piece(b, B_BISHOP, WHITE_SQUARE);
955 place_piece(b, B_BISHOP, BLACK_SQUARE);
956 place_piece(b, B_KNIGHT, ANY_SQUARE);
957 place_piece(b, B_KNIGHT, ANY_SQUARE);
960 place_piece(b, W_KING, ANY_SQUARE);
961 place_piece(b, W_QUEEN, ANY_SQUARE);
962 place_piece(b, W_ROOK, ANY_SQUARE);
963 place_piece(b, W_ROOK, ANY_SQUARE);
964 place_piece(b, W_BISHOP, ANY_SQUARE);
965 place_piece(b, W_BISHOP, ANY_SQUARE);
966 place_piece(b, W_KNIGHT, ANY_SQUARE);
967 place_piece(b, W_KNIGHT, ANY_SQUARE);
968 /* Black mirrors White */
969 for (i = 0; i < 8; i++) {
970 b[i][7] = b[i][0] | BLACK;
974 /* Generate White king on random square plus random set of pieces */
975 place_piece(b, W_KING, ANY_SQUARE);
976 for (i = 0; i < 8; i++) {
977 if (b[i][0] != W_KING) {
978 b[i][0] = (random() % 4) + 2;
981 /* Black mirrors White */
982 for (i = 0; i < 8; i++) {
983 b[i][7] = b[i][0] | BLACK;
987 /* Generate White king on random square plus random set of pieces */
988 place_piece(b, W_KING, ANY_SQUARE);
989 for (i = 0; i < 8; i++) {
990 if (b[i][0] != W_KING) {
991 b[i][0] = (random() % 4) + 2;
994 /* Black has same set of pieces, but randomly permuted, except that Black
995 must have the same number of bishops on white squares as White has on
996 black squares, and vice versa. So we must place Black's bishops first
997 to be sure there are enough squares left of the correct color. */
998 for (i = 0; i < 8; i++) {
999 if (b[i][0] == W_BISHOP) {
1000 place_piece(b, B_BISHOP, !SquareColor(i, 0));
1003 for (i = 0; i < 8; i++) {
1004 if (b[i][0] != W_BISHOP) {
1005 place_piece(b, b[i][0] | BLACK, ANY_SQUARE);
1017 fp = fopen_p("%s/wild/%d", "w", BOARD_DIR, style);
1019 d_printf( "CHESSD: Can't write wild style %d\n", style);
1024 for (r = 1; r >= 0; r--) {
1025 for (f = 0; f < 8; f++) {
1026 if (onPiece < 0 || b[f][r] != onPiece) {
1028 fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
1030 fprintf(fp, " %c%c", f + 'a', r + '1');
1033 fprintf(fp, "\nB:");
1035 for (r = 6; r < 8; r++) {
1036 for (f = 0; f < 8; f++) {
1037 if (onPiece < 0 || b[f][r] != onPiece) {
1039 fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
1041 fprintf(fp, " %c%c", f + 'a', r + '1');
1049 void wild_init(void)