Beispiel #1
0
  //--------------------------------------------- HAS PATH ---------------------------------------------------
  bool UnitInterface::hasPath(PositionOrUnit target) const
  {
    Broodwar->setLastError();
    // Return error if the position is invalid
    if ( !target.getPosition() )
      return Broodwar->setLastError(Errors::Invalid_Parameter);

    // Return true if this unit is an air unit
    if ( this->isFlying() )
      return true;

    // Return error if either this or the target does not "exist"
    if ( (target.getUnit() && !target.getUnit()->exists()) || !exists() )
      return Broodwar->setLastError(Errors::Unit_Not_Visible);

    // return result of Game::hasPath
    return Broodwar->hasPath(this->getPosition(), target.getPosition());
  }
Beispiel #2
0
  //--------------------------------------------- GET DISTANCE -----------------------------------------------
  int UnitImpl::getDistance(PositionOrUnit target) const
  {
    // If this unit does not exist
    if ( !exists() )
      return MAXINT;

    // Must be something valid
    if ( !target.getUnit() && !target.getPosition() )
      return MAXINT;

    // if target is a unit but doesn't exist
    if ( target.getUnit() && !target.getUnit()->exists() )
      return MAXINT;

    // If target is the same as the source
    if ( this == target.getUnit() )
      return MAXINT;

    // Compute distance
    return computeDistance(this, target);
  }
Beispiel #3
0
  //--------------------------------------------- GET DISTANCE -----------------------------------------------
  int UnitInterface::getDistance(PositionOrUnit target) const
  {
    // If this unit does not exist
    if ( !exists() )
      return std::numeric_limits<int>::max();

    // Must be something valid
    if ( !target.getUnit() && !target.getPosition() )
      return std::numeric_limits<int>::max();

    // if target is a unit but doesn't exist
    if ( target.getUnit() && !target.getUnit()->exists() )
      return std::numeric_limits<int>::max();

    // If target is the same as the source
    if ( this == target.getUnit() )
      return std::numeric_limits<int>::max();

    /////// Compute distance

    // retrieve left/top/right/bottom values for calculations
    int left, right, top, bottom;

    if ( target.isPosition() )
    {
      // Retrieve the target position if it is so
      Position targPos = target.getPosition();
      left    = targPos.x - 1;
      top     = targPos.y - 1;
      right   = targPos.x + 1;
      bottom  = targPos.y + 1;
    }
    else
    {
      // Retrieve the target unit if it's not a position
      Unit pUnit = target.getUnit();

      // return if target is invalid
      if ( !pUnit || pUnit == this )
        return 0;

      left    = pUnit->getLeft() - 1;
      top     = pUnit->getTop() - 1;
      right   = pUnit->getRight() + 1;
      bottom  = pUnit->getBottom() + 1;
    }

    // compute x distance
    int xDist = this->getLeft() - right;
    if ( xDist < 0 )
    {
      xDist = left - this->getRight();
      if ( xDist < 0 )
        xDist = 0;
    }

    // compute y distance
    int yDist = this->getTop() - bottom;
    if ( yDist < 0 )
    {
      yDist = top - this->getBottom();
      if ( yDist < 0 )
        yDist = 0;
    }

    // compute actual distance
    return Positions::Origin.getApproxDistance(Position(xDist, yDist));
  }
Beispiel #4
0
 //--------------------------------------------- USE TECH ---------------------------------------------------
 bool UnitInterface::useTech(TechType tech, PositionOrUnit target)
 {
   if ( target.isUnit() && target.getUnit() == nullptr )
     return this->issueCommand(UnitCommand::useTech(this,tech));
   return this->issueCommand(UnitCommand::useTech(this,tech,target));
 }
