// TODO: UNTESTED const MoveTuple Player_Kiter::getMoveTuple(GameState & state, const MoveArray & moves) { // the tuple, we will generate this on the fly MoveTuple tuple(0); for (IDType u(0); u<moves.numUnits(); ++u) { bool foundAction (false); IDType actionMoveIndex (0); IDType furthestMoveIndex (0); size_t furthestMoveDist (0); IDType closestMoveIndex (0); int actionDistance (std::numeric_limits<int>::max()); unsigned long long closestMoveDist (std::numeric_limits<unsigned long long>::max()); const Unit & ourUnit (state.getUnit(_playerID, u)); const Unit & closestUnit (ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u)); for (IDType m(0); m<moves.numMoves(u); ++m) { const Move move (moves.getMove(u, m)); if (move.type() == MoveTypes::ATTACK) { const Unit & target (state.getUnit(state.getEnemy(move.player()), move._moveIndex)); PositionType dist (ourUnit.distSq(target, state.getTime())); if (dist < actionDistance) { actionDistance = dist; actionMoveIndex = m; foundAction = true; } } else if (move.type() == MoveTypes::HEAL) { const Unit & target (state.getUnit(move.player(), move._moveIndex)); PositionType dist (ourUnit.distSq(target, state.getTime())); if (dist < actionDistance) { actionDistance = dist; actionMoveIndex = m; foundAction = true; } } else if (move.type() == MoveTypes::MOVE) { Position ourDest (ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]); size_t dist (closestUnit.distSq(ourDest, state.getTime())); if (dist > furthestMoveDist) { furthestMoveDist = dist; furthestMoveIndex = m; } if (dist < closestMoveDist) { closestMoveDist = dist; closestMoveIndex = m; } } } // the move we will be returning size_t bestMoveIndex(0); // if we have an attack move we will use that one if (foundAction) { bestMoveIndex = actionMoveIndex; } // otherwise use the closest move to the opponent else { // if we are in attack range of the unit, back up if (ourUnit.canAttackTarget(closestUnit, state.getTime())) { bestMoveIndex = furthestMoveIndex; } // otherwise get back into the fight else { bestMoveIndex = closestMoveIndex; } } // update the tuple calculation tuple += bestMoveIndex * moves.getProduct(u); } return tuple; }
const MoveTuple Player_AttackClosest::getMoveTuple(GameState & state, const MoveArray & moves) { MoveTuple tuple(0); for (IDType u(0); u<moves.numUnits(); ++u) { bool foundAction (false); size_t actionMoveIndex (0); size_t closestMoveIndex (0); unsigned long long actionDistance (std::numeric_limits<unsigned long long>::max()); unsigned long long closestMoveDist (std::numeric_limits<unsigned long long>::max()); const Unit & ourUnit (state.getUnit(_playerID, u)); const Unit & closestUnit (ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u)); for (size_t m(0); m<moves.numMoves(u); ++m) { const Move move (moves.getMove(u, m)); if (move.type() == MoveTypes::ATTACK) { const Unit & target (state.getUnit(state.getEnemy(move.player()), move._moveIndex)); size_t dist (ourUnit.distSq(target, state.getTime())); if (dist < actionDistance) { actionDistance = dist; actionMoveIndex = m; foundAction = true; } } if (move.type() == MoveTypes::HEAL) { const Unit & target (state.getUnit(move.player(), move._moveIndex)); size_t dist (ourUnit.distSq(target, state.getTime())); if (dist < actionDistance) { actionDistance = dist; actionMoveIndex = m; foundAction = true; } } else if (move.type() == MoveTypes::RELOAD) { if (ourUnit.canAttackTarget(closestUnit, state.getTime())) { closestMoveIndex = m; break; } } else if (move.type() == MoveTypes::MOVE) { Position ourDest (ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]); size_t dist (closestUnit.distSq(ourDest, state.getTime())); if (dist < closestMoveDist) { closestMoveDist = dist; closestMoveIndex = m; } } } size_t bestMoveIndex(foundAction ? actionMoveIndex : closestMoveIndex); tuple += bestMoveIndex * moves.getProduct(u); } return tuple; }
const MoveTuple Player_NOK_AttackDPS::getMoveTuple(GameState & state, const MoveArray & moves) { MoveTuple tuple(0); IDType player(moves.getMove(0,0).player()); IDType enemy(state.getEnemy(player)); Array<int, Search::Constants::Max_Units> hpRemaining; if (state.numUnits(enemy) > Search::Constants::Max_Units) { hpRemaining.resize(state.numUnits(enemy)); } for (IDType u(0); u<state.numUnits(enemy); ++u) { hpRemaining[u] = state.getUnit(enemy,u).currentHP(); } for (IDType u(0); u<moves.numUnits(); ++u) { bool foundAction (false); size_t actionMoveIndex (0); double actionHighestDPS (0); size_t closestMoveIndex (0); unsigned long long closestMoveDist (std::numeric_limits<unsigned long long>::max()); const Unit & ourUnit (state.getUnit(_playerID, u)); const Unit & closestUnit (ourUnit.canHeal() ? state.getClosestOurUnit(_playerID, u) : state.getClosestEnemyUnit(_playerID, u)); for (size_t m(0); m<moves.numMoves(u); ++m) { const Move move (moves.getMove(u, m)); if ((move.type() == MoveTypes::ATTACK) && (hpRemaining[move._moveIndex] > 0)) { const Unit & target (state.getUnit(state.getEnemy(move.player()), move._moveIndex)); double dpsHPValue = (target.dpf() / hpRemaining[move._moveIndex]); if (dpsHPValue > actionHighestDPS) { actionHighestDPS = dpsHPValue; actionMoveIndex = m; foundAction = true; } } else if (move.type() == MoveTypes::HEAL) { const Unit & target (state.getUnit(move.player(), move._moveIndex)); double dpsHPValue = (target.dpf() / hpRemaining[move._moveIndex]); if (dpsHPValue > actionHighestDPS) { actionHighestDPS = dpsHPValue; actionMoveIndex = m; foundAction = true; } } else if (move.type() == MoveTypes::RELOAD) { if (ourUnit.canAttackTarget(closestUnit, state.getTime())) { closestMoveIndex = m; break; } } else if (move.type() == MoveTypes::MOVE) { Position ourDest (ourUnit.x() + Search::Constants::Move_Dir[move._moveIndex][0], ourUnit.y() + Search::Constants::Move_Dir[move._moveIndex][1]); size_t dist (closestUnit.distSq(ourDest, state.getTime())); if (dist < closestMoveDist) { closestMoveDist = dist; closestMoveIndex = m; } } } size_t bestMoveIndex(foundAction ? actionMoveIndex : closestMoveIndex); Move theMove(moves.getMove(u, actionMoveIndex)); if (theMove.type() == MoveTypes::ATTACK) { hpRemaining[theMove.index()] -= state.getUnit(player, theMove.unit()).damage(); } tuple += bestMoveIndex * moves.getProduct(u); } return tuple; }