Exemplo n.º 1
0
// check whether all moves end up in wins for the opponent
// if we are here, all captures are losing
static int check_loss(int *pcs, long64 idx0, ubyte *table, bitboard occ, int *p)
{
  int sq;
  long64 idx, idx2;
  bitboard bb;
  int best = LOSS_IN_ONE;

  int k = *pcs++;
  if (k == 0) { // white king
    bb = WhiteKingMoves;
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove0(idx0, sq);
      int v = win_loss[table[idx2]];
      if (!v) return 0;
      if (v < best) best = v;
      ClearFirst(bb);
    }
  } else { // otherwise k == 1, i.e. black king
    bb = BlackKingMoves;
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove1(idx0, sq);
      int v = win_loss[table[idx2]];
      if (!v) return 0;
      if (v < best) best = v;
      ClearFirst(bb);
    }
  }
  while ((k = *pcs++) >= 0) {
    bb = PieceMoves(p[k], pt[k], occ);
    idx = idx0 & ~mask[k];
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove2(idx, k, sq);
      int v = win_loss[table[idx2]];
      if (!v) return 0;
      if (v < best) best = v;
      ClearFirst(bb);
    }
  }

  return best;
}
Exemplo n.º 2
0
static int check_mate(int *pcs, long64 idx0, ubyte *table, bitboard occ, int *p)
{
  int sq;
  long64 idx, idx2;
  bitboard bb;

  int k = *pcs++;
  if (k == 0) { // white king
    bb = WhiteKingMoves;
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove0(idx0, sq);
      if (table[idx2] != ILLEGAL) return 0;
      ClearFirst(bb);
    }
  } else { // otherwise k == 1, i.e. black king
    bb = BlackKingMoves;
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove1(idx0, sq);
      if (table[idx2] != ILLEGAL) return 0;
      ClearFirst(bb);
    }
  }
  while ((k = *pcs++) >= 0) {
    bb = PieceMoves(p[k], pt[k], occ);
    idx = idx0 & ~mask[k];
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove2(idx, k, sq);
      if (table[idx2] != ILLEGAL) return 0;
      ClearFirst(bb);
    }
  }

  return 1;
}
Exemplo n.º 3
0
// captures should be taken care of already
int check_mate_pieces(int *pcs, long64 idx0, ubyte *table, bitboard occ, int *p)
{
  int sq;
  long64 idx, idx2;
  bitboard bb;

  do {
    int k = *pcs;
    bb = PieceMoves(p[k], pt[k], occ);
    idx = idx0 & ~mask[k];
    while (bb) {
      sq = FirstOne(bb);
      idx2 = MakeMove(idx, k, sq);
      if (table[idx2] < WDL_ILLEGAL) return 0;
      ClearFirst(bb);
    }
  } while (*(++pcs) >= 0);

  return 1;
}
Exemplo n.º 4
0
Arquivo: sprobe.c Projeto: syzygy1/tb
static int probe_tb_capts(struct Player *player, struct Player *opp, bitboard player_occ, bitboard opp_occ, int alpha, int beta, int *capts)
{
  int i, j;

  *capts = 0;

  if (opp->num > 1) {
    for (i = 0; i < player->num; i++) {
      int from = player->pos[i];
      bitboard bb = PieceRange(from, player->type[i], player_occ | opp_occ) & opp_occ;
      if (bb) {
	*capts = 1;
	opp->num--;
	bitboard occ2 = player_occ ^ bit[from];
	do {
	  int to = FirstOne(bb);
	  player->pos[i] = to;
	  for (j = 0; opp->pos[j] != to; j++);
	  int tmp_type = opp->type[j];
	  opp->type[j] = opp->type[opp->num];
	  opp->pos[j] = opp->pos[opp->num];
#ifdef HAS_PAWNS
	  // FIXME: optimise
	  if ((player->type[i] & 0x07) == PAWN && ((to + 0x08) & 0x30) == 0) {
	    int t = player->type[i];
	    int m;
	    for (m = KING - PAWN; m >= KNIGHT - PAWN; m--) {
	      player->type[i] = t + m;
	      int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha);
	      if (v > alpha) {
		alpha = v;
		if (alpha >= beta) break;
	      }
	    }
	    player->type[i] = t;
	  } else {
#endif
	    int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha);
	    if (v > alpha)
	      alpha = v;
#ifdef HAS_PAWNS
	  }
#endif
	  opp->type[j] = tmp_type;
	  opp->pos[j] = to;
	  if (alpha >= beta) {
	    player->pos[i] = from;
	    opp->num++;
	    return alpha;
	  }
	  ClearFirst(bb);
	} while (bb);
	player->pos[i] = from;
	opp->num++;
      }
    }
  } else {
    for (i = 0; i < player->num; i++) {
      bitboard bb = PieceRange(player->pos[i], player->type[i], player_occ) & opp_occ;
      if (bb) {
	*capts = 1;
	return -2;
      }
    }
  }

  return alpha;
}
Exemplo n.º 5
0
Arquivo: sprobe.c Projeto: syzygy1/tb
static int probe_tb2(struct Player *player, struct Player *opp, bitboard player_occ, bitboard opp_occ, int alpha, int beta)
{
  int i, j;
  bitboard player_att[5];
  bitboard opp_att[5];

  // first try captures
  if (opp->num > 1) {
    int capts = 0;
    for (i = 0; i < player->num; i++) {
      int from = player->pos[i];
      bitboard bb = PieceRange(from, player->type[i], player_occ | opp_occ);
      player_att[i] = bb;
      bb &= opp_occ;
      if (bb) {
	capts = 1;
	opp->num--;
	bitboard occ2 = player_occ ^ bit[from];
	do {
	  int to = FirstOne(bb);
	  player->pos[i] = to;
	  for (j = 0; opp->pos[j] != to; j++);
	  int tmp_type = opp->type[j];
	  opp->type[j] = opp->type[opp->num];
	  opp->pos[j] = opp->pos[opp->num];
#ifdef HAS_PAWNS
	  if ((player->type[i] & 0x07) == PAWN && ((to + 0x08) & 0x30) == 0) {
	    int t = player->type[i];
	    int m;
	    for (m = KING - PAWN; m >= KNIGHT - PAWN; m--) {
	      player->type[i] = t + m;
	      int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha);
	      if (v > alpha) {
		alpha = v;
		if (alpha >= beta) break;
	      }
	    }
	    player->type[i] = t;
	  } else {
#endif
	    int v = -probe_tb2(opp, player, opp_occ ^ bit[to], occ2 ^ bit[to], -beta, -alpha);
	    if (v > alpha)
	      alpha = v;
#ifdef HAS_PAWNS
	  }
#endif
	  opp->type[j] = tmp_type;
	  opp->pos[j] = to;
	  if (alpha >= beta) {
	    player->pos[i] = from;
	    opp->num++;
	    return alpha;
	  }
	  ClearFirst(bb);
	} while (bb);
	player->pos[i] = from;
	opp->num++;
      }
    }
    if (capts) return alpha;
  } else {
    for (i = 0; i < player->num; i++) {
      bitboard bb = PieceRange(player->pos[i], player->type[i], player_occ);
      player_att[i] = bb;
      if (bb & opp_occ)
	return -2;
    }
  }