Beispiel #5
0
 //--------------------------------------------- USE TECH ---------------------------------------------------
 bool Unitset::useTech(TechType tech, PositionOrUnit target) const
 {
   if ( target.isUnit() && target.getUnit() == nullptr )
     return this->issueCommand(UnitCommand::useTech(nullptr,tech));
   return this->issueCommand(UnitCommand::useTech(nullptr,tech,target));
 }
    void DesolatorModule::onFrame() {
        auto & ourUnits    = us_->getUnits();
        auto & theirUnits  = them_->getUnits();

        // Return if the game is a replay or is paused
        if ( Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self() )
            return;

        // Prevent spamming by only running our onFrame once every number of latency frames.
        // Latency frames are the number of frames before commands are processed.
        if ( Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0 )
            return;

        /************************/
        /**** DESOLATOR CODE ****/
        /************************/

        if ( theirUnits.empty() ) {
            //   cout << "Exploring" << endl;
            for (auto u : ourUnits) {
                unitStates_[u->getID()].setNoDraw();
            }
            // Only move when idle.
            if(!ourUnits.begin()->isMoving()) {
                ourUnits.move(AI::explore());
            }
        }
        else {
            //cout << "New action frame" << endl;
            // This updates the game state for each unit we have ( not the MDP state though )
            for ( auto u : ourUnits )
                updateUnitState(u);
            //cout << "Basic update completed" << endl;
            for ( auto u : ourUnits )
                shareKnowledge(u);
            //cout << "Shares completed" << endl;
            // Now that the observations of the units are correct, we select the actions that we want the units to perform.
            for ( auto u : ourUnits ) {
                auto & GS = unitStates_[u->getID()];
                //cout << "Executing unit " << u->getID() << endl;

                // Check when the units moved a tile
                bool moved = GS.updatePosition(u->getTilePosition());

                // Hack to avoid units stopping while actually moving..
                if ( !moved && GS.lastAction == Action::Move && GS.lastPerfectPosition == u->getPosition() )
                    GS.notMovingTurns++;
                else {
                    GS.lastPerfectPosition = u->getPosition();
                    GS.notMovingTurns = 0;
                }
                //cout << "- unit movement updates done" << endl;
                // If our personal tick ended
                if ( u->isIdle() || moved || GS.lastAction == Action::None ||
                   ( GS.lastAction == Action::Attack && ! GS.isStartingAttack &&  ! u->isAttackFrame() ) ) {
                    //cout << "- UNIT TICK" << endl;
                    updateUnitMDPState(u);
                    //cout << "- UNIT MDP updated state" << endl;

                    Strategy strategy;
                    Action action;

                    int selectedAction = 0;
                    //cout << "We use policy? " << usingPolicy_ << endl;
                    // We check if we follow the policy or we go full random
                    if (usingPolicy_) {
                        AIToolbox::EpsilonPolicy p(policy_,1);
                        selectedAction = p.sampleAction(GS.state);
                    }
                    else selectedAction = RandomInt::get(0,1);
                    //selectedAction = 1;
                    //cout << "Got action: " << selectedAction << endl;
                    switch ( selectedAction ) {
                        case 1: { // We flee
                            strategy = Strategy::Flee;
                            //cout << "Flee!" << endl;
                            // Obtain where to flee
                            auto position = AI::flee(u, ourUnits, theirUnits, unitStates_);

                            action = moveUnitToPosition(u, position);

                            break;
                        }
                        default: { // We attack
                            strategy = Strategy::Fight;
                            action   = Action::Attack;
                            //cout << "Fight" << endl;
                            // Obtain who to attack or where to go
                            PositionOrUnit target = AI::attack(u, ourUnits, theirUnits, unitStates_);

                            if ( target.isPosition() ) {
                                action = moveUnitToPosition(u, target.getPosition());
                            }
                            // This check is to avoid breaking Starcraft when we spam attack command
                            else {
                                if ( u->getOrder() != Orders::AttackUnit || unitStates_[u->getID()].lastTarget != target.getUnit() ) {
                                    u->attack(target.getUnit());

                                    GS.isStartingAttack = true;
                                    GS.lastTarget = target.getUnit();

                                    GS.setDraw(target);
                                    //cout << "Attack" << endl;
                                }
                            }
                        }
                    }
                    //cout << "UNIT action selected" << strategy << endl;
                    // Update Action taken
                    GS.lastStrategy = strategy;
                    GS.lastAction = action;

                } // End, personal tick
                // End of hack, here we stop the units so I guess internally it resets so we can move it again.
                else if ( GS.notMovingTurns == 3 ) {
                    //Broodwar->printf("Unit %d triggered an hack", u->getID());

                    log_ << "HACK TRIGGERED" << "\n";
                    log_ << "Action: " << GS.lastAction << " -- Strategy: " << GS.lastStrategy << "\n";
                    log_ << "Order:  " << u->getOrder() << " -- Position: " << u->getPosition() << " -- Target Position: " << u->getTargetPosition() << "\n";
                    log_ << "Diff = "       << u->getPosition() - u->getTargetPosition() << "\n";
                    log_ << "Unit Tile: "   << convertToTile(u->getPosition())  << " -- Target Tile: " << convertToTile(u->getTargetPosition()) << "\n";

                    u->stop();
                    GS.setNoDraw();
                }
            } // closure: unit iterator
        } // closure: We have enemies
    }