X-Git-Url: http://winboard.nl/cgi-bin?p=capablanca.git;a=blobdiff_plain;f=lasker-2.2.3%2Fsrc%2Fboard.c;h=8c9247377a68002308a89b2da702211ca622bb1f;hp=8fdbb0e4271e0948d720c4f1eb4ba60bdbed04d2;hb=ec7b6bb32ba9632cda17b308808ce9ba1e27c090;hpb=76f1e81b3426b94e1d80c9daa309f78045e5335b diff --git a/lasker-2.2.3/src/board.c b/lasker-2.2.3/src/board.c index 8fdbb0e..8c92473 100644 --- a/lasker-2.2.3/src/board.c +++ b/lasker-2.2.3/src/board.c @@ -23,18 +23,20 @@ #include "includes.h" -const char *wpstring[] = {" ", "P", "N", "B", "R", "Q", "K"}; -static const char *bpstring[] = {" ", "p", "n", "b", "r", "q", "k"}; +const char *wpstring[] = {" ", "P", "N", "B", "R", "A", "C", "M", "Q", "E", "B", "Q", "W", "H", "N", "D", "H", "L", + "C", "S", "G", "H", "A", "F", "E", "H", "M", "S", "E", "W", "O", "G", "V", "S", "E", "A", "K", "H", "E"}; +const char *bpstring[] = {" ", "p", "n", "b", "r", "a", "c", "m", "q", "e", "b", "q", "w", "h", "n", "d", "h", "l", + "c", "s", "g", "h", "a", "f", "e", "h", "m", "s", "e", "w", "o", "g", "v", "s", "e", "a", "k", "h", "e"}; -static int pieceValues[7] = {0, 1, 3, 3, 5, 9, 0}; +int pieceValues[PIECES] = {0, 1, 3, 3, 5, 8, 9, 3, 9, 1, 1, 2, 2, 2, 1, 6, 5, 2, 3, 3, 3, 1, 5, 2, 1, 7, 7, 3, 3, 3, 7, 7, 7, 8, 9, 12, 0, 8, 9}; static const int mach_type = (1<<7) | (1<<8) | (1<<9) | (1<<10) | (1<<11); #define IsMachineStyle(n) (((1<<(n)) & mach_type) != 0) -static char bstring[MAX_BOARD_STRING_LEGTH]; +static char bstring[MAX_BOARD_STRING_LENGTH]; static int board_read_file(char *category, char *gname, struct game_state_t *gs); -static void wild_update(int style); +static void wild_update(board_t b, int style); static int style1(struct game_state_t *b, struct move_t *ml); static int style2(struct game_state_t *b, struct move_t *ml); @@ -71,14 +73,16 @@ static void reset_board_vars(struct game_state_t *gs) { int f,r; + if(gs->files <= 0) gs->files = 8; // [HGM] for pristine board, set default size + if(gs->ranks <= 0) gs->ranks = 8; for (f = 0; f < 2; f++) { - for (r = 0; r < 8; r++) + for (r = 0; r < BW; r++) gs->ep_possible[f][r] = 0; - for (r = PAWN; r <= QUEEN; r++) + for (r = PAWN; r <= PIECES-1; r++) gs->holding[f][r-PAWN] = 0; } - gs->wkmoved = gs->wqrmoved = gs->wkrmoved = 0; - gs->bkmoved = gs->bqrmoved = gs->bkrmoved = 0; + gs->wkmoved = gs->wqrmoved = gs->wkrmoved = -1; // [HGM] castle: no rights + gs->bkmoved = gs->bqrmoved = gs->bkrmoved = -1; gs->onMove = WHITE; gs->moveNum = 1; gs->lastIrreversable = -1; @@ -89,8 +93,8 @@ void board_clear(struct game_state_t *gs) { int f,r; - for (f = 0; f < 8; f++) - for (r = 0; r < 8; r++) + for (f = 0; f < BW; f++) + for (r = 0; r < BH; r++) gs->board[f][r] = NOPIECE; reset_board_vars(gs); } @@ -99,48 +103,142 @@ void board_standard(struct game_state_t *gs) { int f,r; - for (f = 0; f < 8; f++) - for (r = 2; r < 6; r++) + for (f = 0; f < BW; f++) + for (r = 0; r < BH; r++) gs->board[f][r] = NOPIECE; - for (f = 0; f < 8; f++) - gs->board[f][1] = W_PAWN; - for (f = 0; f < 8; f++) + for (f = 0; f < gs->files; f++) + gs->board[f][gs->ranks-7] = W_PAWN; + for (f = 0; f < gs->files; f++) gs->board[f][6] = B_PAWN; gs->board[0][0] = W_ROOK; gs->board[1][0] = W_KNIGHT; gs->board[2][0] = W_BISHOP; gs->board[3][0] = W_QUEEN; - gs->board[4][0] = W_KING; - gs->board[5][0] = W_BISHOP; - gs->board[6][0] = W_KNIGHT; - gs->board[7][0] = W_ROOK; - gs->board[0][7] = B_ROOK; - gs->board[1][7] = B_KNIGHT; - gs->board[2][7] = B_BISHOP; - gs->board[3][7] = B_QUEEN; - gs->board[4][7] = B_KING; - gs->board[5][7] = B_BISHOP; - gs->board[6][7] = B_KNIGHT; - gs->board[7][7] = B_ROOK; + gs->board[gs->files/2][0] = W_KING; + gs->board[gs->files-3][0] = W_BISHOP; + gs->board[gs->files-2][0] = W_KNIGHT; + gs->board[gs->files-1][0] = W_ROOK; + gs->board[0][gs->ranks-1] = B_ROOK; + gs->board[1][gs->ranks-1] = B_KNIGHT; + gs->board[2][gs->ranks-1] = B_BISHOP; + gs->board[3][gs->ranks-1] = B_QUEEN; + gs->board[gs->files/2][gs->ranks-1] = B_KING; + gs->board[gs->files-3][gs->ranks-1] = B_BISHOP; + gs->board[gs->files-2][gs->ranks-1] = B_KNIGHT; + gs->board[gs->files-1][gs->ranks-1] = B_ROOK; +#if 1 + if(gs->files == 10) { + gs->board[6][0] = W_CARDINAL; + gs->board[4][0] = W_MARSHALL; + gs->board[6][gs->ranks-1] = B_CARDINAL; + gs->board[4][gs->ranks-1] = B_MARSHALL; + } + if(gs->royalKnight) { + gs->board[1][0] = W_MAN; + gs->board[gs->files-2][0] = W_MAN; + gs->board[1][gs->ranks-1] = B_MAN; + gs->board[gs->files-2][gs->ranks-1] = B_MAN; + } +#endif + reset_board_vars(gs); + // [HGM] castle: standard setup has rights for corner Rooks and central King + gs->wkmoved = gs->files/2; + gs->bkmoved = gs->files/2; + gs->wkrmoved = gs->files-1; + gs->bkrmoved = gs->files-1; + gs->wqrmoved = 0; + gs->bqrmoved = 0; } int board_init(int g,struct game_state_t *b, char *category, char *board) { int retval = 0; - int wval; - + int wval, i, j; + + b->files = b->ranks = 8; + b->pawnDblStep = (!category || strcmp(category, "shatranj")); + b->royalKnight = (category && !strcmp(category, "knightmate")); + b->capablancaPieces = 0; + b->holdings = 0; + b->drops = 0; + b->castlingStyle = 1; + b->palace = 0; + b->setup = 0; + b->bareKingLoses = 0; + b->stalemate = 1; + b->promoType = 1; + b->promoZone = 1; + b->variant[0] = 0; // [HGM] variant: default is normal, if variant name is missing if (!category || !board || !category[0] || !board[0]) /* accounts for bughouse too */ board_standard(b); else { - if (!strcmp(category, "wild")) { - if (sscanf(board, "%d", &wval) == 1 && wval >= 1 && wval <= 4) - wild_update(wval); + if(category && category[0]) strcpy(b->variant, category); // [HGM] variant: remember category name + if (!strcmp(category, "wild") && sscanf(board, "%d", &wval) == 1) { + if(wval >= 1 && wval <= 4) + wild_update(b->board, wval); + sprintf(b->variant, "wild/%d", wval); + } + + if (board && !strcmp(board, "0")) + b->setup = 0; // [HGM] variant: any board in the default file "0" is supposed to be implied by the variant + + if (!strcmp(category, "knightmate")) { + board_standard(b); + } else if (!strcmp(category, "super")) { + board_standard(b); + b->holdings = 1; + b->promoType = 2; + for(i=CENTAUR; i<=AMAZON; i++) { + int placed = 0; + do { int p, newp; + j = random() % 8; + if((p = piecetype(b->board[j][0])) >= CENTAUR) continue; // includes King + b->holding[1][p-PAWN] = ++b->holding[0][p-PAWN]; // piece to holding + if(board && !strcmp(board, "1")) newp = i - CENTAUR + WOODY; else newp = i; + if(board && !strcmp(board, "2")) newp = WOODY + random()%7; + b->board[j][0] = newp | WHITE; // place replacements + b->board[j][7] = newp | BLACK; + placed = 1; + } while(!placed); } - retval = board_read_file(category, board, b); + b->setup = 1; + } else if (!strcmp(category, "fischerandom")) { + wild_update(b->board, 22); + b->castlingStyle = 2; + b->setup = 1; // [HGM] FRC: even the default is a setup position, for which an initial board has to be printed + } else if (!strcmp(category, "caparandom")) { + b->files = 10; + wild_update(b->board, 46); + b->castlingStyle = 2; + b->setup = 1; + } else retval = board_read_file(category, board, b); } + if(b->setup && game_globals.garray[g].FENstartPos[0]) // [HGM] use pre-existing start position, if one available + FEN_to_board(game_globals.garray[g].FENstartPos, b); // (could be wild board, or shuffle variant) + if(b->castlingStyle == 1) { + b->wkmoved = b->files/2; + b->bkmoved = b->files/2; + b->wkrmoved = b->files-1; + b->bkrmoved = b->files-1; + b->wqrmoved = 0; + b->bqrmoved = 0; + } else if(b->castlingStyle == 2) { + for(i=j=0; i < b->files; i++) { + int p = b->board[i][0]; + if(p == W_ROOK || p == W_KING) { + switch(j++) { + case 0: b->wqrmoved = b->bqrmoved = i; break; + case 1: b->wkmoved = b->bkmoved = i; break; + case 2: b->wkrmoved = b->bkrmoved = i; break; + } + } + } + } + MakeFENpos(g, game_globals.garray[g].FENstartPos); + return retval; } @@ -150,8 +248,8 @@ void board_calc_strength(struct game_state_t *b, int *ws, int *bs) int *p; *ws = *bs = 0; - for (f = 0; f < 8; f++) { - for (r = 0; r < 8; r++) { + for (f = 0; f < b->ranks; f++) { + for (r = 0; r < b->files; r++) { if (colorval(b->board[r][f]) == WHITE) p = ws; else @@ -159,7 +257,7 @@ void board_calc_strength(struct game_state_t *b, int *ws, int *bs) *p += pieceValues[piecetype(b->board[r][f])]; } } - for (r = PAWN; r <= QUEEN; r++) { + for (r = PAWN; r < PIECES; r++) { *ws += b->holding[0][r-1] * pieceValues[r]; *bs += b->holding[1][r-1] * pieceValues[r]; } @@ -167,11 +265,11 @@ void board_calc_strength(struct game_state_t *b, int *ws, int *bs) static char *holding_str(int *holding) { - static char tmp[30]; + static char tmp[80]; int p,i,j; i = 0; - for (p = PAWN; p <= QUEEN; p++) { + for (p = PAWN; p < PIECES; p++) { for (j = 0; j < holding[p-1]; j++) { tmp[i++] = wpstring[p][0]; } @@ -183,7 +281,7 @@ static char *holding_str(int *holding) static char *append_holding_machine(char *buf, int g, int c, int p) { struct game_state_t *gs = &game_globals.garray[g].game_state; - char tmp[50]; + char tmp[160]; sprintf(tmp, " game %d white [%s] black [", g+1, holding_str(gs->holding[0])); strcat(tmp, holding_str(gs->holding[1])); @@ -213,7 +311,7 @@ void update_holding(int g, int pieceCaptured) int c = colorval(pieceCaptured); struct game_state_t *gs = &game_globals.garray[g].game_state; int pp, pl; - char tmp1[80], tmp2[80]; + char tmp1[160], tmp2[160]; if (c == WHITE) { c = 0; @@ -251,7 +349,8 @@ char *board_to_string(char *wn, char *bn, int orientation, int relation, int p) { - int bh = (b->gameNum >= 0 && game_globals.garray[b->gameNum].link >= 0); + int bh = (b->gameNum >= 0 && game_globals.garray[b->gameNum].link >= 0 + || b->holdings || b->drops == 2); // [HGM] zh: make sure holdings are printed (also in Seirawan) orient = orientation; myTurn = relation; @@ -262,6 +361,7 @@ char *board_to_string(char *wn, char *bn, move happened, not current time */ if (game_globals.garray[b->gameNum].status == GAME_EXAMINE) { unsigned nhm = game_globals.garray[b->gameNum].numHalfMoves; + if (nhm > 0) { wTime = ml[nhm - 1].wTime; bTime = ml[nhm - 1].bTime; @@ -288,8 +388,10 @@ char *board_to_string(char *wn, char *bn, bstring[0] = '\0'; if (bh && !IsMachineStyle(style)) append_holding_display(bstring, b, orientation==BLACK); + if (styleFuncs[style] (b, ml)) return NULL; + if (bh) { if (IsMachineStyle(style)) append_holding_machine(bstring, b->gameNum, 0, 0); @@ -302,37 +404,61 @@ char *board_to_string(char *wn, char *bn, char *move_and_time(struct move_t *m) { static char tmp[20]; +#if 0 + if(m->depth>0) + sprintf(tmp, "%-7s (%s%.2f/%d)", m->algString, /* tenth_str(m->tookTime, 0), */ + m->score>0 ? "+" : "", m->score, m->depth); + else +#endif sprintf(tmp, "%-7s (%s)", m->algString, tenth_str(m->tookTime, 0)); return tmp; } /* The following take the game state and whole move list */ +void Enlarge(char *a, int ss, int w) +{ + int l, i; + char *p, *q; + if(strlen(a) < ss) return; + for(i=8; iranks-1; + firstF = b->files-1; + lastR = lastF = 0; inc = -1; } else { - first = 0; - last = 7; + firstR = firstF = 0; + lastR = b->ranks-1; + lastF = b->files-1; inc = 1; } - strcat(bstring, top); - for (f = first, count = 7; f != last + inc; f += inc, count--) { - sprintf(tmp, " %d %s", f + 1, start); + strcpy(myTop, top); + strcpy(myMid, mid); + Enlarge(myTop, sqrSize, b->files); + Enlarge(myMid, sqrSize, b->files); + strcat(bstring, myTop); + for (f = firstR, count = b->ranks-1; f != lastR + inc; f += inc, count--) { + sprintf(tmp, " %d %s", f + (b->ranks < 10), start); strcat(bstring, tmp); - for (r = last; r != first - inc; r = r - inc) { + for (r = lastF; r != firstF - inc; r = r - inc) { if (square_color(r, f) == WHITE) strcat(bstring, wsqr); else @@ -343,10 +469,12 @@ static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[], else strcat(bstring, wp[0]); } else { + int piece = piecetype(b->board[r][f]); +// if(piece > QUEEN) piece = ELEPHANT + (piece == KING); // All fairies become elephants in ascii styles if (colorval(b->board[r][f]) == WHITE) - strcat(bstring, wp[piecetype(b->board[r][f])]); + strcat(bstring, wp[piece]); else - strcat(bstring, bp[piecetype(b->board[r][f])]); + strcat(bstring, bp[piece]); } } sprintf(tmp, "%s", end); @@ -389,47 +517,77 @@ static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[], } strcat(bstring, "\n"); if (count != 0) - strcat(bstring, mid); + strcat(bstring, myMid); else - strcat(bstring, top); + strcat(bstring, myTop); } - if (orient == WHITE) - strcat(bstring, label); - else - strcat(bstring, blabel); + q = mylabel; i = 0; + if (orient == WHITE) { + p = label; + while(*p) { + switch(*p) { + case ' ': + case '\t': + case '\n': + *q++ = *p++; break; + default: + if(++i > b->files) { *q++ = '\n'; *q++ = 0; } + *q++ = *p++; + } + } + } else { + p = blabel; + while(*p) { + switch(*p) { + case ' ': + case '\t': + case '\n': + *q++ = *p++; break; + default: + *q++ = *p++ + b->files - 12; + if(++i >= b->files) { *q++ = '\n'; *q++ = 0; } + } + } + } + *q++ = 0; + strcat(bstring, mylabel); return 0; } /* Experimental ANSI board for colour representation */ static int style13(struct game_state_t *b, struct move_t *ml) { - 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 "}; - 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 "}; + 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 A ", "\033[37m\033[1m C ", "\033[37m\033[1m M ", "\033[37m\033[1m Q ", "\033[37m\033[1m E ", "\033[37m\033[1m K "}; + 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 A ", "\033[21m\033[37m C ", "\033[21m\033[37m M ", "\033[21m\033[37m Q ", "\033[21m\033[37m E ", "\033[21m\033[37m K "}; static const char *wsqr = "\033[40m"; static const char *bsqr = "\033[45m"; static const char *top = "\t+------------------------+\n"; static const char *mid = ""; static const char *start = "|"; static const char *end = "\033[0m|"; - static const char *label = "\t a b c d e f g h\n"; - static const char *blabel = "\t h g f e d c b a\n"; - + static const char *label = "\t a b c d e f g h i j k l\n"; + static const char *blabel = "\t l k j i h g f e d c b a\n"; +return 0; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } /* Standard ICS */ static int style1(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" |", " P |", " N |", " B |", " R |", " Q |", " K |"}; - static const char *bp[] = {" |", " *P|", " *N|", " *B|", " *R|", " *Q|", " *K|"}; + static const char *wp[] = {" |", " P |", " N |", " B |", " R |", " A |", " C |", " M |", " Q |", " E |", " B |", " Q |", + " W |", " H |", " N |", " D |", " H |", " L |", " C |", " S |", " G |", " H |", " A |", " F |", + " E |", " H |", " M |", " S |", " E |", " W |", " O |", " G |", " V |", " S |", " E |", " A |", " K |", " H |", " E |"}; + static const char *bp[] = {" |", " *P|", " *N|", " *B|", " *R|", " *A|", " *C|", " *M|", " *Q|", " *E|", " *B|", " *Q|", + " *W|", " *H|", " *N|", " *D|", " *H|", " *L|", " *C|", " *S|", " *G|", " *H|", " *A|", " *F|", + " *E|", " *H|", " *M|", " *S|", " *E|", " *W|", " *O|", " *G|", " *V|", " *S|", " *E|", " *A|", " *K|", " *H|", " *E|"}; static char *wsqr = ""; static char *bsqr = ""; static char *top = "\t---------------------------------\n"; static char *mid = "\t|---+---+---+---+---+---+---+---|\n"; static char *start = "|"; static char *end = ""; - static char *label = "\t a b c d e f g h\n"; - static char *blabel = "\t h g f e d c b a\n"; + static char *label = "\t a b c d e f g h i j k l\n"; + static char *blabel = "\t l k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -437,16 +595,20 @@ static int style1(struct game_state_t *b, struct move_t *ml) /* USA-Today Sports Center-style board */ static int style2(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {"+ ", "P ", "N ", "B ", "R ", "Q ", "K "}; - static const char *bp[] = {"- ", "p' ", "n' ", "b' ", "r' ", "q' ", "k' "}; + static const char *wp[] = {"- ", "P ", "N ", "B ", "R ", "A ", "C ", "M ", "Q ", "E ", "B ", "Q ", + "W ", "H ", "N ", "D ", "H ", "L ", "C ", "S ", "G ", "H ", "A ", "F ", + "E ", "H ", "M ", "S ", "E ", "W ", "O ", "G ", "V ", "S ", "E ", "A ", "K ", "H ", "E "}; + static const char *bp[] = {"+ ", "p' ", "n' ", "b' ", "r' ", "a' ", "c' ", "m' ", "q' ", "e' ", "b' ", "q' ", + "w' ", "h' ", "n' ", "d' ", "h' ", "l' ", "c' ", "s' ", "g' ", "h' ", "a' ", "f' ", + "e' ", "h' ", "m' ", "s' ", "e' ", "w' ", "o' ", "g' ", "v' ", "s' ", "e' ", "a' ", "k' ", "h' ", "e' "}; static char *wsqr = ""; static char *bsqr = ""; static char *top = ""; static char *mid = ""; static char *start = ""; static char *end = ""; - static char *label = "\ta b c d e f g h\n"; - static char *blabel = "\th g f e d c b a\n"; + static char *label = "\ta b c d e f g h i j k l\n"; + static char *blabel = "\tl k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -454,16 +616,20 @@ static int style2(struct game_state_t *b, struct move_t *ml) /* Experimental vt-100 ANSI board for dark backgrounds */ static int style3(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "}; - static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"}; + static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", + " W ", " H ", " N ", " D ", " H ", " L ", " C ", " S ", " G ", " H ", " A ", " F ", + " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K ", " H ", " E "}; + static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", + " *W", " *H", " *N", " *D", " *H", " *L", " *C", " *S", " *G", " *H", " *A", " *F", + " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K", " *H", " *E"}; static char *wsqr = "\033[0m"; static char *bsqr = "\033[7m"; static char *top = "\t+------------------------+\n"; static char *mid = ""; static char *start = "|"; static char *end = "\033[0m|"; - static char *label = "\t a b c d e f g h\n"; - static char *blabel = "\t h g f e d c b a\n"; + static char *label = "\t a b c d e f g h i j k l\n"; + static char *blabel = "\t l k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -471,16 +637,20 @@ static int style3(struct game_state_t *b, struct move_t *ml) /* Experimental vt-100 ANSI board for light backgrounds */ static int style4(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "}; - static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"}; + static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", + " W ", " H ", " N ", " D ", " H ", " L ", " C ", " S ", " G ", " H ", " A ", " F ", + " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K ", " H ", " E "}; + static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", + " *W", " *H", " *N", " *D", " *H", " *L", " *C", " *S", " *G", " *H", " *A", " *F", + " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K", " *H", " *E"}; static char *wsqr = "\033[7m"; static char *bsqr = "\033[0m"; static char *top = "\t+------------------------+\n"; static char *mid = ""; static char *start = "|"; static char *end = "\033[0m|"; - static char *label = "\t a b c d e f g h\n"; - static char *blabel = "\t h g f e d c b a\n"; + static char *label = "\t a b c d e f g h i j k l\n"; + static char *blabel = "\t l k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -488,16 +658,22 @@ static int style4(struct game_state_t *b, struct move_t *ml) /* Style suggested by ajpierce@med.unc.edu */ static int style5(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" ", " o ", " :N:", " ", " |R|", " {Q}", " =K="}; - static const char *bp[] = {" ", " p ", " :n:", " ", " |r|", " {q}", " =k="}; + static const char *wp[] = {" ", " o ", " :N:", " ", " |R|", " (A)", " [C]", " :M:", " {Q}", " !E!", + " ", " {Q}", " .W.", " :H:", " :N:", " ", " |D|", " |L|", + " |C|", " !S!", " :G:", " :H:", " {A}", " {F}", " !E!", " (H)", " [M]", " :S:", + " !E!", " |W|", " *O*", " {G}", " :V:", " (S)", " [E]", " &A&", " =K=", " (H)", " [E]"}; + static const char *bp[] = {" ", " p ", " :n:", " ", " |r|", " (a)", " [c]", " :m:", " {q}", " !e!", + " ", " {q}", " .w.", " :h:", " :n:", " ", " |d|", " |l|", + " |c|", " !s!", " :g:", " :h:", " {a}", " {f}", " !e!", " (h)", " [m]", " :s:", + " !e!", " |w|", " *o*", " {g}", " :v:", " (s)", " [e]", " &a&", " =k=", " (f)", " [e]"}; static char *wsqr = ""; static char *bsqr = ""; static char *top = " . . . . . . . . .\n"; static char *mid = " . . . . . . . . .\n"; static char *start = ""; static char *end = ""; - static char *label = "\t a b c d e f g h\n"; - static char *blabel = "\t h g f e d c b a\n"; + static char *label = "\t a b c d e f g h i j k l\n"; + static char *blabel = "\t l k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -505,16 +681,23 @@ static int style5(struct game_state_t *b, struct move_t *ml) /* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */ static int style6(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" |", " wp |", " WN |", " WB |", " WR |", " WQ |", " WK |"}; - static const char *bp[] = {" |", " bp |", " BN |", " BB |", " BR |", " BQ |", " BK |"}; + static const char *wp[] = {" |", " wp |", " WN |", " WB |", " WR |", " WA |", " WC |", " WM |", " WQ |", + " WE |", " WB |", " WQ |", " WW |", " WH |", " WN |", " WD |", " WH |", " WL |", + " WC |", " WS |", " WG |", " WH |", " WA |", " WF |", " WE |", " WH |", " WM |", + " WS |", " WE |", " WW |", " WO |", " WG |", " WV |", " WS |", " WE |", " WA |", " WK |", " WH |", " WE |"}; + static const char *bp[] = {" |", " bp |", " BN |", " BB |", " BR |", " BA |", " BC |", " BM |", " BQ |", + " BE |", " BB |", " BQ |", " BW |", " BH |", " BN |", " BD |", " BH |", " BL |", + " BC |", " BS |", " BG |", " BH |", " BA |", " BF |", " BE |", " BH |", " BM |", + " BS |", " BE |", " BW |", " BO |", " BG |", " BV |", " BS |", " BE |", " BA |", " BK |", " BH |", " BE |"}; static char *wsqr = ""; static char *bsqr = ""; static char *top = "\t-----------------------------------------\n"; + static char *mid = "\t-----------------------------------------\n"; static char *start = "|"; static char *end = ""; - static char *label = "\t A B C D E F G H\n"; - static char *blabel = "\t H G F E D C B A\n"; + static char *label = "\t A B C D E F G H I J K L\n"; + static char *blabel = "\t L K J I H G F E D C B A\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -522,16 +705,18 @@ static int style6(struct game_state_t *b, struct move_t *ml) /* Miniature board */ static int style7(struct game_state_t *b, struct move_t *ml) { - static const char *wp[] = {" ", " P", " N", " B", " R", " Q", " K"}; - static const char *bp[] = {" -", " p", " n", " b", " r", " q", " k"}; + static const char *wp[] = {" ", " P", " N", " B", " R", " A", " C", " M", " Q", " E", " B", " Q", " W", " H", " N", " D", " H", " L", + " C", " S", " G", " H", " A", " F", " E", " H", " M", " S", " E", " W", " O", " G", " V", " S", " E", " A", " K", " H", " E"}; + static const char *bp[] = {" -", " p", " n", " b", " r", " a", " c", " m", " q", " e", " b", " q", " w", " h", " n", " d", " h", " l", + " c", " s", " g", " h", " a", " f", " e", " h", " m", " s", " e", " w", " o", " g", " v", " s", " e", " a", " k", " h", " e"}; static char *wsqr = ""; static char *bsqr = ""; static char *top = "\t:::::::::::::::::::::\n"; static char *mid = ""; static char *start = ".."; static char *end = " .."; - static char *label = "\t a b c d e f g h\n"; - static char *blabel = "\t h g f e d c b a\n"; + static char *label = "\t a b c d e f g h i j k l\n"; + static char *blabel = "\t l k j i h g f e d c b a\n"; return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel); } @@ -539,7 +724,7 @@ static int style7(struct game_state_t *b, struct move_t *ml) /* ICS interface maker board-- raw data dump */ static int style8(struct game_state_t *b, struct move_t *ml) { - char tmp[80]; + char tmp[160]; int f, r; int ws, bs; @@ -550,8 +735,8 @@ static int style8(struct game_state_t *b, struct move_t *ml) game_globals.garray[b->gameNum].black_name, (orient == WHITE) ? ":" : "*"); strcat(bstring, tmp); - for (r = 0; r < 8; r++) { - for (f = 0; f < 8; f++) { + for (r = 0; r < b->ranks; r++) { + for (f = 0; f < b->files; f++) { if (b->board[f][r] == NOPIECE) { strcat(bstring, " "); } else { @@ -583,7 +768,7 @@ static int style8(struct game_state_t *b, struct move_t *ml) static int style9(struct game_state_t *b, struct move_t *ml) { int i, count; - char tmp[80]; + char tmp[160]; int startmove; sprintf(tmp, "\nMove %-23s%s\n", @@ -616,15 +801,15 @@ static int style9(struct game_state_t *b, struct move_t *ml) static int style10(struct game_state_t *b, struct move_t *ml) { int f, r; - char tmp[80]; + char tmp[160]; int ws, bs; board_calc_strength(b, &ws, &bs); sprintf(tmp, "<10>\n"); strcat(bstring, tmp); - for (r = 7; r >= 0; r--) { + for (r = b->ranks-1; r >= 0; r--) { strcat(bstring, "|"); - for (f = 0; f < 8; f++) { + for (f = 0; f < b->files; f++) { if (b->board[f][r] == NOPIECE) { strcat(bstring, " "); } else { @@ -645,10 +830,10 @@ static int style10(struct game_state_t *b, struct move_t *ml) } strcat(bstring, tmp); sprintf(tmp, "%d %d %d %d %d\n", - !(b->wkmoved || b->wkrmoved), - !(b->wkmoved || b->wqrmoved), - !(b->bkmoved || b->bkrmoved), - !(b->bkmoved || b->bqrmoved), + (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights + (b->wkmoved >= 0 && b->wqrmoved >= 0), + (b->bkmoved >= 0 && b->bkrmoved >= 0), + (b->bkmoved >= 0 && b->bqrmoved >= 0), (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable))); strcat(bstring, tmp); @@ -683,7 +868,7 @@ static int style10(struct game_state_t *b, struct move_t *ml) /* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */ static int style11(struct game_state_t *b, struct move_t *ml) { - char tmp[80]; + char tmp[160]; int f, r; int ws, bs; @@ -694,8 +879,8 @@ static int style11(struct game_state_t *b, struct move_t *ml) game_globals.garray[b->gameNum].black_name, (orient == WHITE) ? ":" : "*"); strcat(bstring, tmp); - for (r = 0; r < 8; r++) { - for (f = 0; f < 8; f++) { + for (r = 0; r < b->ranks; r++) { + for (f = 0; f < b->files; f++) { if (b->board[f][r] == NOPIECE) { strcat(bstring, " "); } else { @@ -723,17 +908,26 @@ static int style11(struct game_state_t *b, struct move_t *ml) return 0; } + +int kludgeFlag = 0; /* Similar to style 10. See the "style12" help file for information */ static int style12(struct game_state_t *b, struct move_t *ml) { int f, r; - char tmp[80]; - int ws, bs; + char tmp[160]; // [HGM] 80 caused problems with long login names + int ws, bs; + int nhm = kludgeFlag ? 0 : game_globals.garray[b->gameNum].numHalfMoves; + // [HGM] setup: the number of half moves appeared in this routine an enormous number of times, + // and had to be dug out of the game_globals, so that this routine could only be used to print + // a board from a game, and not just any board given by an isolated game_state_t. This was very + // inconvenient for printing initial boards in move lists of shuffle variants, so I added the + // global kludgeFlag to signal that we want to print an initial position, and force nhm = 0. board_calc_strength(b, &ws, &bs); + sprintf(bstring, "<12> "); - for (r = 7; r >= 0; r--) { - for (f = 0; f < 8; f++) { + for (r = b->ranks-1; r >= 0; r--) { + for (f = 0; f < b->files; f++) { if (b->board[f][r] == NOPIECE) { strcat(bstring, "-"); } else { @@ -745,20 +939,21 @@ static int style12(struct game_state_t *b, struct move_t *ml) } strcat(bstring, " "); } + strcat(bstring, (b->onMove == WHITE) ? "W " : "B "); - if (game_globals.garray[b->gameNum].numHalfMoves) { + if (nhm) { sprintf(tmp, "%d ", - ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn); + ml[nhm - 1].doublePawn); } else { sprintf(tmp, "-1 "); } strcat(bstring, tmp); sprintf(tmp, "%d %d %d %d %d ", - !(b->wkmoved || b->wkrmoved), - !(b->wkmoved || b->wqrmoved), - !(b->bkmoved || b->bkrmoved), - !(b->bkmoved || b->bqrmoved), - (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable))); + (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights + (b->wkmoved >= 0 && b->wqrmoved >= 0), + (b->bkmoved >= 0 && b->bkrmoved >= 0), + (b->bkmoved >= 0 && b->bqrmoved >= 0), + (nhm - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable))); strcat(bstring, tmp); sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n", b->gameNum + 1, @@ -771,15 +966,15 @@ static int style12(struct game_state_t *b, struct move_t *ml) bs, (wTime / 10), (bTime / 10), - game_globals.garray[b->gameNum].numHalfMoves / 2 + 1, - game_globals.garray[b->gameNum].numHalfMoves ? - ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString : + nhm / 2 + 1, + nhm ? + ml[nhm - 1].moveString : "none", - game_globals.garray[b->gameNum].numHalfMoves ? - tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) : + nhm ? + tenth_str(ml[nhm - 1].tookTime, 0) : "0:00", - game_globals.garray[b->gameNum].numHalfMoves ? - ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString : + nhm ? + ml[nhm - 1].algString : "none", (orient == WHITE) ? 0 : 1, b->moveNum > 1 ? 1 : 0); /* ticking */ @@ -802,6 +997,7 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) return 1; board_clear(gs); + gs->setup = 1; while (!feof(fp)) { c = fgetc(fp); if (onNewLine) { @@ -813,6 +1009,65 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) onColor = BLACK; if (gs->onMove < 0) gs->onMove = BLACK; + } else if (c == 'S') { int f=8, r=8; + // [HGM] rules: read rule modifiers + fscanf(fp, "%dx%d", &f, &r); gs->files=f; gs->ranks = r; + while (!feof(fp) && c != '\n') { + c = fgetc(fp); + switch(c) { + case 'r': + gs->royalKnight = 1; + break; + case 'c': + gs->capablancaPieces = 1; + break; + case 'd': + gs->drops = 1; + break; + case 'g': + gs->drops = 2; + break; + case 'h': + gs->holdings = -1; // color-flip holdings + break; + case 'p': + gs->palace = 3; + break; + case 'P': + gs->promoType = 2; // only promote to captured pieces + gs->holdings = 1; // use holdings to hold own captured pieces + break; + case 'S': + gs->promoType = 3; // Shogi-type promotions + break; + case 'Z': + gs->promoZone = 3; // for Grand Chess + gs->pawnDblStep = 2; + break; + case 'F': + gs->castlingStyle = 2; // FRC castling + break; + case 'w': + gs->castlingStyle = 1; // wild castling, from both center files + break; + case 'n': + gs->castlingStyle = 0; // no castling + break; + case 'f': + gs->castlingStyle = 3; // free castling + break; + case 'D': + gs->pawnDblStep = 0; // suppress pawn double step + break; + case 'b': + gs->bareKingLoses = 1; // apply baring rule + break; + case 's': + gs->stalemate = 0; // stalemate loses + break; + } + } + continue; } else if (c == '#') { while (!feof(fp) && c != '\n') c = fgetc(fp); /* Comment line */ @@ -837,12 +1092,99 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) case 'B': onPiece = BISHOP; break; + case 'A': + onPiece = CARDINAL; + break; + case 'C': + onPiece = MARSHALL; + break; + case 'M': + onPiece = MAN; + break; case 'Q': onPiece = QUEEN; break; + case 'T': + onPiece = ELEPHANT; + break; + case 'E': + onPiece = ALFIL; + break; + case 't': + onPiece = ALFIL2; + break; + case 'q': + onPiece = FERZ; + break; + case 'F': + onPiece = FERZ2; + break; + case 'W': + onPiece = WAZIR; + break; + case 'w': + onPiece = WOODY; + break; + case 'p': + onPiece = PRIESTESS; + break; + case 'r': + onPiece = MINISTER; + break; + case 'z': + onPiece = MAN2; + break; + case 'u': + onPiece = NIGHTRIDER; + break; + case 'o': + onPiece = MODERNELEPHANT; + break; + case 's': + onPiece = MASTODON; + break; + case 'Z': + onPiece = AMAZON; + break; + case 'V': + onPiece = CENTAUR; + break; + case 'H': + onPiece = HORSE; + break; + case 'n': + onPiece = HONORABLEHORSE; + break; + case 'J': + onPiece = DRAGONKING; + break; + case 'I': + onPiece = DRAGONHORSE; + break; + case 'L': + onPiece = LANCE; + break; + case 'O': + onPiece = CANNON; + break; + case 'S': + onPiece = SILVER; + break; + case 'G': + onPiece = GOLD; + break; + case 'm': + onPiece = MANDARIN; + break; case 'K': onPiece = KING; break; + case 'D': + onPiece = SELEPHANT; + break; + case 'U': + onPiece = HAWK; + break; case 'a': case 'b': case 'c': @@ -851,9 +1193,18 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) case 'f': case 'g': case 'h': + case 'i': + case 'j': + case 'k': + case 'l': onFile = c - 'a'; + if(onFile >= gs->files) { onFile = -1; break; } onRank = -1; break; + case '@': + if (onColor >= 0 && onPiece >= 0) // allow placement in holdings + gs->holding[onColor == BLACK][onPiece-1]++; + break; case '1': case '2': case '3': @@ -862,7 +1213,10 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) case '6': case '7': case '8': - onRank = c - '1'; + case '9': + case '0': + onRank = c - '1' + (gs->ranks > 9); + if(onRank < 0 || onRank >= gs->ranks) { onRank = -1; break; } if (onFile >= 0 && onColor >= 0 && onPiece >= 0) gs->board[onFile][onRank] = onPiece | onColor; break; @@ -890,8 +1244,8 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs) #define ANY_SQUARE -1 #define SquareColor(f, r) ((f ^ r) & 1) -static void place_piece(board_t b, int piece, int squareColor) -{ +static void place_piece(board_t b, int piece, int squareColor, int width) +{ //[HGM] board: make width a variable int r, f; int placed = 0; @@ -902,9 +1256,9 @@ static void place_piece(board_t b, int piece, int squareColor) while (!placed) { if (squareColor == ANY_SQUARE) { - f = random() % 8; + f = random() % width; } else { - f = (random() % 4) * 2; + f = (random() % ((width+1)/2)) * 2; // to not overflow odd-width boards if (SquareColor(f, r) != squareColor) f++; } @@ -915,12 +1269,11 @@ static void place_piece(board_t b, int piece, int squareColor) } } -static void wild_update(int style) +static void wild_update(board_t b, int style) { - int f, r, i; - board_t b; + int f, r, i, j; - for (f = 0; f < 8; f++) + for (f = 0; f < BW; f++) // [HGM] board: make sure also works with wider boards for (r = 0; r < 8; r++) b[f][r] = NOPIECE; for (f = 0; f < 8; f++) { @@ -947,24 +1300,24 @@ static void wild_update(int style) b[0][7] = b[7][7] = B_ROOK; /* Must do bishops before knights to be sure opposite colored squares are available. */ - place_piece(b, W_BISHOP, WHITE_SQUARE); - place_piece(b, W_BISHOP, BLACK_SQUARE); - place_piece(b, W_KNIGHT, ANY_SQUARE); - place_piece(b, W_KNIGHT, ANY_SQUARE); - place_piece(b, B_BISHOP, WHITE_SQUARE); - place_piece(b, B_BISHOP, BLACK_SQUARE); - place_piece(b, B_KNIGHT, ANY_SQUARE); - place_piece(b, B_KNIGHT, ANY_SQUARE); + place_piece(b, W_BISHOP, WHITE_SQUARE, 8); + place_piece(b, W_BISHOP, BLACK_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); + place_piece(b, B_BISHOP, WHITE_SQUARE, 8); + place_piece(b, B_BISHOP, BLACK_SQUARE, 8); + place_piece(b, B_KNIGHT, ANY_SQUARE, 8); + place_piece(b, B_KNIGHT, ANY_SQUARE, 8); break; case 2: - place_piece(b, W_KING, ANY_SQUARE); - place_piece(b, W_QUEEN, ANY_SQUARE); - place_piece(b, W_ROOK, ANY_SQUARE); - place_piece(b, W_ROOK, ANY_SQUARE); - place_piece(b, W_BISHOP, ANY_SQUARE); - place_piece(b, W_BISHOP, ANY_SQUARE); - place_piece(b, W_KNIGHT, ANY_SQUARE); - place_piece(b, W_KNIGHT, ANY_SQUARE); + place_piece(b, W_KING, ANY_SQUARE, 8); + place_piece(b, W_QUEEN, ANY_SQUARE, 8); + place_piece(b, W_ROOK, ANY_SQUARE, 8); + place_piece(b, W_ROOK, ANY_SQUARE, 8); + place_piece(b, W_BISHOP, ANY_SQUARE, 8); + place_piece(b, W_BISHOP, ANY_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); /* Black mirrors White */ for (i = 0; i < 8; i++) { b[i][7] = b[i][0] | BLACK; @@ -972,7 +1325,7 @@ static void wild_update(int style) break; case 3: /* Generate White king on random square plus random set of pieces */ - place_piece(b, W_KING, ANY_SQUARE); + place_piece(b, W_KING, ANY_SQUARE, 8); for (i = 0; i < 8; i++) { if (b[i][0] != W_KING) { b[i][0] = (random() % 4) + 2; @@ -985,7 +1338,7 @@ static void wild_update(int style) break; case 4: /* Generate White king on random square plus random set of pieces */ - place_piece(b, W_KING, ANY_SQUARE); + place_piece(b, W_KING, ANY_SQUARE, 8); for (i = 0; i < 8; i++) { if (b[i][0] != W_KING) { b[i][0] = (random() % 4) + 2; @@ -997,15 +1350,47 @@ static void wild_update(int style) to be sure there are enough squares left of the correct color. */ for (i = 0; i < 8; i++) { if (b[i][0] == W_BISHOP) { - place_piece(b, B_BISHOP, !SquareColor(i, 0)); + place_piece(b, B_BISHOP, !SquareColor(i, 0), 8); } } for (i = 0; i < 8; i++) { if (b[i][0] != W_BISHOP) { - place_piece(b, b[i][0] | BLACK, ANY_SQUARE); + place_piece(b, b[i][0] | BLACK, ANY_SQUARE, 8); } } break; + case 22: + /* Chess960 placement: King between R */ + place_piece(b, W_BISHOP, WHITE_SQUARE, 8); + place_piece(b, W_BISHOP, BLACK_SQUARE, 8); + place_piece(b, W_QUEEN, ANY_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); + place_piece(b, W_KNIGHT, ANY_SQUARE, 8); + for (i = j = 0; i < 8; i++) { + if(b[i][0] == NOPIECE) b[i][0] = (j++ == 1 ? W_KING : W_ROOK); + } + /* Black mirrors White */ + for (i = 0; i < 8; i++) { + b[i][7] = b[i][0] | BLACK; + } + break; + case 46: + /* Chess960 placement: King between R */ + place_piece(b, W_BISHOP, WHITE_SQUARE, 10); + place_piece(b, W_BISHOP, BLACK_SQUARE, 10); + place_piece(b, W_QUEEN, ANY_SQUARE, 10); + place_piece(b, W_MARSHALL, ANY_SQUARE, 10); + place_piece(b, W_CARDINAL, ANY_SQUARE, 10); + place_piece(b, W_KNIGHT, ANY_SQUARE, 10); + place_piece(b, W_KNIGHT, ANY_SQUARE, 10); + for (i = j = 0; i < 10; i++) { + if(b[i][0] == NOPIECE) j++ == 1 ? W_KING : W_ROOK; + } + /* Black mirrors White */ + for (i = 0; i < 10; i++) { + b[i][7] = b[i][0] | BLACK; + } + break; default: return; break; @@ -1048,9 +1433,10 @@ static void wild_update(int style) void wild_init(void) { - wild_update(1); - wild_update(2); - wild_update(3); - wild_update(4); + board_t b; + wild_update(b, 1); + wild_update(b, 2); + wild_update(b, 3); + wild_update(b, 4); }