Finish implementation of Shogi
[capablanca.git] / lasker-2.2.3 / src / board.c
index 8fdbb0e..315df34 100644 (file)
 #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", "J", "I", "L", 
+                         "C", "S", "G", "H", "A", "F", "E", "H", "M", "S", "E", "W", "O", "G", "V", "S", "E", "A", "K"};
+const char *bpstring[] = {" ", "p", "n", "b", "r", "a", "c", "m", "q", "e", "b", "q", "w", "h", "n", "j", "i", "l", 
+                         "c", "s", "g", "h", "a", "f", "e", "h", "m", "s", "e", "w", "o", "g", "v", "s", "e", "a", "k"};
 
-static int pieceValues[7] = {0, 1, 3, 3, 5, 9, 0};
+int pieceValues[KING+1] = {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};
 
 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 <= KING-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,141 @@ void board_standard(struct game_state_t *gs)
 {
  int f,r;
 
- for (f = 0; f < 8; f++)
-    for (r = 2; r < 6; r++)
-      gs->board[f][r] = NOPIECE;
- for (f = 0; f < 8; f++)
-   gs->board[f][1] = W_PAWN;
- for (f = 0; f < 8; 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;
+ for (f = 0; f < BW; f++)\r
+    for (r = 0; r < BH; r++)\r
+      gs->board[f][r] = NOPIECE;\r
+ for (f = 0; f < gs->files; f++)\r
+   gs->board[f][gs->ranks-7] = W_PAWN;\r
+ for (f = 0; f < gs->files; f++)\r
+   gs->board[f][6] = B_PAWN;\r
+ gs->board[0][0] = W_ROOK;\r
+ gs->board[1][0] = W_KNIGHT;\r
+ gs->board[2][0] = W_BISHOP; \r
+ gs->board[3][0] = W_QUEEN;\r
+ gs->board[gs->files/2][0] = W_KING;\r
+ gs->board[gs->files-3][0] = W_BISHOP;\r
+ gs->board[gs->files-2][0] = W_KNIGHT;\r
+ gs->board[gs->files-1][0] = W_ROOK;\r
+ gs->board[0][gs->ranks-1] = B_ROOK;\r
+ gs->board[1][gs->ranks-1] = B_KNIGHT;\r
+ gs->board[2][gs->ranks-1] = B_BISHOP;\r
+ gs->board[3][gs->ranks-1] = B_QUEEN;\r
+ gs->board[gs->files/2][gs->ranks-1] = B_KING;\r
+ gs->board[gs->files-3][gs->ranks-1] = B_BISHOP;\r
+ gs->board[gs->files-2][gs->ranks-1] = B_KNIGHT;\r
+ gs->board[gs->files-1][gs->ranks-1] = B_ROOK;\r
+#if 1
+ if(gs->files == 10) {\r
+  gs->board[6][0] = W_CARDINAL;\r
+  gs->board[4][0] = W_MARSHALL;\r
+  gs->board[6][gs->ranks-1] = B_CARDINAL;\r
+  gs->board[4][gs->ranks-1] = B_MARSHALL;\r
+ }\r
+ if(gs->royalKnight) {\r
+   gs->board[1][0] = W_MAN;\r
+   gs->board[gs->files-2][0] = W_MAN;\r
+   gs->board[1][gs->ranks-1] = B_MAN;\r
+   gs->board[gs->files-2][gs->ranks-1] = B_MAN;\r
+ }\r
+#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;
-
-  if (!category || !board || !category[0] || !board[0]) 
-                               /* accounts for bughouse too */
-    board_standard(b);
+  int wval, i, j;
+
+  b->files = b->ranks = 8;\r
+  b->pawnDblStep = (!category || strcmp(category, "shatranj")); \r
+  b->royalKnight = (category && !strcmp(category, "knightmate"));\r
+  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->variant[0] = 0; // [HGM] variant: default is normal, if variant name is missing\r
+  if (!category || !board || !category[0] || !board[0]) \r
+                               /* accounts for bughouse too */\r
+    board_standard(b);\r
   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\r
+    if (!strcmp(category, "wild") && sscanf(board, "%d", &wval) == 1) {
+       if(wval >= 1 && wval <= 4)\r
+            wild_update(b->board, wval);
+       sprintf(b->variant, "wild/%d", wval);\r
+    }
+
+    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\r
+
+    if (!strcmp(category, "knightmate")) {\r
+      board_standard(b);\r
+    } else if (!strcmp(category, "super")) {\r
+      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;\r
+    } else if (!strcmp(category, "fischerandom")) {\r
+      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\r
+    } else if (!strcmp(category, "caparandom")) {
+      b->files = 10;\r
+      wild_update(b->board, 46);
+      b->castlingStyle = 2;
+      b->setup = 1; \r
+    } else retval = board_read_file(category, board, b); \r
+  }
+  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;
+       }
+      }
+    }
   }
+\r
   MakeFENpos(g, game_globals.garray[g].FENstartPos);
+
   return retval;
 }
 
@@ -150,8 +247,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 +256,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 < KING; r++) {
     *ws += b->holding[0][r-1] * pieceValues[r];
     *bs += b->holding[1][r-1] * pieceValues[r];
   }
