Exemplo n.º 1
0
/* --------------------------------------------------------------------- */
bool
Circle2D::HasIntersection(Line2D line )
{
    double dist = line.dist(this->center());
    if (dist > this->radius()) return false;
    else return true;
}
/*!

*/
bool
Body_GoToPointDodge::get_dodge_point( const PlayerAgent * agent,
                                      const Vector2D & target,
                                      Vector2D * sol )
{
    const WorldModel & wm = agent->world();

    if ( wm.self().pos().dist( target )
         < ServerParam::i().defaultPlayerSize() * 2.0 )
    {
        return false;
    }

    const Line2D line2target( wm.self().pos(), target );

    /*--------------------------------------------------------*/
    // check players
    const AngleDeg target_angle = ( target - wm.self().pos() ).th();
    const double dodge_perpend_dist2
        = square( ServerParam::i().defaultPlayerSize() * 2.0 + 0.1 );

    const double consider_dist_max = 1.5;

    double mindist = 100.0;

    bool found = false;

    PlayerPtrCont::const_iterator it;

    const PlayerPtrCont::const_iterator t_end
        = wm.teammatesFromSelf().end();
    for ( it = wm.teammatesFromSelf().begin();
          it != t_end;
          ++it )
    {
        if ( (*it)->distFromSelf() > consider_dist_max )
        {
            break;
        }
        // this player is near to target trajectry
        if ( mindist > (*it)->distFromSelf()
             && line2target.dist2( (*it)->pos() ) < dodge_perpend_dist2
             && (target_angle - (*it)->angleFromSelf()).abs() < 90.0 )
        {
            mindist = (*it)->distFromSelf();
            *sol = (*it)->pos();
            found = true;
        }
    }

    const PlayerPtrCont::const_iterator o_end
        = wm.opponentsFromSelf().end();
    for ( it = wm.opponentsFromSelf().begin();
          it != o_end;
          ++it )
    {
        if ( (*it)->distFromSelf() > consider_dist_max )
        {
            break;
        }
        // this player is near to target trajectry
        if ( mindist > (*it)->distFromSelf()
             && line2target.dist2( (*it)->pos() ) < dodge_perpend_dist2
             && ( target_angle - (*it)->angleFromSelf() ).abs() < 90.0 )
        {
            mindist = (*it)->distFromSelf();
            *sol = (*it)->pos();
            found = true;
        }
    }

    /*--------------------------------------------------------*/
    // check ball
    if ( wm.gameMode().type() != GameMode::PlayOn
         && wm.ball().posValid() )
    {
        if ( wm.ball().distFromSelf() < consider_dist_max
             && line2target.dist( wm.ball().pos() ) < 1.5
             && ( ( target_angle - ( wm.ball().pos()
                                     - wm.self().pos() ).th() ).abs()
                  < 90.0 ) )
        {
            if ( mindist > wm.ball().distFromSelf() )
            {
                *sol = wm.ball().pos();
                found = true;
            }
        }
    }

    return found;
}
Exemplo n.º 3
0
/*!
  execute action
*/
bool
Bhv_GoalieChaseBall::execute( PlayerAgent * agent )
{
    dlog.addText( Logger::TEAM,
                  __FILE__": Bhv_GoalieChaseBall" );

    //////////////////////////////////////////////////////////////////
    // tackle
    if ( Bhv_BasicTackle( 0.8, 90.0 ).execute( agent ) )
    {
        dlog.addText( Logger::TEAM,
                      __FILE__": tackle" );
        return true;
    }

    const ServerParam & SP = ServerParam::i();
    const WorldModel & wm = agent->world();

    ////////////////////////////////////////////////////////////////////////
    // get active interception catch point

    Vector2D my_int_pos = wm.ball().inertiaPoint( wm.interceptTable()->selfReachCycle() );
    dlog.addText( Logger::TEAM,
                  __FILE__": execute. intercept point=(%.2f %.2f)",
                  my_int_pos.x, my_int_pos.y );

    double pen_thr = wm.ball().distFromSelf() * 0.1 + 1.0;
    if ( pen_thr < 1.0 ) pen_thr = 1.0;

    //----------------------------------------------------------
    const Line2D ball_line( wm.ball().pos(), wm.ball().vel().th() );
    const Line2D defend_line( Vector2D( wm.self().pos().x, -10.0 ),
                              Vector2D( wm.self().pos().x, 10.0 ) );

    if ( my_int_pos.x > - SP.pitchHalfLength() - 1.0
         && my_int_pos.x < SP.ourPenaltyAreaLineX() - pen_thr
         && my_int_pos.absY() < SP.penaltyAreaHalfWidth() - pen_thr )
    {
        bool save_recovery = false;
        if ( ball_line.dist( wm.self().pos() ) < SP.catchableArea() )
        {
            save_recovery = true;
        }
        dlog.addText( Logger::TEAM,
                      __FILE__": execute normal intercept" );
        agent->debugClient().addMessage( "Intercept(0)" );
        Body_Intercept( save_recovery ).execute( agent );
        agent->setNeckAction( new Neck_TurnToBall() );
        return true;
    }

    int self_goalie_min = wm.interceptTable()->selfReachCycle();
    int opp_min_cyc = wm.interceptTable()->opponentReachCycle();

    Vector2D intersection = ball_line.intersection( defend_line );
    if ( ! intersection.isValid()
         || ball_line.dist( wm.self().pos() ) < SP.catchableArea() * 0.8
         || intersection.absY() > SP.goalHalfWidth() + 3.0
         )
    {
        if ( ! wm.existKickableOpponent() )
        {
            if ( self_goalie_min <= opp_min_cyc + 2
                 && my_int_pos.x > -SP.pitchHalfLength() - 2.0
                 && my_int_pos.x < SP.ourPenaltyAreaLineX() - pen_thr
                 && my_int_pos.absY() < SP.penaltyAreaHalfWidth() - pen_thr
                 )
            {
                if ( Body_Intercept( false ).execute( agent ) )
                {
                    dlog.addText( Logger::TEAM,
                                  __FILE__": execute normal interception" );
                    agent->debugClient().addMessage( "Intercept(1)" );
                    agent->setNeckAction( new Neck_TurnToBall() );
                    return true;
                }
            }

            dlog.addText( Logger::TEAM,
                          __FILE__": execute. ball vel has same slope to my body??"
                          " myvel-ang=%f body=%f. go to ball direct",
                          wm.ball().vel().th().degree(),
                          wm.self().body().degree() );
            // ball vel angle is same to my body angle
            agent->debugClient().addMessage( "GoToCatch(1)" );
            doGoToCatchPoint( agent, wm.ball().pos() );
            return true;
        }
    }

    //----------------------------------------------------------
    // body is already face to intersection
    // only dash to intersection

    // check catch point
    if ( intersection.absX() > SP.pitchHalfLength() + SP.catchableArea()
         || intersection.x > SP.ourPenaltyAreaLineX() - SP.catchableArea()
         || intersection.absY() > SP.penaltyAreaHalfWidth() - SP.catchableArea()
         )
    {
        dlog.addText( Logger::TEAM,
                      __FILE__": execute intersection(%.2f, %.2f) over range.",
                      intersection.x, intersection.y );
        if ( Body_Intercept( false ).execute( agent ) )
        {
            agent->debugClient().addMessage( "Intercept(2)" );
            agent->setNeckAction( new Neck_TurnToBall() );
            return true;
        }
        else
        {
            return Bhv_GoalieBasicMove().execute( agent );
        }
    }

    //----------------------------------------------------------
    // check already there
    const Vector2D my_inertia_final_pos
        = wm.self().pos()
        + wm.self().vel()
        / (1.0 - wm.self().playerType().playerDecay());
    double dist_thr = 0.2 + wm.ball().distFromSelf() * 0.1;
    if ( dist_thr < 0.5 ) dist_thr = 0.5;

    // if already intersection point stop dash
    if ( my_inertia_final_pos.dist( intersection ) < dist_thr )
    {
        agent->debugClient().addMessage( "StopForChase" );
        Body_StopDash( false ).execute( agent );
        agent->setNeckAction( new Neck_TurnToBall() );
        return true;
    }

    //----------------------------------------------------------
    // forward or backward

    dlog.addText( Logger::TEAM,
                  __FILE__": slide move. point=(%.1f, %.1f)",
                  intersection.x, intersection.y );
    if ( wm.ball().pos().x > -35.0 )
    {
        if ( wm.ball().pos().y * intersection.y < 0.0 ) // opposite side
        {
            intersection.y = 0.0;
        }
        else
        {
            intersection.y *= 0.5;
        }
    }

    agent->debugClient().addMessage( "GoToCatch(2)" );
    doGoToCatchPoint( agent, intersection );
    return true;
}