/* --------------------------------------------------------------------- */ 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; }
/*! 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; }