@@ -167,11 +264,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 < KING; p++) {
                for (j = 0; j < holding[p-1]; j++) {
                        tmp[i++] = wpstring[p][0];
                }
@@ -183,7 +280,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, "<b1> game %d white [%s] black [", g+1, holding_str(gs->holding[0]));
   strcat(tmp, holding_str(gs->holding[1]));
@@ -213,7 +310,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 +348,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 ); // [HGM] zh: make sure holdings are printed
   orient = orientation;
   myTurn = relation;
 
@@ -262,6 +360,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 +387,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,490 +403,582 @@ 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; i<w; i++) {
+    l = strlen(a);
+    p = a + l; q = p + ss;
+    while(q != a+l-ss) *q-- = *p--;
+  }
+}
+
 static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[], const char *bp[],
                    const char *wsqr, const char *bsqr,
                    const char *top, const char *mid, const char *start, const char *end, 
                    const char *label,const char *blabel)
 {
-  int f, r, count;
-  char tmp[80];
-  int first, last, inc;
-  int ws, bs;
-
-  board_calc_strength(b, &ws, &bs);
-  if (orient == WHITE) {
-    first = 7;
-    last = 0;
-    inc = -1;
-  } else {
-    first = 0;
-    last = 7;
-    inc = 1;
+  int f, r, count, i;\r
+  char tmp[80], mylabel[80], *p, *q, myTop[80], myMid[80];\r
+  int firstR, lastR, firstF, lastF, inc;\r
+  int ws, bs, sqrSize = strlen(wp[0]);\r
+\r
+  board_calc_strength(b, &ws, &bs);\r
+  if (orient == WHITE) {\r
+    firstR = b->ranks-1;\r
+    firstF = b->files-1;\r
+    lastR = lastF = 0;\r
+    inc = -1;\r
+  } else {\r
+    firstR = firstF = 0;\r
+    lastR = b->ranks-1;\r
+    lastF = b->files-1;\r
+    inc = 1;\r
   }
-  strcat(bstring, top);
-  for (f = first, count = 7; f != last + inc; f += inc, count--) {
-    sprintf(tmp, "     %d  %s", f + 1, start);
-    strcat(bstring, tmp);
-    for (r = last; r != first - inc; r = r - inc) {
-      if (square_color(r, f) == WHITE)
-       strcat(bstring, wsqr);
-      else
-       strcat(bstring, bsqr);
-      if (piecetype(b->board[r][f]) == NOPIECE) {
-       if (square_color(r, f) == WHITE)
-         strcat(bstring, bp[0]);
-       else
-         strcat(bstring, wp[0]);
+  strcpy(myTop, top);
+  strcpy(myMid, mid);
+  Enlarge(myTop, sqrSize, b->files);\r
+  Enlarge(myMid, sqrSize, b->files);\r
+  strcat(bstring, myTop);\r
+  for (f = firstR, count = b->ranks-1; f != lastR + inc; f += inc, count--) {\r
+    sprintf(tmp, "     %d  %s", f + (b->ranks < 10), start);\r
+    strcat(bstring, tmp);\r
+    for (r = lastF; r != firstF - inc; r = r - inc) {\r
+      if (square_color(r, f) == WHITE)\r
+       strcat(bstring, wsqr);\r
+      else\r
+       strcat(bstring, bsqr);\r
+      if (piecetype(b->board[r][f]) == NOPIECE) {\r
+       if (square_color(r, f) == WHITE)\r
+         strcat(bstring, bp[0]);\r
+       else\r
+         strcat(bstring, wp[0]);\r
       } else {
-       if (colorval(b->board[r][f]) == WHITE)
-         strcat(bstring, wp[piecetype(b->board[r][f])]);
-       else
-         strcat(bstring, bp[piecetype(b->board[r][f])]);
-      }
-    }
-    sprintf(tmp, "%s", end);
-    strcat(bstring, tmp);
-    switch (count) {
-    case 7:
-      sprintf(tmp, "     Move # : %d (%s)", b->moveNum, CString(b->onMove));
-      strcat(bstring, tmp);
-      break;
-    case 6:
-/*    if ((b->moveNum > 1) || (b->onMove == BLACK)) {  */
-/* The change from the above line to the one below is a kludge by hersco. */
-      if (game_globals.garray[b->gameNum].numHalfMoves > 0) {
-/* loon: think this fixes the crashing ascii board on takeback bug */
-       sprintf(tmp, "     %s Moves : '%s'", CString(CToggle(b->onMove)),
-               move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));
-       strcat(bstring, tmp);
-      }
-      break;
-    case 5:
-      break;
-    case 4:
-      sprintf(tmp, "     Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));
-      strcat(bstring, tmp);
-      break;
-    case 3:
-      sprintf(tmp, "     White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));
-      strcat(bstring, tmp);
-      break;
-    case 2:
-      sprintf(tmp, "     Black Strength : %d", bs);
-      strcat(bstring, tmp);
-      break;
-    case 1:
-      sprintf(tmp, "     White Strength : %d", ws);
-      strcat(bstring, tmp);
-      break;
-    case 0:
-      break;
-    }
-    strcat(bstring, "\n");
-    if (count != 0)
-      strcat(bstring, mid);
-    else
-      strcat(bstring, top);
-  }
-  if (orient == WHITE)
-    strcat(bstring, label);
-  else
-    strcat(bstring, blabel);
-  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 *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";
-
-  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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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:", " <B>", " |R|", " {Q}", " =K="};
-  static const char *bp[] = {"    ", "  p ", " :n:", " <b>", " |r|", " {q}", " =k="};
-  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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* 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 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";
-
-  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
-}
-
-/* ICS interface maker board-- raw data dump */
-static int style8(struct game_state_t *b, struct move_t *ml)
-{
-  char tmp[80];
-  int f, r;
-  int ws, bs;
-
-  board_calc_strength(b, &ws, &bs);
-  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,
-         game_globals.garray[b->gameNum].white_name,
-         (orient == WHITE) ? "*" : ":",
-         game_globals.garray[b->gameNum].black_name,
-         (orient == WHITE) ? ":" : "*");
-  strcat(bstring, tmp);
-  for (r = 0; r < 8; r++) {
-    for (f = 0; f < 8; f++) {
-      if (b->board[f][r] == NOPIECE) {
-       strcat(bstring, " ");
-      } else {
-       if (colorval(b->board[f][r]) == WHITE)
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
-       else
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
-      }
-    }
-  }
-  sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
-         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
-         (b->onMove == WHITE) ? "W" : "B",
-         ws,
-         bs,
-         (wTime + 5) / 10,
-         (bTime + 5) / 10,
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
-         "none",
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
-         "0:00");
-  strcat(bstring, tmp);
-  return 0;
-}
-
-/* last 2 moves only (previous non-verbose mode) */
-static int style9(struct game_state_t *b, struct move_t *ml)
-{
-  int i, count;
-  char tmp[80];
-  int startmove;
-
-  sprintf(tmp, "\nMove     %-23s%s\n",
-         game_globals.garray[b->gameNum].white_name,
-         game_globals.garray[b->gameNum].black_name);
-  strcat(bstring, tmp);
-  sprintf(tmp, "----     --------------         --------------\n");
-  strcat(bstring, tmp);
-  startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;
-  if (startmove < 0)
-    startmove = 0;
-  for (i = startmove, count = 0;
-       i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;
-       i++, count++) {
-    if (!(i & 0x01)) {
-      sprintf(tmp, "  %2d     ", i / 2 + 1);
-      strcat(bstring, tmp);
-    }
-    sprintf(tmp, "%-23s", move_and_time(&ml[i]));
-    strcat(bstring, tmp);
-    if (i & 0x01)
-      strcat(bstring, "\n");
-  }
-  if (i & 0x01)
-    strcat(bstring, "\n");
-  return 0;
-}
-
-/* Sleator's 'new and improved' raw dump format... */
-static int style10(struct game_state_t *b, struct move_t *ml)
-{
-  int f, r;
-  char tmp[80];
-  int ws, bs;
-
-  board_calc_strength(b, &ws, &bs);
-  sprintf(tmp, "<10>\n");
-  strcat(bstring, tmp);
-  for (r = 7; r >= 0; r--) {
-    strcat(bstring, "|");
-    for (f = 0; f < 8; f++) {
-      if (b->board[f][r] == NOPIECE) {
-       strcat(bstring, " ");
-      } else {
-       if (colorval(b->board[f][r]) == WHITE)
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
-       else
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
-      }
+       int piece = piecetype(b->board[r][f]);
+//     if(piece > QUEEN) piece = ELEPHANT + (piece == KING); // All fairies become elephants in ascii styles\r
+       if (colorval(b->board[r][f]) == WHITE)\r
+         strcat(bstring, wp[piece]);\r
+       else\r
+         strcat(bstring, bp[piece]);\r
+      }\r
+    }\r
+    sprintf(tmp, "%s", end);\r
+    strcat(bstring, tmp);\r
+    switch (count) {\r
+    case 7:\r
+      sprintf(tmp, "     Move # : %d (%s)", b->moveNum, CString(b->onMove));\r
+      strcat(bstring, tmp);\r
+      break;\r
+    case 6:\r
+/*    if ((b->moveNum > 1) || (b->onMove == BLACK)) {  */\r
+/* The change from the above line to the one below is a kludge by hersco. */\r
+      if (game_globals.garray[b->gameNum].numHalfMoves > 0) {\r
+/* loon: think this fixes the crashing ascii board on takeback bug */\r
+       sprintf(tmp, "     %s Moves : '%s'", CString(CToggle(b->onMove)),\r
+               move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));\r
+       strcat(bstring, tmp);\r
+      }\r
+      break;\r
+    case 5:\r
+      break;\r
+    case 4:\r
+      sprintf(tmp, "     Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));\r
+      strcat(bstring, tmp);\r
+      break;\r
+    case 3:\r
+      sprintf(tmp, "     White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));\r
+      strcat(bstring, tmp);\r
+      break;\r
+    case 2:\r
+      sprintf(tmp, "     Black Strength : %d", bs);\r
+      strcat(bstring, tmp);\r
+      break;\r
+    case 1:\r
+      sprintf(tmp, "     White Strength : %d", ws);\r
+      strcat(bstring, tmp);\r
+      break;\r
+    case 0:\r
+      break;\r
+    }\r
+    strcat(bstring, "\n");\r
+    if (count != 0)\r
+      strcat(bstring, myMid);\r
+    else\r
+      strcat(bstring, myTop);\r
+  }\r
+  q = mylabel; i = 0;
+  if (orient == WHITE) {\r
+    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++;
+       }
     }
-    strcat(bstring, "|\n");
-  }
-  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
-  if (game_globals.garray[b->gameNum].numHalfMoves) {
-    sprintf(tmp, "%d ",
-           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
   } else {
-    sprintf(tmp, "-1 ");
-  }
-  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),
-       (game_globals.garray[b->gameNum].numHalfMoves - ((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\n",
-         b->gameNum,
-         game_globals.garray[b->gameNum].white_name,
-         game_globals.garray[b->gameNum].black_name,
-         myTurn,
-         game_globals.garray[b->gameNum].wInitTime / 600,
-         game_globals.garray[b->gameNum].wIncrement / 10,
-         ws,
-         bs,
-         (wTime + 5) / 10,
-         (bTime + 5) / 10,
-         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
-         "none",
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
-         "0:00",
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
-         "none",
-         (orient == WHITE) ? 0 : 1);
-  strcat(bstring, tmp);
-  sprintf(tmp, ">10<\n");
-  strcat(bstring, tmp);
-  return 0;
-}
-
-/* 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];
-  int f, r;
-  int ws, bs;
-
-  board_calc_strength(b, &ws, &bs);
-  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,
-         game_globals.garray[b->gameNum].white_name,
-         (orient == WHITE) ? "*" : ":",
-         game_globals.garray[b->gameNum].black_name,
-         (orient == WHITE) ? ":" : "*");
-  strcat(bstring, tmp);
-  for (r = 0; r < 8; r++) {
-    for (f = 0; f < 8; f++) {
-      if (b->board[f][r] == NOPIECE) {
-       strcat(bstring, " ");
-      } else {
-       if (colorval(b->board[f][r]) == WHITE)
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
-       else
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
-      }
-    }
-  }
-    sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
-           game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
-           (b->onMove == WHITE) ? "W" : "B",
-           ws,
-           bs,
-           (wTime + 5) / 10,
-           (bTime + 5) / 10,
-           game_globals.garray[b->gameNum].numHalfMoves ?
-           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
-           "none",
-           game_globals.garray[b->gameNum].numHalfMoves ?
-           tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
-           "0:00");
-  strcat(bstring, tmp);
-  return 0;
+    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; }
+       }
+    }\r
+  }\r
+  *q++ = 0;
+  strcat(bstring, mylabel);\r
+  return 0;\r
 }
 
-/* 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;
-
-  board_calc_strength(b, &ws, &bs);
-  sprintf(bstring, "<12> ");
-  for (r = 7; r >= 0; r--) {
-    for (f = 0; f < 8; f++) {
-      if (b->board[f][r] == NOPIECE) {
-       strcat(bstring, "-");
-      } else {
-       if (colorval(b->board[f][r]) == WHITE)
-         strcat(bstring, wpstring[piecetype(b->board[f][r])]);
-       else
-         strcat(bstring, bpstring[piecetype(b->board[f][r])]);
-      }
-    }
-    strcat(bstring, " ");
-  }
-  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
-  if (game_globals.garray[b->gameNum].numHalfMoves) {
-    sprintf(tmp, "%d ",
-           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
-  } else {
-    sprintf(tmp, "-1 ");
+/* Experimental ANSI board for colour representation */\r
+static int style13(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  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 "};\r
+  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 "};\r
+  static const char *wsqr = "\033[40m";\r
+  static const char *bsqr = "\033[45m";\r
+  static const char *top = "\t+------------------------+\n";\r
+  static const char *mid = "";\r
+  static const char *start = "|";\r
+  static const char *end = "\033[0m|";\r
+  static const char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
+  static const char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
+return 0;\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Standard ICS */\r
+static int style1(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"   |", " P |", " N |", " B |", " R |", " A |", " C |", " M |", " Q |", " E |", " B |", " Q |", 
+                            " W |", " H |", " N |", " J |", " I |", " L |", " C |", " S |", " G |", " H |", " A |", " F |",
+                            " E |", " H |", " M |", " S |", " E |", " W |", " O |", " G |", " V |", " S |", " E |", " A |", " K |"};
+  static const char *bp[] = {"   |", " *P|", " *N|", " *B|", " *R|", " *A|", " *C|", " *M|", " *Q|", " *E|", " *B|", " *Q|", 
+                            " *W|", " *H|", " *N|", " *J|", " *I|", " *L|", " *C|", " *S|", " *G|", " *H|", " *A|", " *F|",
+                            " *E|", " *H|", " *M|", " *S|", " *E|", " *W|", " *O|", " *G|", " *V|", " *S|", " *E|", " *A|", " *K|"};
+  static char *wsqr = "";\r
+  static char *bsqr = "";\r
+  static char *top = "\t---------------------------------\n";\r
+  static char *mid = "\t|---+---+---+---+---+---+---+---|\n";\r
+  static char *start = "|";\r
+  static char *end = "";\r
+  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";\r
+  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* USA-Today Sports Center-style board */\r
+static int style2(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"-  ", "P  ", "N  ", "B  ", "R  ", "A  ", "C  ", "M  ", "Q  ", "E  ", "B  ", "Q  ",
+                            "W  ", "H  ", "N  ", "J  ", "I  ", "L  ", "C  ", "S  ", "G  ", "H  ", "A  ", "F  ",
+                            "E  ", "H  ", "M  ", "S  ", "E  ", "W  ", "O  ", "G  ", "V  ", "S  ", "E  ", "A  ", "K  "};
+  static const char *bp[] = {"+  ", "p' ", "n' ", "b' ", "r' ", "a' ", "c' ", "m' ", "q' ", "e' ", "b' ", "q' ",
+                            "w' ", "h' ", "n' ", "j' ", "i' ", "l' ", "c' ", "s' ", "g' ", "h' ", "a' ", "f' ",
+                            "e' ", "h' ", "m' ", "s' ", "e' ", "w' ", "o' ", "g' ", "v' ", "s' ", "e' ", "a' ", "k' "};
+  static char *wsqr = "";\r
+  static char *bsqr = "";\r
+  static char *top = "";\r
+  static char *mid = "";\r
+  static char *start = "";\r
+  static char *end = "";\r
+  static char *label = "\ta  b  c  d  e  f  g  h  i  j  k  l\n";\r
+  static char *blabel = "\tl  k  j  i  h  g  f  e  d  c  b  a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Experimental vt-100 ANSI board for dark backgrounds */\r
+static int style3(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"   ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", 
+                            " W ", " H ", " N ", " J ", " I ", " L ", " C ", " S ", " G ", " H ", " A ", " F ",
+                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K "};
+  static const char *bp[] = {"   ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", 
+                            " *W", " *H", " *N", " *J", " *I", " *L", " *C", " *S", " *G", " *H", " *A", " *F",
+                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K"};
+  static char *wsqr = "\033[0m";\r
+  static char *bsqr = "\033[7m";\r
+  static char *top = "\t+------------------------+\n";\r
+  static char *mid = "";\r
+  static char *start = "|";\r
+  static char *end = "\033[0m|";\r
+  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
+  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Experimental vt-100 ANSI board for light backgrounds */\r
+static int style4(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"   ", " P ", " N ", " B ", " R ", " A ", " C ", " M ", " Q ", " E ", " B ", " Q ", 
+                            " W ", " H ", " N ", " J ", " I ", " L ", " C ", " S ", " G ", " H ", " A ", " F ",
+                            " E ", " H ", " M ", " S ", " E ", " W ", " O ", " G ", " V ", " S ", " E ", " A ", " K "};
+  static const char *bp[] = {"   ", " *P", " *N", " *B", " *R", " *A", " *C", " *M", " *Q", " *E", " *B", " *Q", 
+                            " *W", " *H", " *N", " *J", " *I", " *L", " *C", " *S", " *G", " *H", " *A", " *F",
+                            " *E", " *H", " *M", " *S", " *E", " *W", " *O", " *G", " *V", " *S", " *E", " *A", " *K"};
+  static char *wsqr = "\033[7m";\r
+  static char *bsqr = "\033[0m";\r
+  static char *top = "\t+------------------------+\n";\r
+  static char *mid = "";\r
+  static char *start = "|";\r
+  static char *end = "\033[0m|";\r
+  static char *label = "\t  a  b  c  d  e  f  g  h  i  j  k  l\n";\r
+  static char *blabel = "\t  l  k  j  i  h  g  f  e  d  c  b  a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Style suggested by ajpierce@med.unc.edu */\r
+static int style5(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"    ", "  o ", " :N:", " <B>", " |R|", " (A)", " [C]", " :M:", " {Q}", " !E!",
+                            " <B>", " {Q}", " .W.", " :H:", " :N:", " <J>", " |I|", " |L|", 
+                            " |C|", " !S!", " :G:", " :H:", " {A}", " {F}", " !E!", " (H)", " [M]", " :S:",
+                            " !E!", " |W|", " *O*", " {G}", " :V:", " (S)", " [E]", " &A&", " =K="};
+  static const char *bp[] = {"    ", "  p ", " :n:", " <b>", " |r|", " (a)", " [c]", " :m:", " {q}", " !e!",
+                            " <b>", " {q}", " .w.", " :h:", " :n:", " <j>", " |i|", " |l|", 
+                            " |c|", " !s!", " :g:", " :h:", " {a}", " {f}", " !e!", " (h)", " [m]", " :s:",
+                            " !e!", " |w|", " *o*", " {g}", " :v:", " (s)", " [e]", " &a&", " =k="};
+  static char *wsqr = "";\r
+  static char *bsqr = "";\r
+  static char *top = "        .   .   .   .   .   .   .   .   .\n";\r
+  static char *mid = "        .   .   .   .   .   .   .   .   .\n";\r
+  static char *start = "";\r
+  static char *end = "";\r
+  static char *label = "\t  a   b   c   d   e   f   g   h   i   j   k   l\n";\r
+  static char *blabel = "\t  l   k   j   i   h   g   f   e   d   c   b   a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */\r
+static int style6(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"    |", " wp |", " WN |", " WB |", " WR |", " WA |", " WC |", " WM |", " WQ |", 
+                            " WE |", " WB |", " WQ |", " WW |", " WH |", " WN |", " WJ |", " WI |", " WL |", 
+                            " WC |", " WS |", " WG |", " WH |", " WA |", " WF |", " WE |", " WH |", " WM |", 
+                            " WS |", " WE |", " WW |", " WO |", " WG |", " WV |", " WS |", " WE |", " WA |", " WK |"};
+  static const char *bp[] = {"    |", " bp |", " BN |", " BB |", " BR |", " BA |", " BC |", " BM |", " BQ |", 
+                            " BE |", " BB |", " BQ |", " BW |", " BH |", " BN |", " BJ |", " BI |", " BL |", 
+                            " BC |", " BS |", " BG |", " BH |", " BA |", " BF |", " BE |", " BH |", " BM |", 
+                            " BS |", " BE |", " BW |", " BO |", " BG |", " BV |", " BS |", " BE |", " BA |", " BK |"};
+  static char *wsqr = "";\r
+  static char *bsqr = "";\r
+  static char *top = "\t-----------------------------------------\n";\r
+  static char *mid = "\t-----------------------------------------\n";\r
+  static char *start = "|";\r
+  static char *end = "";\r
+  static char *label = "\t  A    B    C    D    E    F    G    H    I    J    K    L\n";\r
+  static char *blabel = "\t  L    K    J    I    H    G    F    E    D    C    B    A\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+\r
+/* Miniature board */\r
+static int style7(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  static const char *wp[] = {"  ", " P", " N", " B", " R", " A", " C", " M", " Q", " E", " B", " Q", " W", " H", " N", " J", " I", " L", 
+                            " C", " S", " G", " H", " A", " F", " E", " H", " M", " S", " E", " W", " O", " G", " V", " S", " E", " A", " K"};
+  static const char *bp[] = {" -", " p", " n", " b", " r", " a", " c", " m", " q", " e", " b", " q", " w", " h", " n", " j", " i", " l", 
+                            " c", " s", " g", " h", " a", " f", " e", " h", " m", " s", " e", " w", " o", " g", " v", " s", " e", " a", " k"};
+  static char *wsqr = "";\r
+  static char *bsqr = "";\r
+  static char *top = "\t:::::::::::::::::::::\n";\r
+  static char *mid = "";\r
+  static char *start = "..";\r
+  static char *end = " ..";\r
+  static char *label = "\t   a b c d e f g h i j k l\n";\r
+  static char *blabel = "\t   l k j i h g f e d c b a\n";\r
+\r
+  return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);\r
+}\r
+
+/* ICS interface maker board-- raw data dump */\r
+static int style8(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  char tmp[160];\r
+  int f, r;\r
+  int ws, bs;\r
+\r
+  board_calc_strength(b, &ws, &bs);\r
+  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,\r
+         game_globals.garray[b->gameNum].white_name,\r
+         (orient == WHITE) ? "*" : ":",\r
+         game_globals.garray[b->gameNum].black_name,\r
+         (orient == WHITE) ? ":" : "*");\r
+  strcat(bstring, tmp);\r
+  for (r = 0; r < b->ranks; r++) {\r
+    for (f = 0; f < b->files; f++) {\r
+      if (b->board[f][r] == NOPIECE) {\r
+       strcat(bstring, " ");\r
+      } else {\r
+       if (colorval(b->board[f][r]) == WHITE)\r
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
+       else\r
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
+      }\r
+    }\r
+  }\r
+  sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",\r
+         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
+         (b->onMove == WHITE) ? "W" : "B",\r
+         ws,\r
+         bs,\r
+         (wTime + 5) / 10,\r
+         (bTime + 5) / 10,\r
+         game_globals.garray[b->gameNum].numHalfMoves ?\r
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :\r
+         "none",\r
+         game_globals.garray[b->gameNum].numHalfMoves ?\r
+         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
+         "0:00");\r
+  strcat(bstring, tmp);\r
+  return 0;\r
+}\r
+\r
+/* last 2 moves only (previous non-verbose mode) */\r
+static int style9(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  int i, count;\r
+  char tmp[160];\r
+  int startmove;\r
+\r
+  sprintf(tmp, "\nMove     %-23s%s\n",\r
+         game_globals.garray[b->gameNum].white_name,\r
+         game_globals.garray[b->gameNum].black_name);\r
+  strcat(bstring, tmp);\r
+  sprintf(tmp, "----     --------------         --------------\n");\r
+  strcat(bstring, tmp);\r
+  startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;\r
+  if (startmove < 0)\r
+    startmove = 0;\r
+  for (i = startmove, count = 0;\r
+       i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;\r
+       i++, count++) {\r
+    if (!(i & 0x01)) {\r
+      sprintf(tmp, "  %2d     ", i / 2 + 1);\r
+      strcat(bstring, tmp);\r
+    }\r
+    sprintf(tmp, "%-23s", move_and_time(&ml[i]));\r
+    strcat(bstring, tmp);\r
+    if (i & 0x01)\r
+      strcat(bstring, "\n");\r
+  }\r
+  if (i & 0x01)\r
+    strcat(bstring, "\n");\r
+  return 0;\r
+}\r
+\r
+/* Sleator's 'new and improved' raw dump format... */\r
+static int style10(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  int f, r;\r
+  char tmp[160];\r
+  int ws, bs;\r
+\r
+  board_calc_strength(b, &ws, &bs);\r
+  sprintf(tmp, "<10>\n");\r
+  strcat(bstring, tmp);\r
+  for (r = b->ranks-1; r >= 0; r--) {\r
+    strcat(bstring, "|");\r
+    for (f = 0; f < b->files; f++) {\r
+      if (b->board[f][r] == NOPIECE) {\r
+       strcat(bstring, " ");\r
+      } else {\r
+       if (colorval(b->board[f][r]) == WHITE)\r
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
+       else\r
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
+      }\r
+    }\r
+    strcat(bstring, "|\n");\r
+  }\r
+  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");\r
+  if (game_globals.garray[b->gameNum].numHalfMoves) {\r
+    sprintf(tmp, "%d ",\r
+           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);\r
+  } else {\r
+    sprintf(tmp, "-1 ");\r
+  }\r
+  strcat(bstring, tmp);\r
+  sprintf(tmp, "%d %d %d %d %d\n",\r
+         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights\r
+         (b->wkmoved >= 0 && b->wqrmoved >= 0),\r
+         (b->bkmoved >= 0 && b->bkrmoved >= 0),\r
+         (b->bkmoved >= 0 && b->bqrmoved >= 0),\r
+       (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :\r
+                                          b->lastIrreversable)));\r
+  strcat(bstring, tmp);\r
+  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",\r
+         b->gameNum,\r
+         game_globals.garray[b->gameNum].white_name,\r
+         game_globals.garray[b->gameNum].black_name,\r
+         myTurn,\r
+         game_globals.garray[b->gameNum].wInitTime / 600,\r
+         game_globals.garray[b->gameNum].wIncrement / 10,\r
+         ws,\r
+         bs,\r
+         (wTime + 5) / 10,\r
+         (bTime + 5) / 10,\r
+         game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
+         game_globals.garray[b->gameNum].numHalfMoves ?\r
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :\r
+         "none",\r
+         game_globals.garray[b->gameNum].numHalfMoves ?\r
+         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
+         "0:00",\r
+         game_globals.garray[b->gameNum].numHalfMoves ?\r
+         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :\r
+         "none",\r
+         (orient == WHITE) ? 0 : 1);\r
+  strcat(bstring, tmp);\r
+  sprintf(tmp, ">10<\n");\r
+  strcat(bstring, tmp);\r
+  return 0;\r
+}\r
+\r
+/* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */\r
+static int style11(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  char tmp[160];\r
+  int f, r;\r
+  int ws, bs;\r
+\r
+  board_calc_strength(b, &ws, &bs);\r
+  sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,\r
+         game_globals.garray[b->gameNum].white_name,\r
+         (orient == WHITE) ? "*" : ":",\r
+         game_globals.garray[b->gameNum].black_name,\r
+         (orient == WHITE) ? ":" : "*");\r
+  strcat(bstring, tmp);\r
+  for (r = 0; r < b->ranks; r++) {\r
+    for (f = 0; f < b->files; f++) {\r
+      if (b->board[f][r] == NOPIECE) {\r
+       strcat(bstring, " ");\r
+      } else {\r
+       if (colorval(b->board[f][r]) == WHITE)\r
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
+       else\r
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
+      }\r
+    }\r
+  }\r
+    sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",\r
+           game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,\r
+           (b->onMove == WHITE) ? "W" : "B",\r
+           ws,\r
+           bs,\r
+           (wTime + 5) / 10,\r
+           (bTime + 5) / 10,\r
+           game_globals.garray[b->gameNum].numHalfMoves ?\r
+           ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :\r
+           "none",\r
+           game_globals.garray[b->gameNum].numHalfMoves ?\r
+           tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :\r
+           "0:00");\r
+  strcat(bstring, tmp);\r
+  return 0;\r
+}\r
+
+
+int kludgeFlag = 0; \r
+/* Similar to style 10.  See the "style12" help file for information */\r
+static int style12(struct game_state_t *b, struct move_t *ml)\r
+{\r
+  int f, r;\r
+  char tmp[160]; // [HGM] 80 caused problems with long login names\r
+  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.\r
+\r
+  board_calc_strength(b, &ws, &bs);\r
+\r
+  sprintf(bstring, "<12> ");\r
+  for (r = b->ranks-1; r >= 0; r--) {\r
+    for (f = 0; f < b->files; f++) {
+      if (b->board[f][r] == NOPIECE) {\r
+       strcat(bstring, "-");\r
+      } else {\r
+       if (colorval(b->board[f][r]) == WHITE)\r
+         strcat(bstring, wpstring[piecetype(b->board[f][r])]);\r
+       else\r
+         strcat(bstring, bpstring[piecetype(b->board[f][r])]);\r
+      }\r
+    }\r
+    strcat(bstring, " ");\r
   }
+\r
+  strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");\r
+  if (nhm) {\r
+    sprintf(tmp, "%d ",\r
+           ml[nhm - 1].doublePawn);\r
+  } else {\r
+    sprintf(tmp, "-1 ");\r
+  }\r
+  strcat(bstring, tmp);\r
+  sprintf(tmp, "%d %d %d %d %d ",\r
+         (b->wkmoved >= 0 && b->wkrmoved >= 0), // [HGM] castle: inverted the logic, both must have rights\r
+         (b->wkmoved >= 0 && b->wqrmoved >= 0),\r
+         (b->bkmoved >= 0 && b->bkrmoved >= 0),\r
+         (b->bkmoved >= 0 && b->bqrmoved >= 0),\r
+         (nhm - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));\r
   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)));
