Fix force mode after setboard
[bonanza.git] / csa.c
diff --git a/csa.c b/csa.c
index e99f953..f1f0479 100644 (file)
--- a/csa.c
+++ b/csa.c
@@ -421,77 +421,6 @@ interpret_CSA_move( tree_t * restrict ptree, unsigned int *pmove,
 
 
 const char *
-str_CSA_move_plus( tree_t * restrict ptree, unsigned int move, int ply,
-                  int turn )
-{
-  static char str[ 13 ];
-  const unsigned int *pmove_last;
-  unsigned int amove[ MAX_LEGAL_EVASION ];
-  char *p;
-  int is_promo, ipiece_cap, ipiece_move, ifrom, ito, turn_next;
-
-  is_promo    = (int)I2IsPromote(move);
-  ipiece_move = (int)I2PieceMove(move);
-  ifrom       = (int)I2From(move);
-  ito         = (int)I2To(move);
-  ipiece_cap  = (int)UToCap(move);
-  turn_next   = Flip( turn );
-
-  if ( is_promo && ipiece_cap )
-    {
-      snprintf( str, 13, "%d%d%d%d%spx%s",
-              9-aifile[ifrom], airank[ifrom]+1,
-              9-aifile[ito],   airank[ito]  +1,
-              astr_table_piece[ ipiece_move + promote ],
-              astr_table_piece[ ipiece_cap ] );
-      p = str + 10;
-    }
-  else if ( ipiece_cap )
-    {
-      snprintf( str, 13, "%d%d%d%d%sx%s",
-              9-aifile[ifrom], airank[ifrom]+1,
-              9-aifile[ito],   airank[ito]  +1,
-              astr_table_piece[ ipiece_move ],
-              astr_table_piece[ ipiece_cap ] );
-      p = str + 9;
-    }
-  else if ( is_promo )
-    {
-      snprintf( str, 13, "%d%d%d%d%sp",
-              9-aifile[ifrom], airank[ifrom]+1,
-              9-aifile[ito],   airank[ito]  +1,
-              astr_table_piece[ ipiece_move + promote ] );
-      p = str + 7;
-    }
-  else if ( ifrom < nsquare )
-    {
-      snprintf( str, 13, "%d%d%d%d%s",
-              9-aifile[ifrom], airank[ifrom]+1,
-              9-aifile[ito],   airank[ito]  +1,
-              astr_table_piece[ ipiece_move ] );
-      p = str + 6;
-    }
-  else {
-    snprintf( str, 13, "00%d%d%s", 9-aifile[ito], airank[ito]+1,
-            astr_table_piece[ From2Drop(ifrom) ] );
-    p = str + 6;
-  }
-
-  MakeMove( turn, move, ply );
-  if ( InCheck( turn_next ) )
-    {
-      pmove_last = GenEvasion( turn_next, amove );
-      if ( pmove_last == amove ) { *p++ = '#'; }
-      else                       { *p++ = '!'; }
-      *p   = '\0';
-    }
-  UnMakeMove( turn, move, ply );
-
-  return str;
-}
-
-
-const char *
 str_CSA_move( unsigned int move )
 {
   static char str[7];
@@ -533,7 +462,13 @@ read_board_rep1( const char *str_line, min_posi_t *pmin_posi )
   char str_piece[3];
   int piece, ifile, irank, isquare;
   signed char board[nsquare];
+  int add = 0, color = -1;
 
+  if( *str_line == 'S' ) { // [HGM] setup: allow 'SU' representation that adds pieces in stead of removing them
+    add = 1;
+    for ( isquare = 0; isquare < nsquare; isquare++ ) board[isquare] = empty;
+    pmin_posi->hand_white = pmin_posi->hand_black = 0;
+  } else
   memcpy( board, &min_posi_no_handicap.asquare, nsquare );
 
   for ( p = str_line + 2; p[0] != '\0'; p += 4 )
@@ -543,6 +478,18 @@ read_board_rep1( const char *str_line, min_posi_t *pmin_posi )
          str_error = str_bad_board;
          return -2;
        }
+      if( add && p[0] == '+' ) // [HGM] setup: change color
+       {
+         color = 1;
+         p -= 3;
+         continue;
+       }
+      if( add && p[0] == '-' )
+       {
+         color = -1;
+         p -= 3;
+         continue;
+       }
       str_piece[0] = p[2];
       str_piece[1] = p[3];
       str_piece[2] = '\0';
@@ -552,12 +499,24 @@ read_board_rep1( const char *str_line, min_posi_t *pmin_posi )
       ifile        = 9 - ifile;
       irank        = irank - 1;
       isquare      = irank * nfile + ifile;
+      if ( add && piece != -2 && p[0] == '0' && p[1] == '0' )
+       { // [HGM] setup: holdings
+           static int unit[] = {0, 1, 1<<5, 1<<8, 1<<11, 1<<14, 1<<17, 1<<19};
+           if(piece < 1 || piece > 7) { // only unpromoted in hand!
+               str_error = str_bad_board;
+               return -2;
+           }
+           if(color > 0) pmin_posi->hand_black += unit[piece];
+           else          pmin_posi->hand_white += unit[piece];
+           continue;
+       }
       if ( piece == -2 || ifile < file1 || ifile > file9 || irank < rank1
-          || irank > rank9 || abs(board[isquare]) != piece )
+          || irank > rank9 || abs(board[isquare]) != (add ? empty : piece) )
        {
          str_error = str_bad_board;
          return -2;
        }
+      if( add ) board[isquare] = piece*color; else
       board[isquare] = empty;
     }
   
