int AIInterface::getPlayerToMove() { if (duel->isChoiceActive) return duel->choicePlayer; if (duel->attackphase == PHASE_BLOCK || duel->attackphase == PHASE_TRIGGER) return getOpponent(duel->turn); return duel->turn; }
bool Team::isSafeGoingThroughAllOpponents(const Ogre::Vector3& from, const Ogre::Vector3& target, float force) { std::vector<Player*>& opponents = getOpponent()->getPlayers(); //const std::vector<Ogre::Vector3>& points = mPitch->getPassSafePolygon(); //for (int i = 0; i < points.size(); ++i) //{ // mPassSafePolygon[i] = GetRotationThroughHeading(target - from) * points[i] + from; //} //int num_in_polygon = 0; //for (auto it = opponents.begin(); it != opponents.end(); ++it) //{ // // If Distance(opponent, from) > Distance(from, target), pass // if (from.distance((*it)->getPosition()) > from.distance(target)) // { // continue; // } // // if (GeometryHelper::get().isInPolygon((*it)->getPosition(), mPassSafePolygon)) // { // ++num_in_polygon; // } //} //// 有人在这个区域内 //if (num_in_polygon > 0) //{ // return false; //} for (auto it = opponents.begin(); it != opponents.end(); ++it) { if (!isSafeGoingThroughOpponent(from, target, force, *it)) { return false; } } return true; //return false; // Enforce to pass the ball }
void abstractGame(ChessMove (*whitePlayer)(ChessBoard &,int),ChessMove (*blackPlayer)(ChessBoard &,int)) { ChessBoard board; board.setup(); SearchTree ai; ChessMove selectedMove; unsigned int i; vector<ChessMove> moves; BoardIO boardWriter; vector<ChessBoard> boards; int color=WHITE; for (i=0;i<16;i++) { boards.push_back(board); if (color==WHITE) selectedMove=(*whitePlayer)(board,color); else selectedMove=(*blackPlayer)(board,color); board.getMoves(color,moves); board.applyMove(selectedMove); cout << moveString(selectedMove) << "\n"; color=getOpponent(color); } boardWriter.saveBoards(boards, "C:\\Users\\sam\\Documents\\cpp\\chess.html"); }
bool Team::canShoot(const Ogre::Vector3& from, Ogre::Vector3& proper_target, float shooting_force) { Goal* goal = getOpponent()->getGoal(); float dist_to_goal = Vector3To2(from).distance(goal->getCenter()); // If too far from goal, it may be not a good chance to shoot if (dist_to_goal > Prm.PlayerShootingRange) { return false; } // If shooting angle is too narrow, drop it float theta = fabs(from.x - goal->getCenter().x) / dist_to_goal; if (asin(theta) < PI / 6) { return false; } int tot = Prm.PlayerShootingTryNum; Ogre::Vector3 left_to_right = goal->getRightPost() - goal->getLeftPost(); while (tot--) { Ogre::Vector3 target = goal->getLeftPost() + left_to_right * dt::Random::get(0.f, 1.f); // If safe to shot // or with some possibility if (isSafeGoingThroughAllOpponents(mBall->getPosition(), target, shooting_force) || WithPossibility(0.05)) { proper_target = target; return true; } } return false; }
bool Team::isSafeGoingThroughAllOpponents(const Ogre::Vector3& from, const Ogre::Vector3& target, float force) { std::vector<Player*>& opponents = getOpponent()->getPlayers(); const std::vector<Ogre::Vector3>& points = mPitch->getPassSafePolygon(); for (int i = 0; i < points.size(); ++i) { mPassSafePolygon[i] = GetRotationThroughHeading(target - from) * points[i] + from; } int num_in_polygon = 0; for (auto it = opponents.begin(); it != opponents.end(); ++it) { // If Distance(opponent, from) > Distance(from, target), pass if (from.distance((*it)->getPosition()) > from.distance(target)) { continue; } if (GeometryHelper::get().isInPolygon((*it)->getPosition(), mPassSafePolygon)) { ++num_in_polygon; } } // No one in this region, pass is safe if (!num_in_polygon) { return true; } //return false; // Enforce to pass the ball return WithPossibility(0.01 / (num_in_polygon * num_in_polygon)); }
int Engine::StaticExchangeEvaluation(int to, int from, int movpiece, int capt) { capt = getSquare2Piece(capt); /*if (PieceMaterial[capt] >= PieceMaterial[movpiece]) { return PieceMaterial[capt] - PieceMaterial[movpiece]; }*/ int gain[100], d = 0; Bitset occ = pos.OccupiedSq; /*Bitset occ90 = pos.OccupiedSq90; Bitset occ45 = pos.OccupiedSq45; Bitset occ135 = pos.OccupiedSq135;*/ Bitset pieces[2][6]; for (int i = 0;i<2;i++) { for (int j = 0;j<6;j++) { pieces[i][j] = pos.Pieces[i][j]; } } int turn = pos.turn; gain[d] = PieceMaterial[capt]; //cout << "gain " << d << " is " << gain[0] << endl; Move m = CONS_NULLMOVE; do { //cout << m.toString() << movpiece << endl; d++; // next depth and side gain[d] = PieceMaterial[movpiece] - gain[d - 1]; // speculative store, if defended if (max(-gain[d - 1], gain[d]) < 0) break; // pruning does not influence the result //cout << "gain " << d << " is " << gain[d] << endl; pos.OccupiedSq ^= getPos2Bit(from); // reset bit in temporary occupancy (for x-Rays) /*pos.OccupiedSq90 ^= getPos2Bit(getturn90(from)); pos.OccupiedSq45 ^= getPos2Bit(getturn45(from)); pos.OccupiedSq135 ^= getPos2Bit(getturn135(from));*/ pos.Pieces[turn][movpiece] ^= getPos2Bit(from); turn = getOpponent(turn); m = pos.getSmallestAttacker(turn, to); from = m.getFrom(); capt = movpiece; movpiece = m.getMovingPiece(); } while (m.isNullMove() == false); pos.OccupiedSq = occ; /*pos.OccupiedSq90 = occ90; pos.OccupiedSq45 = occ45; pos.OccupiedSq135 = occ135;*/ for (int i = 0;i<2;i++) { for (int j = 0;j<6;j++) { pos.Pieces[i][j] = pieces[i][j]; } } //cout << "gain " << d << " is " << gain[d] << endl; while (--d) { gain[d - 1] = -max(-gain[d - 1], gain[d]); //d--; //cout << "gain " << d << " is " << gain[d] << endl; } return gain[0]; }
vector<Message> AIInterface::getValidMoves(Duel* d) { vector<Message> moves(0); int player = getPlayerToMove(d); if (d->turn == player && d->attackphase == PHASE_NONE && !(d->isChoiceActive) && d->castingcard == -1) { Message m("endturn"); m.addValue("player", d->turn); moves.push_back(m); } else if (d->isChoiceActive && player == d->choicePlayer) { if (d->choice->buttoncount > 0) { Message msg("choiceselect"); msg.addValue("selection", RETURN_BUTTON1); moves.push_back(msg); } if (d->choice->buttoncount > 1) { Message msg("choiceselect"); msg.addValue("selection", RETURN_BUTTON2); moves.push_back(msg); } for (vector<Card*>::iterator i = d->CardList.begin(); i != d->CardList.end(); i++) { if ((*i)->Zone != ZONE_EVOLVED) { if (d->choice->callvalid(d->choiceCard, (*i)->UniqueId) == 1) { Message msg("choiceselect"); msg.addValue("selection", (*i)->UniqueId); moves.push_back(msg); } } } } else if (d->attackphase == PHASE_TRIGGER && player == getOpponent(d->turn)) //use shield triggers { for (vector<Card*>::iterator i = d->hands[getOpponent(d->turn)].cards.begin(); i != d->hands[getOpponent(d->turn)].cards.end(); i++) { for (vector<int>::iterator j = d->shieldtargets.begin(); j != d->shieldtargets.end(); j++) { if (*j == (*i)->UniqueId) { if (d->getIsShieldTrigger(*j) && d->canUseShieldTrigger(*j) && d->getCardCanCast(*j)) { Message msg("triggeruse"); msg.addValue("trigger", *j); moves.push_back(msg); } } } } Message m("triggerskip"); moves.push_back(m); } else if (d->attackphase == PHASE_TARGET && player == d->turn) //target shields { for (vector<Card*>::iterator i = d->shields[getOpponent(d->turn)].cards.begin(); i != d->shields[getOpponent(d->turn)].cards.end(); i++) { Message m("targetshield"); m.addValue("attacker", d->attacker); m.addValue("shield", (*i)->UniqueId); moves.push_back(m); } } else if (d->attackphase == PHASE_BLOCK && player == getOpponent(d->turn)) //block { for (vector<Card*>::iterator i = d->battlezones[getOpponent(d->turn)].cards.begin(); i != d->battlezones[getOpponent(d->turn)].cards.end(); i++) { if (d->getCreatureCanBlock(d->attacker, (*i)->UniqueId) && (*i)->isTapped == false && ((*i)->UniqueId != d->defender || d->defendertype == DEFENDER_PLAYER)) { /*Message msg2("cardtap"); msg2.addValue("card", (*i)->UniqueId); MsgMngr.sendMessage(msg2);*/ Message msg("creatureblock"); msg.addValue("attacker", d->attacker); msg.addValue("blocker", (*i)->UniqueId); moves.push_back(msg); } } Message m("blockskip"); moves.push_back(m); } else if (d->castingcard != -1 && player == d->turn) //tap mana { for (vector<Card*>::iterator i = d->manazones[d->turn].cards.begin(); i != d->manazones[d->turn].cards.end(); i++) { if ((*i)->isTapped == false) { if (d->castingcost == 1) //last card to be tapped { if (d->getCardCivilization((*i)->UniqueId) == d->castingciv || d->castingcivtapped) { Message m("manatap"); m.addValue("card", (*i)->UniqueId); moves.push_back(m); } } else { Message m("manatap"); m.addValue("card", (*i)->UniqueId); moves.push_back(m); } } } } if (player == d->turn && !d->isChoiceActive) { for (vector<Card*>::iterator i = d->hands[d->turn].cards.begin(); i != d->hands[d->turn].cards.end(); i++) { if (d->getCardCost((*i)->UniqueId) <= d->manazones[d->turn].getUntappedMana() && d->isThereUntappedManaOfCiv(d->turn, d->getCardCivilization((*i)->UniqueId)) && d->getCardCanCast((*i)->UniqueId) == 1) { if (d->getIsEvolution((*i)->UniqueId) == 1) { for (vector<Card*>::iterator j = d->battlezones[d->turn].cards.begin(); j != d->battlezones[d->turn].cards.end(); j++) { if (d->getCreatureCanEvolve((*i)->UniqueId, (*j)->UniqueId) == 1) { Message msg("cardplay"); msg.addValue("card", (*i)->UniqueId); msg.addValue("evobait", (*j)->UniqueId); moves.push_back(msg); } } } else { Message msg("cardplay"); msg.addValue("card", (*i)->UniqueId); msg.addValue("evobait", -1); moves.push_back(msg); } } if (d->manaUsed == 0) { Message msg("cardmana"); msg.addValue("card", (*i)->UniqueId); moves.push_back(msg); } } } if (player == d->turn && !d->isChoiceActive) { for (vector<Card*>::iterator i = d->battlezones[d->turn].cards.begin(); i != d->battlezones[d->turn].cards.end(); i++) { int canattack = d->getCreatureCanAttackPlayers((*i)->UniqueId); if ((canattack == CANATTACK_ALWAYS || ((d->CardList.at((*i)->UniqueId)->summoningSickness == 0 || d->getIsSpeedAttacker((*i)->UniqueId) == 1) && (canattack == CANATTACK_TAPPED || canattack == CANATTACK_UNTAPPED))) && d->CardList.at((*i)->UniqueId)->isTapped == false) { Message msg("creatureattack"); msg.addValue("attacker", (*i)->UniqueId); msg.addValue("defender", getOpponent(d->turn)); msg.addValue("defendertype", DEFENDER_PLAYER); moves.push_back(msg); } for (vector<Card*>::iterator j = d->battlezones[getOpponent(d->turn)].cards.begin(); j != d->battlezones[getOpponent(d->turn)].cards.end(); j++) { int canattack = d->getCreatureCanAttackCreature((*i)->UniqueId, (*j)->UniqueId); if (((*j)->isTapped == true || canattack == CANATTACK_UNTAPPED) && canattack <= CANATTACK_UNTAPPED && d->CardList.at((*i)->UniqueId)->summoningSickness == 0 && d->CardList.at((*i)->UniqueId)->isTapped == false) { Message msg("creatureattack"); msg.addValue("attacker", (*i)->UniqueId); msg.addValue("defender", (*j)->UniqueId); msg.addValue("defendertype", DEFENDER_CREATURE); moves.push_back(msg); } } } } return moves; }
int AIInterface::Evaluate(Duel* pos, int player) { return (5 * pos->shields[player].cards.size() + 4 * pos->battlezones[player].cards.size() + 2 * pos->manazones[player].cards.size() + pos->hands[player].cards.size() - 5 * pos->shields[getOpponent(player)].cards.size() - 4 * pos->battlezones[getOpponent(player)].cards.size() - 2 * pos->manazones[getOpponent(player)].cards.size() - pos->hands[getOpponent(player)].cards.size()); }