Пример #1
0
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;
}
Пример #2
0
/*
 * Return the physical address of the requested table or zero if one
 * is not found.
 */
vm_paddr_t
acpi_find_table(const char *sig)
{
	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
	ACPI_TABLE_RSDP *rsdp;
	ACPI_TABLE_XSDT *xsdt;
	ACPI_TABLE_HEADER *table;
	vm_paddr_t addr;
	int i, count;

	if (resource_disabled("acpi", 0))
		return (0);

	/*
	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
	 * pmap_mapbios() to map the RSDP.
	 */
	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
		return (0);
	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
	if (rsdp == NULL) {
		if (bootverbose)
			printf("ACPI: Failed to map RSDP\n");
		return (0);
	}

	addr = 0;
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
		/*
		 * AcpiOsGetRootPointer only verifies the checksum for
		 * the version 1.0 portion of the RSDP.  Version 2.0 has
		 * an additional checksum that we verify first.
		 */
		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
			if (bootverbose)
				printf("ACPI: RSDP failed extended checksum\n");
			return (0);
		}
		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
		if (xsdt == NULL) {
			if (bootverbose)
				printf("ACPI: Failed to map XSDT\n");
			pmap_unmapbios((vm_offset_t)rsdp,
			    sizeof(ACPI_TABLE_RSDP));
			return (0);
		}
		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
		    sizeof(UINT64);
		for (i = 0; i < count; i++)
			if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
				addr = xsdt->TableOffsetEntry[i];
				break;
			}
		acpi_unmap_table(xsdt);
	}
	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));

	if (addr == 0) {
		if (bootverbose)
			printf("ACPI: No %s table found\n", sig);
		return (0);
	}
	if (bootverbose)
		printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);

	/*
	 * Verify that we can map the full table and that its checksum is
	 * correct, etc.
	 */
	table = map_table(addr, 0, sig);
	if (table == NULL)
		return (0);
	acpi_unmap_table(table);

	return (addr);
}