-  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,
-         game_globals.garray[b->gameNum].white_name,
-         game_globals.garray[b->gameNum].black_name,
-         myTurn,
-         game_globals.garray[b->gameNum].wInitTime / 600,
-         game_globals.garray[b->gameNum].wIncrement / 10,
-         ws,
-         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 :
-         "none",
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
-         "0:00",
-         game_globals.garray[b->gameNum].numHalfMoves ?
-         ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
-         "none", (orient == WHITE) ? 0 : 1,
-         b->moveNum > 1 ? 1 : 0); /* ticking */
-
-  strcat(bstring, tmp);
-  return 0;
-}
+  sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n",\r
+         b->gameNum + 1,\r
+         game_globals.garray[b->gameNum].white_name,\r
+         game_globals.garray[b->gameNum].black_name,\r
+         myTurn,\r
+         game_globals.garray[b->gameNum].wInitTime / 600,\r
+         game_globals.garray[b->gameNum].wIncrement / 10,\r
+         ws,\r
+         bs,\r
+         (wTime / 10),\r
+         (bTime / 10),\r
+         nhm / 2 + 1,\r
+         nhm ?\r
+         ml[nhm - 1].moveString :\r
+         "none",\r
+         nhm ?\r
+         tenth_str(ml[nhm - 1].tookTime, 0) :\r
+         "0:00",\r
+         nhm ?\r
+         ml[nhm - 1].algString :\r
+         "none", (orient == WHITE) ? 0 : 1,\r
+         b->moveNum > 1 ? 1 : 0); /* ticking */\r
+
+  strcat(bstring, tmp);\r
+  return 0;\r
+}\r
 
 static int board_read_file(char *category, char *gname, struct game_state_t *gs)
 {
@@ -802,6 +995,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 +1007,58 @@ 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 '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 '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,36 +1083,128 @@ static int board_read_file(char *category, char *gname, struct game_state_t *gs)
       case 'B':
        onPiece = BISHOP;
        break;
+      case 'A':\r
+       onPiece = CARDINAL;\r
+       break;\r
+      case 'C':\r
+       onPiece = MARSHALL;\r
+       break;\r
+      case 'M':\r
+       onPiece = MAN;\r
+       break;\r
       case 'Q':
        onPiece = QUEEN;
        break;
-      case 'K':
-       onPiece = KING;
+      case 'T':
+       onPiece = ELEPHANT;
        break;
-      case 'a':
-      case 'b':
-      case 'c':
-      case 'd':
-      case 'e':
-      case 'f':
-      case 'g':
-      case 'h':
-       onFile = c - 'a';
-       onRank = -1;
+      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 '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-       onRank = c - '1';
-       if (onFile >= 0 && onColor >= 0 && onPiece >= 0)
-         gs->board[onFile][onRank] = onPiece | onColor;
+      case 'I':
+       onPiece = DRAGONHORSE;
        break;
-      case '#':
+      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 'a':\r
+      case 'b':\r
+      case 'c':\r
+      case 'd':\r
+      case 'e':\r
+      case 'f':\r
+      case 'g':\r
+      case 'h':\r
+      case 'i':\r
+      case 'j':\r
+      case 'k':\r
+      case 'l':\r
+       onFile = c - 'a';\r
+        if(onFile >= gs->files) { onFile = -1; break; }\r
+       onRank = -1;\r
+       break;\r
+      case '@':
+       if (onColor >= 0 && onPiece >= 0) // allow placement in holdings\r
+         gs->holding[onColor == BLACK][onPiece-1]++;
+       break;\r
+      case '1':\r
+      case '2':\r
+      case '3':\r
+      case '4':\r
+      case '5':\r
+      case '6':\r
+      case '7':\r
+      case '8':\r
+      case '9':\r
+      case '0':\r
+       onRank = c - '1' + (gs->ranks > 9);\r
+        if(onRank < 0 || onRank >= gs->ranks) { onRank = -1; break; }\r
+       if (onFile >= 0 && onColor >= 0 && onPiece >= 0)\r
+         gs->board[onFile][onRank] = onPiece | onColor;\r
+       break;\r      case '#':
        while (!feof(fp) && c != '\n')
          c = fgetc(fp);        /* Comment line */
       case '\n':
@@ -890,8 +1228,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 +1240,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 +1253,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 +1284,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 +1309,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 +1322,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 +1334,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 +1417,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);
 }