@@ -575,6 +534,144 @@ read_board_rep1( const char *str_line, min_posi_t *pmin_posi )
 }
 
 
+#if defined(USI)
+int CONV
+usi2csa( const tree_t * restrict ptree, const char *str_usi, char *str_csa )
+{
+  int sq_file, sq_rank, sq, pc;
+
+  if ( '1' <= str_usi[0] && str_usi[0] <= '9'
+       && 'a' <= str_usi[1] && str_usi[1] <= 'i'
+       && '1' <= str_usi[2] && str_usi[2] <= '9'
+       && 'a' <= str_usi[3] && str_usi[3] <= 'i' )
+    {
+      str_csa[0] = str_usi[0];
+      str_csa[1] = (char)( str_usi[1] + '1' - 'a' );
+      str_csa[2] = str_usi[2];
+      str_csa[3] = (char)( str_usi[3] + '1' - 'a' );
+
+      sq_file = str_csa[0]-'0';
+      sq_file = 9 - sq_file;
+      sq_rank = str_csa[1]-'0';
+      sq_rank = sq_rank - 1;
+      sq      = sq_rank * 9 + sq_file;
+      pc      = abs(BOARD[sq]);
+      if ( str_usi[4] == '+' ) { pc += promote; }
+
+      str_csa[4] = astr_table_piece[pc][0];
+      str_csa[5] = astr_table_piece[pc][1];
+      str_csa[6] = '\0';
+
+      return 1;
+    }
+
+  if ( isascii( (int)str_usi[0] )
+       && isalpha( (int)str_usi[0] )
+       && str_usi[1] == '*'
+       && '1' <= str_usi[2] && str_usi[2] <= '9'
+       && 'a' <= str_usi[3] && str_usi[3] <= 'i' )
+    {
+      str_csa[0] = '0';
+      str_csa[1] = '0';
+      str_csa[2] = str_usi[2];
+      str_csa[3] = (char)( str_usi[3] - 'a' + '1' );
+      
+      switch ( str_usi[0] )
+       {
+       case 'P':  pc = pawn;    break;
+       case 'L':  pc = lance;   break;
+       case 'N':  pc = knight;  break;
+       case 'S':  pc = silver;  break;
+       case 'G':  pc = gold;    break;
+       case 'B':  pc = bishop;  break;
+       case 'R':  pc = rook;    break;
+       default:   return -1;
+       }
+
+      str_csa[4] = astr_table_piece[pc][0];
+      str_csa[5] = astr_table_piece[pc][1];
+      str_csa[6] = '\0';
+
+      return 1;
+    }
+
+  snprintf( str_message, SIZE_MESSAGE, "%s: %s", str_illegal_move, str_usi );
+  str_error = str_message;
+  return -1;
+}
+
+
+int CONV
+csa2usi( const tree_t * restrict ptree, const char *str_csa, char *str_usi )
+{
+  if ( str_csa[0] == '0' && str_csa[1] == '0'
+       && '1' <= str_csa[2] && str_csa[2] <= '9'
+       && '1' <= str_csa[3] && str_csa[3] <= '9'
+       && 'A' <= str_csa[4] && str_csa[4] <= 'Z'
+       && 'A' <= str_csa[5] && str_csa[5] <= 'Z' )
+    {
+      switch ( str2piece( str_csa + 4 ) )
+       {
+       case pawn:    str_usi[0] = 'P';  break;
+       case lance:   str_usi[0] = 'L';  break;
+       case knight:  str_usi[0] = 'N';  break;
+       case silver:  str_usi[0] = 'S';  break;
+       case gold:    str_usi[0] = 'G';  break;
+       case bishop:  str_usi[0] = 'B';  break;
+       case rook:    str_usi[0] = 'R';  break;
+       default:  return -1;  break;
+       }
+
+      str_usi[1] = '*';
+      str_usi[2] = str_csa[2];
+      str_usi[3] = (char)( str_csa[3] + 'a' - '1' );
+      str_usi[4] = '\0';
+
+      return 1;
+    }
+
+
+  if ( '1' <= str_csa[0] && str_csa[0] <= '9'
+       && '1' <= str_csa[1] && str_csa[1] <= '9'
+       && '1' <= str_csa[2] && str_csa[2] <= '9'
+       && '1' <= str_csa[3] && str_csa[3] <= '9'
+       && 'A' <= str_csa[4] && str_csa[4] <= 'Z'
+       && 'A' <= str_csa[5] && str_csa[5] <= 'Z' )
+    {
+      int sq_file, sq_rank, sq, pc;
+
+
+      str_usi[0] = str_csa[0];
+      str_usi[1] = (char)( str_csa[1] + 'a' - '1' );
+      str_usi[2] = str_csa[2];
+      str_usi[3] = (char)( str_csa[3] + 'a' - '1' );
+
+      sq_file = str_csa[0]-'0';
+      sq_file = 9 - sq_file;
+
+      sq_rank = str_csa[1]-'0';
+      sq_rank = sq_rank - 1;
+      sq      = sq_rank * 9 + sq_file;
+      pc      = abs(BOARD[sq]);
+
+      if ( pc + promote == str2piece( str_csa + 4 ) )
+       {
+         str_usi[4] = '+';
+         str_usi[5] = '\0';
+       }
+      else { str_usi[4] = '\0'; }
+
+
+      return 1;
+    }
+
+  str_usi[0] = '*';
+  str_usi[1] = '\0';
+  return 1;
+}
+#endif
+
+
 static void
 out_CSA_header( const tree_t * restrict ptree, record_t *pr )
 {