zoukankan      html  css  js  c++  java
  • deMeer5_Defender

    #include "Player.h"

    SoccerCommand Player::deMeer5_Defender()
    {
    SoccerCommand soc(CMD_ILLEGAL);
    if (WM->isBeforeKickOff())
    {
    // if not in kickoff formation, teleport to kick_off formation
    if (formations->getFormation() != FT_INITIAL || WM->getAgentGlobalPosition().getDistanceTo(WM->getStrategicPosition()) > 2.0)
    {
    formations->setFormation(FT_INITIAL);
    soc = teleportToPos(WM->getStrategicPosition());
    }
    // else turn to front
    else
    {
    soc = turnBodyToPoint(WM->getAgentGlobalPosition() + VecPosition(1, 0), 0);
    ACT->putCommandInQueue(alignNeckWithBody());
    }
    }
    else
    {
    Log.log(100, " windywinter4defender");
    soc = windywinter4defender();
    }

    ACT->putCommandInQueue(soc);
    ACT->putCommandInQueue(WM->getChangeViewCommand());
    return soc;
    }

    SoccerCommand Player::windywinter4defender()
    {
    SoccerCommand soc(CMD_ILLEGAL);
    ObjectT ClosestTeamMate = WM->getClosestRelativeInSet(OBJECT_SET_TEAMMATES);
    ObjectT ClosestOpponent = WM->getClosestRelativeInSet(OBJECT_SET_OPPONENTS);
    int iTmp;

    PS->setBallConfThr(0.95);
    PS->setTackleHighConfThr(0.75);

    // if ball pos unknown, search for it
    if (WM->getConfidence(OBJECT_BALL) < PS->getBallConfThr())
    {
    Log.log(100, " search ball");
    soc = searchBall();
    ACT->putCommandInQueue(alignNeckWithBody());
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // if kickable (which means the ball is in kickable range and the play mode allows us to kick)
    else if (WM->isBallKickable())
    {
    if (WM->isDeadBallUs() && WM->isInOwnPenaltyArea(WM->getBallPos()))
    {
    Log.log(100, " dead ball in penalty area");
    AngDeg angBall = (WM->getBallPos() - WM->getAgentGlobalPosition()).getDirection();
    angBall = VecPosition::normalizeAngle(angBall - 90);
    VecPosition pos = WM->getBallPos() + VecPosition(2, angBall, POLAR);
    soc = moveToPos(pos, PS->getPlayerWhenToTurnAngle());
    ACT->putCommandInQueue(lookaround(soc));
    }
    // if close to opponent goal or goalie and not an indirect free kick, shoot
    if ((WM->getAgentGlobalPosition().getDistanceTo(WM->getPosOpponentGoal()) < 12.0 || WM->getAgentGlobalPosition().getDistanceTo(WM->getGlobalPosition(OBJECT_OPPONENT_GOALIE)) < 3.0)
    && !WM->isIndirectFreeKickUs())
    {
    Log.log(100, " shoot");
    Line shoot_line_1 = Line::makeLineFromTwoPoints(WM->getBallPos(), WM->getPosOpponentGoalTop());
    Line shoot_line_2 = Line::makeLineFromTwoPoints(WM->getBallPos(), WM->getPosOpponentGoalBottom());
    double distance_1 = shoot_line_1.getDistanceWithPoint(WM->predictPosAfterNrCycles(OBJECT_OPPONENT_GOALIE, 1));
    double distance_2 = shoot_line_2.getDistanceWithPoint(WM->predictPosAfterNrCycles(OBJECT_OPPONENT_GOALIE, 1));
    VecPosition posGoal;
    double shoot_range = max(SS->getGoalWidth() * WM->getAgentGlobalPosition().getDistanceTo(WM->getPosOpponentGoal()) / PITCH_LENGTH, 0.3);
    if (distance_1 < distance_2)
    {
    posGoal = WM->getPosOpponentGoalBottom() - shoot_range;
    }
    else
    {
    posGoal = WM->getPosOpponentGoalTop() + shoot_range;
    }
    soc = kickTo(posGoal, SS->getBallSpeedMax()); // kick maximal
    ACT->putCommandInQueue(lookaround(soc));
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // prepare to take dead ball, look for teammates first
    else if (WM->isDeadBallUs() && WM->getConfidence(ClosestTeamMate) < 0.98)
    {
    Log.log(100, " our dead ball, search for teammate");
    soc = SoccerCommand(CMD_TURN, VecPosition::normalizeAngle(WM->getAgentGlobalBodyAngle() + 60));
    ACT->putCommandInQueue(alignNeckWithBody());
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    else if (WM->getBallPos().getX() < -10.0
    && WM->getActualKickPowerRate(WM->getClosestInSetTo(OBJECT_SET_OPPONENTS, OBJECT_BALL)) > 0.75//对于球相对于当前agent的位置,计算实际踢球力量的比率。
    && WM->getProbTackleSucceeds() > PS->getTackleHighConfThr())//agent铲球成功的概率>
    {
    Log.log(100, " too dangerous, tackle it");
    Line body = Line::makeLineFromPositionAndAngle(WM->getAgentGlobalPosition(), WM->getAgentGlobalBodyAngle());
    Line bottom = Line::makeLineFromTwoPoints(VecPosition(-PITCH_LENGTH/2, 7.01), VecPosition(-PITCH_LENGTH/2, -7.01));
    if (fabs(body.getIntersection(bottom).getY())>8.0)
    {
    soc = tackle(WM->getAgentGlobalBodyAngle());
    }
    else
    {
    VecPosition agent_to_top = VecPosition(-PITCH_LENGTH/2, PITCH_WIDTH/2) - WM->getAgentGlobalPosition();
    VecPosition agent_to_bottom = VecPosition(-PITCH_LENGTH/2, -PITCH_WIDTH/2) - WM->getAgentGlobalPosition();
    VecPosition agent_body = VecPosition(1, WM->getAgentGlobalBodyAngle(), POLAR);
    if (agent_body.getAngleTo(agent_to_top) < agent_body.getAngleTo(agent_to_bottom))
    {
    soc = tackle(agent_to_top.getDirection());
    }
    else
    {
    soc = tackle(agent_to_bottom.getDirection());
    }
    }
    }
    else
    {
    soc = getBestPassCmd_Defender();
    if (soc.commandType == CMD_ILLEGAL)
    {
    soc = getSecondPassCmd_Defender(8);
    }
    // pass ball (for both play on and dead ball)
    if (soc.commandType != CMD_ILLEGAL)
    {
    Log.log(100, " pass ball");
    // prevent too smart kick
    if (WM->isDeadBallUs() && soc.dPower < 30.0) soc.dPower = 100.0;
    ACT->putCommandInQueue(lookaround(soc));
    }
    // if no one to pass, stamina high and not a dead ball, dribble
    else if (WM->getAgentStamina().getStamina() > SS->getRecoverDecThr() * SS->getStaminaMax() + 800
    && !WM->isDeadBallUs())
    {
    ObjectT ClosestOpponentAhead = WM->getClosestAheadRelativeInSet(OBJECT_SET_OPPONENTS);
    double disToOpp=WM->getAgentGlobalPosition().getDistanceTo(WM->getGlobalPosition(ClosestOpponentAhead));
    if (ClosestOpponentAhead==OBJECT_ILLEGAL || disToOpp>5)
    {
    soc=dribble((WM->getPosOpponentGoal()-WM->getBallPos()).getDirection(),6);
    }
    else if (disToOpp>2)
    {
    double angOpp=VecPosition::normalizeAngle(WM->getGlobalBodyAngle(ClosestOpponentAhead));//标准化角度。(-180,180)
    double outPlayAng;
    if ((angOpp>=0)&&(angOpp<180)) outPlayAng=fabs(VecPosition::normalizeAngle(angOpp+45));
    else outPlayAng=fabs(VecPosition::normalizeAngle(angOpp-45));
    soc=dribble(outPlayAng,5);
    Log.log(100,"dangerous outPlayAng is %lf ",outPlayAng);
    }
    else
    {
    Log.log(100, " no one to pass the ball, kick to opponent goal");
    VecPosition posGoal(PITCH_LENGTH / 2.0, (-1 + 2 * (WM->getCurrentCycle() % 2)) * 0.4 * SS->getGoalWidth());
    soc = kickTo(posGoal, SS->getBallSpeedMax());
    Log.log(100,"hold ball");
    }
    ACT->putCommandInQueue(lookaround(soc));
    }
    else
    {
    Log.log(100, " no one to pass the ball, kick to opponent goal");
    VecPosition posGoal(PITCH_LENGTH / 2.0, (-1 + 2 * (WM->getCurrentCycle() % 2)) * 0.4 * SS->getGoalWidth());
    soc = kickTo(posGoal, SS->getBallSpeedMax());
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    }
    // if we get a dead ball, and it's not in our penalty area (if is, the goalie will take it sooner or later)
    // if this player is closest to the ball, he will go to take the ball
    else if (WM->isDeadBallUs() && !WM->isBallInOwnPenaltyArea()
    && WM->getClosestInSetTo(OBJECT_SET_TEAMMATES_NO_GOALIE, OBJECT_BALL) == WM->getAgentObjectType())
    {
    Log.log(100, " go to take dead ball");
    // if not in position, move to position
    if (WM->getRelativeDistance(OBJECT_BALL) >= SS->getPlayerSize()+0.05)
    {
    soc = moveToPos(getDeadBallPosition(), 5); // move to take dead ball
    // if stamina low, dash slowly
    if (soc.commandType == CMD_DASH && WM->getAgentStamina().getStamina() < SS->getRecoverDecThr() * SS->getStaminaMax() + 800)
    {
    Log.log(100, " but stamina is too low");
    soc.dPower = min(30.0 * WM->getAgentStamina().getRecovery(), soc.dPower*0.3);
    }
    ACT->putCommandInQueue(lookaround(soc));
    }
    // else wait till kickable signal
    else
    {
    soc = turnBodyToPoint(WM->getPosOpponentGoal());
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // if this player is 2nd closest to the ball, he will go to back up the 1st one
    else if (WM->isDeadBallUs() && !WM->isBallInOwnPenaltyArea()
    && WM->getSecondClosestInSetTo(OBJECT_SET_TEAMMATES_NO_GOALIE, OBJECT_BALL) == WM->getAgentObjectType())
    {
    Log.log(100, " go to backup dead ball");
    // if not in position, move to position
    if (WM->getRelativeDistance(OBJECT_BALL) >= SS->getOffsideKickMargin())
    {
    soc = moveToPos(getDeadBallBackUpPosition(), 5); // move to take dead ball
    // if stamina low, dash slowly
    if (soc.commandType == CMD_DASH && WM->getAgentStamina().getStamina() < SS->getRecoverDecThr() * SS->getStaminaMax() + 800)
    {
    Log.log(100, " but stamina is too low");
    soc.dPower = min(30.0 * WM->getAgentStamina().getRecovery(), soc.dPower*0.3);
    }
    ACT->putCommandInQueue(lookaround(soc));
    }
    // else wait till kickable signal
    else
    {
    soc = turnBodyToPoint(WM->getBallPos());
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // if opponents get a dead ball in forward and this player can get there in time, go to set up a wall
    else if (WM->isDeadBallThem() && WM->getBallPos().getX()<-15 && WM->predictNrCyclesToPoint(WM->getAgentObjectType(), WM->getBallPos()) < 18)
    {//预测对象从当前位置移动到posTo所需的周期数。
    Log.log(100, " set up wall of players");
    VecPosition pos = getDeadBallDefencePosition();
    if (WM->getAgentGlobalPosition().getDistanceTo(pos) > SS->getPlayerSize())
    {
    Log.log(100, " move to pos (%f,%f)", pos.getX(), pos.getY());
    soc = moveToPos(pos, 20);
    VecPosition pos = getDeadBallDefencePosition();
    ACT->putCommandInQueue(lookaround(soc));
    }
    else
    {
    soc = turnBodyToPoint(WM->getBallPos());
    ACT->putCommandInQueue(alignNeckWithBody());
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // if opponents possess ball and it's safe to tackle it, tackle
    else if (WM->getBallPos().getX() < -10.0
    && WM->isBallInTheirPossesion()//拥有球·-
    && WM->getProbTackleSucceeds() > PS->getTackleHighConfThr() * min(WM->getBallPos().getDistanceTo(WM->getPosOwnGoal())/30.0, (WM->getBallPos()-WM->getGlobalPosition(WM->getLastDefender())).getX()<0 ? 0.5 : 1))
    {
    Log.log(100, " too dangerous, tackle it");
    // tackle to closest teammate
    if (ClosestTeamMate != OBJECT_ILLEGAL)
    {
    soc = tackle((WM->getGlobalPosition(ClosestTeamMate) - WM->getAgentGlobalPosition()).getDirection());
    }
    // tackle to body angle
    else
    {
    Line body = Line::makeLineFromPositionAndAngle(WM->getAgentGlobalPosition(), WM->getAgentGlobalBodyAngle());
    Line bottom = Line::makeLineFromTwoPoints(VecPosition(-PITCH_LENGTH/2, 7.01), VecPosition(-PITCH_LENGTH/2, -7.01));
    if (fabs(body.getIntersection(bottom).getY())>8.0)
    {
    soc = tackle(WM->getAgentGlobalBodyAngle());
    }
    else
    {
    VecPosition agent_to_top = VecPosition(-PITCH_LENGTH/2, PITCH_WIDTH/2) - WM->getAgentGlobalPosition();
    VecPosition agent_to_bottom = VecPosition(-PITCH_LENGTH/2, -PITCH_WIDTH/2) - WM->getAgentGlobalPosition();
    VecPosition agent_body = VecPosition(1, WM->getAgentGlobalBodyAngle(), POLAR);
    if (agent_body.getAngleTo(agent_to_top) < agent_body.getAngleTo(agent_to_bottom))
    {
    soc = tackle(agent_to_top.getDirection());
    }
    else
    {
    soc = tackle(agent_to_bottom.getDirection());
    }
    }
    }
    ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NORMAL, VQ_HIGH));
    }
    else
    {
    int cycles_opponent_to_ball, cycles_fastest_to_ball, cycles_intercept;
    ObjectT obj_fastest_to_ball = WM->getFastestInSetTo(OBJECT_SET_TEAMMATES_NO_GOALIE, OBJECT_BALL, &cycles_fastest_to_ball);
    WM->predictCommandToInterceptBall(WM->getAgentObjectType(), interceptClose(), &cycles_intercept);
    WM->getFastestInSetTo(OBJECT_SET_OPPONENTS, OBJECT_BALL, &cycles_opponent_to_ball);
    // if fastest to ball, intercept it
    if ((obj_fastest_to_ball == WM->getAgentObjectType() || (cycles_intercept<=cycles_fastest_to_ball+2/* && cycles_opponent_to_ball<=cycles_fastest_to_ball+2*/))
    && !WM->isDeadBallThem() && !WM->isDeadBallUs()
    && WM->getBallPos().getDistanceTo(WM->getGlobalPosition(OBJECT_TEAMMATE_1)) > 1.085)
    {
    Log.log(100, " fastest to ball; can get there in %d cycles", cycles_intercept);
    soc = intercept(false);
    if ((WM->getCurrentTime().getTime()+WM->getCurrentTime().getTimeStopped())%2 == 1)
    {
    ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));
    }
    else
    {
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    else
    {
    // find most valuable player to mark, if there is one and the ball is not in safe position
    pair<double, ObjectT> mark_target = getMostValuableMarkObj();
    if (WM->getBallPos().getX() < 6.0
    && mark_target.second != OBJECT_ILLEGAL && mark_target.first<10000 && WM->getGlobalPosition(mark_target.second).getX() < 0
    && !WM->isDeadBallUs() && (!WM->isDeadBallThem() || WM->isDeadBallThem() && WM->getRelativeDistance(OBJECT_BALL) > SS->getOffsideKickMargin()))
    {
    // if the obj is fastest to ball, mark ball instead
    Log.log(100, " mark %d, profit %f", SoccerTypes::getIndex(mark_target.second)+1, mark_target.first);
    if (WM->getFastestInSetTo(OBJECT_SET_OPPONENTS, OBJECT_BALL, &iTmp) == mark_target.second)
    {
    mark_target.second = OBJECT_BALL;
    }

    soc = mark(mark_target.second, 3.0, MARK_GOAL);

    // calculate save_stamina_rate
    double save_stamina_rate = 0.9* min(1+WM->getBallPos().getX()/((PITCH_LENGTH-PENALTY_AREA_LENGTH)/2), WM->getBallPos().getDistanceTo(WM->getGlobalPosition(mark_target.second)/(PITCH_LENGTH-PENALTY_AREA_LENGTH)));
    VecPosition target_to_ball = WM->getBallPos()-WM->getGlobalPosition(mark_target.second);
    VecPosition target_speed = WM->getGlobalVelocity(mark_target.second);
    if (target_speed.getAngleTo(target_to_ball) < 20.0) save_stamina_rate/=2;
    if (save_stamina_rate > 0.9) save_stamina_rate = 0.9;

    // if stamina low, dash slowly
    if (soc.commandType == CMD_DASH && WM->getAgentStamina().getStamina() < save_stamina_rate * SS->getStaminaMax() )
    {
    soc.dPower = min(30.0 * WM->getAgentStamina().getRecovery(), soc.dPower*0.3);
    Log.log(100, " but stamina is too low");
    }

    if (mark_target.second == OBJECT_BALL)
    {
    if (WM->getRelativeDistance(OBJECT_BALL) > 3.0)
    {
    ACT->putCommandInQueue(turnNeckToPoint(WM->getBallPos(), soc));
    }
    else
    {
    ACT->putCommandInQueue(lookaround(soc));
    }
    }
    else if (WM->getRelativeDistance(mark_target.second) < 6.0
    && WM->getTimeGlobalAngles(mark_target.second) == WM->getCurrentTime())
    {
    ACT->putCommandInQueue(turnNeckToPoint(WM->getGlobalPosition(mark_target.second) + VecPosition(12, WM->getGlobalNeckAngle(mark_target.second), POLAR), soc));
    }
    else
    {
    ACT->putCommandInQueue(turnNeckToPoint(WM->getGlobalPosition(mark_target.second), soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // else if not near strategic pos, go to strategic pos
    else if (WM->getAgentGlobalPosition().getDistanceTo(WM->getStrategicPosition()) > SS->getPlayerSize()*4 /*+ fabs(WM->getAgentGlobalPosition().getX() - WM->getBallPos().getX()) / 10.0*/)
    {
    Log.log(100, " move to strategic position");
    soc = moveToPos(WM->getStrategicPosition(), PS->getPlayerWhenToTurnAngle());
    // calculate save_stamina_rate
    double save_stamina_rate = 0.9;
    if (WM->getAgentGlobalPosition().getX() < WM->getGlobalPosition(WM->getFirstOpponent()).getX())
    {
    save_stamina_rate = 0.3;
    }
    // if stamina low, dash slowly
    if (soc.commandType == CMD_DASH && WM->getAgentStamina().getStamina() < save_stamina_rate * SS->getStaminaMax() )
    {
    soc.dPower = min(30.0 * WM->getAgentStamina().getRecovery(), soc.dPower*0.3);
    Log.log(100, " but stamina is too low");
    }
    if ((WM->getCurrentTime().getTime()+WM->getCurrentTime().getTimeStopped())%2 == 1)
    {
    ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));
    }
    else
    {
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    // nothing to do
    else
    {
    Log.log(100, " nothing to do but watching ball or looking around");
    if (WM->isDeadBallUs())
    {
    if ((WM->getCurrentTime().getTime()+WM->getCurrentTime().getTimeStopped())%2 == 1)
    {
    ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));
    }
    else
    {
    ACT->putCommandInQueue(lookaround(soc));
    }
    ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));
    }
    else
    {
    soc = turnBodyToPoint(WM->getAgentGlobalPosition() + VecPosition(1, 0), 0);
    ACT->putCommandInQueue(lookaround(soc));
    }
    WM->setChangeViewCommand(SoccerCommand(CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH));
    }
    }
    }
    return soc;
    }

    SoccerCommand BasicPlayer::getBestPassCmd_Defender()
    {
    static Feature last_best_cmd;
    if (last_best_cmd.getTimeSee() > WM->getCurrentTime()-2 && last_best_cmd.getCommand().commandType != CMD_ILLEGAL
    && WM->getMinEndSpeed4SafePass(last_best_cmd.getVec()) > 0
    && (WM->isOnside(last_best_cmd.getObject()) || !WM->isOnside(WM->getAgentObjectType())))//判断对象是否未越位。
    {
    Log.log(101, " pass to same pos as last cycle");
    return kickTo(last_best_cmd.getVec(), last_best_cmd.getInfo());
    }

    SoccerCommand soc(CMD_ILLEGAL);
    double max_pass_profit = 0.1;
    VecPosition best_pass_target = VecPosition(UnknownDoubleValue, UnknownDoubleValue);
    ObjectT best_pass_target_o = OBJECT_ILLEGAL;
    double best_pass_speed = -1.0;
    int iIndex;
    for (ObjectT o = WM->iterateObjectStart(iIndex, OBJECT_SET_TEAMMATES_NO_GOALIE, PS->getPlayerHighConfThr()); o != OBJECT_ILLEGAL;
    o = WM->iterateObjectNext(iIndex, OBJECT_SET_TEAMMATES_NO_GOALIE, PS->getPlayerHighConfThr()))
    {
    if (o != WM->getAgentObjectType() && (WM->isOnside(o) || !WM->isOnside(WM->getAgentObjectType())))
    {
    Log.log(101, " calculating pass to %d", SoccerTypes::getIndex(o)+1);
    double confidence = WM->getConfidence(o);
    for (AngDeg leading_dir = -180.0; leading_dir <= 180.0; leading_dir += 30.0)
    {
    if (WM->getTimeGlobalAngles(o) > WM->getCurrentTime()-4)//time储存了身体和脖子的角度
    {
    confidence *= cos(VecPosition::normalizeAngle(leading_dir - WM->getGlobalBodyAngle(o))/180 * PI/2)/2 + 0.5;
    }
    else
    {
    confidence *= 0.5;
    }
    for (double leading_dist = 0; leading_dist <= 4.0; leading_dist += 1.0)
    {
    VecPosition pass_target = WM->getGlobalPosition(o) + VecPosition(leading_dist, leading_dir, POLAR);
    double distX = pass_target.getX() - WM->getBallPos().getX();
    double posY = fabs(pass_target.getY());
    if (pass_target.getX()>30)
    {
    posY = PITCH_WIDTH / 2.0 - posY;
    }
    distX = min(24.0, distX);
    double profit = sin(distX/24.0*PI)*24.0 * posY/4.0;
    if (profit*confidence > max_pass_profit)
    {
    int pass_cycles;
    ObjectT fastest_opponent;
    double min_pass_speed = WM->getMinEndSpeed4SafePass(pass_target, &fastest_opponent, &pass_cycles);
    if (min_pass_speed > 0)
    {
    int cycles_o = WM->predictNrCyclesToPoint(o, pass_target);
    if (cycles_o <= pass_cycles)
    {
    int safety_cycles = min(3, WM->predictNrCyclesToPoint(fastest_opponent, pass_target) - pass_cycles);
    double max_pass_speed = WM->getEndSpeedFromFirstSpeed(WM->getBallPos().getDistanceTo(pass_target) *(1-SS->getBallDecay()) / (1- pow(SS->getBallDecay(), cycles_o+1)), cycles_o);

    //profit += min_pass_speed*4;
    confidence *= fabs(sin(min(1.0, safety_cycles/3.0)* PI/2));
    profit *= confidence;
    if (profit > max_pass_profit)
    {
    max_pass_profit = profit;
    best_pass_target = pass_target;
    best_pass_speed = (min_pass_speed+max_pass_speed)/2;
    best_pass_target_o = o;
    }
    Log.log(102, " pos (%f,%f) profit %f", pass_target.getX(), pass_target.getY(), profit);
    }
    }
    }
    }
    }
    }
    }
    WM->iterateObjectDone(iIndex);
    if (best_pass_target_o != OBJECT_ILLEGAL)
    {
    soc = kickTo(best_pass_target, best_pass_speed);
    last_best_cmd.setTimeSee(WM->getCurrentTime());
    last_best_cmd.setVec(best_pass_target);
    last_best_cmd.setInfo(best_pass_speed);
    last_best_cmd.setObject(best_pass_target_o);
    Log.log(101, " pass to %d pos (%f,%f) profit %f", SoccerTypes::getIndex(best_pass_target_o)+1, best_pass_target.getX(), best_pass_target.getY(), max_pass_profit);
    }
    return soc;
    }

    SoccerCommand BasicPlayer::getSecondPassCmd_Defender(double minPassProfit)
    {
    return getSecondPassCmd_Attacker(minPassProfit);
    }



    作者:BuildNewApp
    出处:http://syxchina.cnblogs.comBuildNewApp.com
    本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
    如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。
  • 相关阅读:
    编写SASS代码
    表单
    动画和变形
    图片多媒体
    基本概念
    弹性布局
    HTML和CSS概述
    页面的制作过程
    盒子定位体系
    css盒子
  • 原文地址:https://www.cnblogs.com/syxchina/p/2197599.html
Copyright © 2011-2022 走看看