Beispiel #1
0
// returns 0 on illegal move
static Move parse_move(Bitboard *board, char* possible_move)
{
	Movelist moves;
	move_generate_movelist(board, &moves);
	char test[6];

	Moveiter it;
	moveiter_init(&it, &moves, MOVEITER_SORT_NONE, MOVE_NULL);
	while (moveiter_has_next(&it))
	{
		Move m = moveiter_next(&it);
		move_srcdest_form(m, test);
		if (!move_is_promotion(m) && !strncmp(test, possible_move, 4))
			return m;
		else if (!strncmp(test, possible_move, 5))
			return m;
	}

	return 0;
}
bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) {

  assert(pos.is_ok());
  assert(move_is_ok(m));
  assert(pinned == pos.pinned_pieces(pos.side_to_move()));

  Color us = pos.side_to_move();
  Color them = opposite_color(us);
  Square from = move_from(m);
  Square to = move_to(m);
  Piece pc = pos.piece_on(from);

  // Use a slower but simpler function for uncommon cases
  if (move_is_ep(m) || move_is_castle(m))
      return move_is_legal(pos, m);

  // If the from square is not occupied by a piece belonging to the side to
  // move, the move is obviously not legal.
  if (color_of_piece(pc) != us)
      return false;

  // The destination square cannot be occupied by a friendly piece
  if (pos.color_of_piece_on(to) == us)
      return false;

  // Handle the special case of a pawn move
  if (type_of_piece(pc) == PAWN)
  {
      // Move direction must be compatible with pawn color
      int direction = to - from;
      if ((us == WHITE) != (direction > 0))
          return false;

      // A pawn move is a promotion iff the destination square is
      // on the 8/1th rank.
      if ((  (square_rank(to) == RANK_8 && us == WHITE)
           ||(square_rank(to) == RANK_1 && us != WHITE)) != bool(move_is_promotion(m)))
          return false;

      // Proceed according to the square delta between the origin and
      // destination squares.
      switch (direction)
      {
      case DELTA_NW:
      case DELTA_NE:
      case DELTA_SW:
      case DELTA_SE:
      // Capture. The destination square must be occupied by an enemy
      // piece (en passant captures was handled earlier).
          if (pos.color_of_piece_on(to) != them)
              return false;
          break;

      case DELTA_N:
      case DELTA_S:
      // Pawn push. The destination square must be empty.
          if (!pos.square_is_empty(to))
              return false;
          break;

      case DELTA_NN:
      // Double white pawn push. The destination square must be on the fourth
      // rank, and both the destination square and the square between the
      // source and destination squares must be empty.
      if (   square_rank(to) != RANK_4
          || !pos.square_is_empty(to)
          || !pos.square_is_empty(from + DELTA_N))
          return false;
          break;

      case DELTA_SS:
      // Double black pawn push. The destination square must be on the fifth
      // rank, and both the destination square and the square between the
      // source and destination squares must be empty.
          if (   square_rank(to) != RANK_5
              || !pos.square_is_empty(to)
              || !pos.square_is_empty(from + DELTA_S))
              return false;
          break;

      default:
          return false;
      }
      // The move is pseudo-legal, check if it is also legal
      return pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned);
  }

  // Luckly we can handle all the other pieces in one go
  return    bit_is_set(pos.attacks_from(pc, from), to)
        && (pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned))
        && !move_is_promotion(m);
}