#if 1
  if (player->num + opp->num < 6)
    goto skip_threats;
#endif

  // now try threats. there are two cases
  bitboard atts = 0ULL;
  for (i = 0; i < opp->num; i++) {
    opp_att[i] = PieceRange(opp->pos[i], opp->type[i], player_occ | opp_occ);
    atts |= opp_att[i];
  }
  // first case: opponent currently is not attacking any pieces
  // we only need to consider moves moving into opponent attacks
  if (!(atts & player_occ)) {
    if (player->num > 1) {
      player->num--;
      for (i = 0; i <= player->num; i++) {
#ifdef HAS_PAWNS
	if ((player->type[i] & 0x07) == 1) continue;
#endif
	bitboard bb = player_att[i] & atts;
	if (!bb) continue;
	int pos = player->pos[i];
	int type = player->type[i];
	player->pos[i] = player->pos[player->num];
	player->type[i] = player->type[player->num];
	do {
	  int sq = FirstOne(bb);
	  int beta2 = beta;
	  for (j = 0; j < opp->num; j++) {
	    if (!(bit[sq] & opp_att[j])) continue;
	    int tmp_pos = opp->pos[j];
	    opp->pos[j] = sq;
#ifdef HAS_PAWNS
	    if ((opp->type[j] & 0x07) == PAWN && ((sq + 0x08) & 0x30) == 0) {
	      int t = opp->type[j];
	      int m;
	      for (m = KING - PAWN; m >= KNIGHT - PAWN; m--) {
		opp->type[j] = t + m;
		int v = probe_tb2(player, opp, player_occ ^ bit[pos], opp_occ ^ bit[sq] ^ bit[tmp_pos], alpha, beta2);
		if (v < beta2) {
		  beta2 = v;
		  if (beta2 <= alpha)
		    break;
		}
	      }
	      opp->type[j] = t;
	    } else {
#endif
	      int v = probe_tb2(player, opp, player_occ ^ bit[pos], opp_occ ^ bit[sq] ^ bit[tmp_pos], alpha, beta2);
	      if (v < beta2)
		beta2 = v;
#ifdef HAS_PAWNS
	    }
#endif
	    opp->pos[j] = tmp_pos;
	    if (beta2 <= alpha) break;
	  }
	  if (beta2 > alpha) {
	    if (beta2 >= beta) {
	      player->pos[i] = pos;
	      player->type[i] = type;
	      player->num++;
	      return beta2;
	    }
	    alpha = beta2;
	  }
	  ClearFirst(bb);
	} while (bb);
	player->pos[i] = pos;
	player->type[i] = type;
      }
      player->num++;
    } else {
      for (i = 0; i < player->num; i++) {
#ifdef HAS_PAWNS
	if ((player->type[i] & 0x07) == 1) continue;
#endif
	if (player_att[i] & atts) return 2;
      }
    }
  } else { // second case: just try all moves
    for (i = 0; i < player->num; i++) {
#ifdef HAS_PAWNS
      if ((player->type[i] & 0x07) == 1) continue;
#endif
      bitboard bb = player_att[i] & ~player_occ;
      if (bb) {
	int from = player->pos[i];
	do {
	  int capts;
	  int to = FirstOne(bb);
	  player->pos[i] = to;
	  int v = -probe_tb_capts(opp, player, opp_occ, player_occ ^ bit[from] ^ bit[to], -beta, -alpha, &capts);
	  if (capts && v > alpha) {
	    if (v >= beta) {
	      player->pos[i] = from;
	      return v;
	    }
	    alpha = v;
	  }
	  ClearFirst(bb);
	} while (bb);
	player->pos[i] = from;
      }
    }
  }

  int pieces[6];
  int pos[6];
skip_threats:
  for (i = 0; i < player->num; i++) {
    pieces[i] = player->type[i];
    pos[i] = player->pos[i];
  }
  for (j = 0; j < opp->num; j++, i++) {
    pieces[i] = opp->type[j];
    pos[i] = opp->pos[j];
  }
  for (; i < numpcs; i++)
    pieces[i] = 0;
  int v = probe_table(pieces, pos, pieces[0] < 8);
  return alpha > v ? alpha : v;
}