Beispiel #1
0
// Returns the short algebraic chess notation and the new board of a castling
// type move. Assume that the castling move is legal. Equivalent of
// Game#apply_move but for a castling move.
char*
castling (Board *board, int castling_type, Board *new_board)
{
  char *move;
  switch (castling_type)
    {
    case WHITE_SHORT_CASTLING:
      memcpy (new_board, board, sizeof (Board));
      new_board->king[WHITE] ^= 0x50;
      new_board->rooks[WHITE] ^= 0xa0;
      new_board->placement[E1] = '\0';
      new_board->placement[F1] = 'R';
      new_board->placement[G1] = 'K';
      new_board->placement[H1] = '\0';
      new_board->castling ^= new_board->castling & 0x1100;
      move = (char *) malloc (5);
      strcpy (move, "O-O");
      break;
    case WHITE_LONG_CASTLING:
      memcpy (new_board, board, sizeof (Board));
      new_board->king[WHITE] ^= 0x14;
      new_board->rooks[WHITE] ^= 0x09;
      new_board->placement[E1] = '\0';
      new_board->placement[D1] = 'R';
      new_board->placement[C1] = 'K';
      new_board->placement[A1] = '\0';
      new_board->castling ^= new_board->castling & 0x1100;
      move = (char *) malloc (7);
      strcpy (move, "O-O-O");
      break;
    case BLACK_SHORT_CASTLING:
      memcpy (new_board, board, sizeof (Board));
      new_board->king[BLACK] ^= 0x5000000000000000;
      new_board->rooks[BLACK] ^= 0xa000000000000000;
      new_board->placement[E8] = '\0';
      new_board->placement[F8] = 'r';
      new_board->placement[G8] = 'k';
      new_board->placement[H8] = '\0';
      new_board->castling ^= new_board->castling & 0x0011;
      move = (char *) malloc (5);
      strcpy (move, "O-O");
      break;
    case BLACK_LONG_CASTLING:
      memcpy (new_board, board, sizeof (Board));
      new_board->king[BLACK] ^= 0x1400000000000000;
      new_board->rooks[BLACK] ^= 0x0900000000000000;
      new_board->placement[E8] = '\0';
      new_board->placement[D8] = 'r';
      new_board->placement[C8] = 'k';
      new_board->placement[A8] = '\0';
      new_board->castling ^= new_board->castling & 0x0011;
      move = (char *) malloc (7);
      strcpy (move, "O-O-O");
      break;
    default:
      return NULL;
    }
  set_occupied (new_board);
  return move;
}
Beispiel #2
0
/*
 A FEN string is composed of 6 parts separated by " " (space).
 1. Piece placement (from white's perspective).
 2. Active color. "w" means white moves next, "b" means black.
 3. Castling availability. If neither side can castle, this is "-".
 4. En passant target square in algebraic notation. If there's no en passant target square, this is "-".
 5. Halfmove clock: this is the number of halfmoves since the last pawn advance or capture.
 6. Fullmove number: the number of the full move. It starts at 1, and is incremented after black's move.
*/
void
set_fen (Game *g, const char *fen)
{
  Board *board = NEW_BOARD;
  int i = 0, j, k, square;
  char *pch;
  char *s = (char *) malloc (sizeof (char) * (strlen (fen) + 1));
  strcpy (s, fen);
  // Init board
  memset (board->placement, '\0', 64);
  board->pawns[WHITE]   = 0x0;
  board->pawns[BLACK]   = 0x0;
  board->rooks[WHITE]   = 0x0;
  board->rooks[BLACK]   = 0x0;
  board->knights[WHITE] = 0x0;
  board->knights[BLACK] = 0x0;
  board->bishops[WHITE] = 0x0;
  board->bishops[BLACK] = 0x0;
  board->queens[WHITE]  = 0x0;
  board->queens[BLACK]  = 0x0;
  board->king[WHITE]    = 0x0;
  board->king[BLACK]    = 0x0;
  pch = strtok (s, " /");
  while (pch != NULL)
    {
      if (i < 8)
        {
          for (j = 0, k = 0; j < (int) strlen (pch); j++)
            {
              if (pch[j] - 48 > 8)
                {
                  square = (abs (i - 7) * 8) + k;
                  switch (pch[j])
                    {
                      case 'P':
                      board->placement[square] = pch[j];
                      board->pawns[WHITE] ^= 1ULL << square;
                      break;
                      case 'p':
                      board->placement[square] = pch[j];
                      board->pawns[BLACK] ^= 1ULL << square;
                      break;
                      case 'R':
                      board->placement[square] = pch[j];
                      board->rooks[WHITE] ^= 1ULL << square;
                      break;
                      case 'r':
                      board->placement[square] = pch[j];
                      board->rooks[BLACK] ^= 1ULL << square;
                      break;
                      case 'N':
                      board->placement[square] = pch[j];
                      board->knights[WHITE] ^= 1ULL << square;
                      break;
                      case 'n':
                      board->placement[square] = pch[j];
                      board->knights[BLACK] ^= 1ULL << square;
                      break;
                      case 'B':
                      board->placement[square] = pch[j];
                      board->bishops[WHITE] ^= 1ULL << square;
                      break;
                      case 'b':
                      board->placement[square] = pch[j];
                      board->bishops[BLACK] ^= 1ULL << square;
                      break;
                      case 'Q':
                      board->placement[square] = pch[j];
                      board->queens[WHITE] ^= 1ULL << square;
                      break;
                      case 'q':
                      board->placement[square] = pch[j];
                      board->queens[BLACK] ^= 1ULL << square;
                      break;
                      case 'K':
                      board->placement[square] = pch[j];
                      board->king[WHITE] ^= 1ULL << square;
                      break;
                      case 'k':
                      board->placement[square] = pch[j];
                      board->king[BLACK] ^= 1ULL << square;
                      break;
                    }
                  k++;
                }
              else
                k += pch[j] - 48;
            }
        }
      else if (i == 8)
        {
          board->active_color = pch[0] == 'b';
        }
      else if (i == 9)
        {
          board->castling = 0x0000;
          for (j = 0; j < (int) strlen (pch); j++)
            {
              switch (pch[j])
                {
                  case 'K':
                  board->castling |= 0x1000;
                  break;
                  case 'Q':
                  board->castling |= 0x0100;
                  break;
                  case 'k':
                  board->castling |= 0x0010;
                  break;
                  case 'q':
                  board->castling |= 0x0001;
                  break;
                }
            }
        }
      else if (i == 10)
        {
          board->en_passant = coord_to_square (pch);
        }
      else if (i == 11)
        {
          board->halfmove_clock = atoi (pch);
        }
      else if (i == 12)
        {
          board->fullmove_number = atoi (pch);
        }
      i++;
      pch = strtok (NULL, " /");
    }
  set_occupied (board);
  g->boards[g->current] = board;
  g->moves[g->current] = (char *) malloc (11);
  g->coord_moves[g->current] = (char *) malloc (11);
  strcpy (g->moves[g->current], "SET BY FEN");
  strcpy (g->coord_moves[g->current], "SET BY FEN");
  g->current++;

  // check result
  if (king_in_checkmate (board, board->active_color))
    g->result = !board->active_color;
  else
    if (stalemate (board, board->active_color) || insufficient_material (board))
      g->result = DRAW;

  free (s);
}