player.cpp
来自「2009 ROBOCUP 仿真2DSERVER 源码」· C++ 代码 · 共 2,189 行 · 第 1/5 页
CPP
2,189 行
// : NormalizeDashPower( power ) );// if ( power_need > stamina() + M_player_type->extraStamina() )// {// power_need = stamina() + M_player_type->extraStamina();// }// M_stamina -= power_need;// if ( stamina() < 0.0 )// {// M_stamina = 0.0;// }// if ( M_stadium.playmode() != PM_BeforeKickOff// && M_stadium.playmode() != PM_TimeOver )// {// M_consumed_stamina += power_need;// }// power = ( power < 0.0// ? power_need / -2.0// : power_need );// double effective_dash_power// = effort()// * power// * M_player_type->dashPowerRate();// if ( pos().y < 0.0 )// {// effective_dash_power /= ( side() == LEFT// ? ServerParam::instance().slownessOnTopForLeft()// : ServerParam::instance().slownessOnTopForRight() );// }// push( PVector::fromPolar( effective_dash_power,// angleBodyCommitted() ) );// ++M_dash_count;// M_command_done = true;// }}voidPlayer::dash( double power, double dir ){ if ( ! M_command_done ) { const ServerParam & param = ServerParam::instance(); power = NormalizeDashPower( power ); dir = NormalizeDashAngle( dir ); bool back_dash = power < 0.0; double dir_rate = ( std::fabs( dir ) > 90.0 ? param.backDashRate() - ( ( param.backDashRate() - param.sideDashRate() ) * ( 1.0 - ( std::fabs( dir ) - 90.0 ) / 90.0 ) ) : param.sideDashRate() + ( ( 1.0 - param.sideDashRate() ) * ( 1.0 - std::fabs( dir ) / 90.0 ) ) ); double power_need = ( back_dash ? power * -2.0 : power ); power_need = std::min( power_need, stamina() + M_player_type->extraStamina() ); M_stamina = std::max( 0.0, stamina() - power_need ); power = ( back_dash ? power_need / -2.0 : power_need ); double effective_dash_power = std::fabs( effort() * power * dir_rate * M_player_type->dashPowerRate() ); if ( pos().y < 0.0 ) { effective_dash_power /= ( side() == LEFT ? param.slownessOnTopForLeft() : param.slownessOnTopForRight() ); } double actual_dir = dir; if ( param.dashAngleStep() < EPS ) { // players can dash in any direction. } else { // The dash direction is discretized by server::dash_angle_step actual_dir = param.dashAngleStep() * rint( actual_dir / param.dashAngleStep() ); } if ( back_dash ) { actual_dir += 180.0; } push( PVector::fromPolar( effective_dash_power, normalize_angle( angleBodyCommitted() + Deg2Rad( actual_dir ) ) ) ); ++M_dash_count; M_command_done = true; }}voidPlayer::turn( double moment ){ if ( ! M_command_done ) { M_angle_body = normalize_angle( angleBodyCommitted() + ( 1.0 + drand( -M_randp, M_randp ) ) * NormalizeMoment( moment ) / ( 1.0 + M_inertia_moment * vel().r() ) ); ++M_turn_count; M_command_done = true; }}voidPlayer::turn_neck( double moment ){ if ( ! M_turn_neck_done ) { M_angle_neck = NormalizeNeckAngle( angleNeckCommitted() + NormalizeNeckMoment( moment ) ); ++M_turn_neck_count; M_turn_neck_done = true; }}voidPlayer::kick( double power, double dir ){ if ( ! M_command_done ) { M_command_done = true; M_kick_cycles = 1; power = NormalizeKickPower( power ); dir = NormalizeMoment( dir ); PVector tmp; double dir_diff; double dist_ball; M_state |= KICK; if ( M_stadium.playmode() == PM_BeforeKickOff || M_stadium.playmode() == PM_AfterGoal_Left || M_stadium.playmode() == PM_AfterGoal_Right || M_stadium.playmode() == PM_OffSide_Left || M_stadium.playmode() == PM_OffSide_Right || M_stadium.playmode() == PM_Back_Pass_Left || M_stadium.playmode() == PM_Back_Pass_Right || M_stadium.playmode() == PM_Free_Kick_Fault_Left || M_stadium.playmode() == PM_Free_Kick_Fault_Right || M_stadium.playmode() == PM_CatchFault_Left || M_stadium.playmode() == PM_CatchFault_Right || M_stadium.playmode() == PM_TimeOver ) { M_state |= KICK_FAULT; return; } if ( pos().distance( M_stadium.ball().pos() ) > ( M_player_type->playerSize() + M_stadium.ball().size() + M_player_type->kickableMargin()) ) { M_state |= KICK_FAULT; return; } dir_diff = std::fabs( angleFromBody( M_stadium.ball() ) ); tmp = M_stadium.ball().pos() - this->pos(); dist_ball = ( tmp.r() - M_player_type->playerSize() - ServerParam::instance().ballSize() ); double eff_power = power * ServerParam::instance().kickPowerRate() * (1.0 - 0.25*dir_diff/M_PI - 0.25*dist_ball/M_player_type->kickableMargin()); PVector accel = PVector::fromPolar( eff_power, dir + angleBodyCommitted() );// // pfr 8/14/00: for RC2000 evaluation// // add noise to kick// {// double maxrnd = M_kick_rand * power / ServerParam::instance().maxPower();// PVector kick_noise( drand( -maxrnd, maxrnd ),// drand( -maxrnd, maxrnd ) );// //std::cout << "Kick noise (" << power << "): " << kick_noise << std::endl;// accel += kick_noise;// } // akiyama 2008-01-30 // new kick noise // noise = kick_rand // * power/max_power // * ( ( 0.5 + 0.25*( dist_rate + dir_rate ) ) // + ( 0.5 + 0.5*ball_speed/(ball_speed_max*ball_decay) ) ) // [0.5, 1.0] double pos_rate = 0.5 + 0.25 * ( dir_diff/M_PI + dist_ball/M_player_type->kickableMargin() ); // [0.5, 1.0] double speed_rate = 0.5 + 0.5 * ( M_stadium.ball().vel().r() / ( ServerParam::instance().ballSpeedMax() * ServerParam::instance().ballDecay() ) ); // [0, 2*kick_rand] double max_rand = M_kick_rand * ( power / ServerParam::instance().maxPower() ) * ( pos_rate + speed_rate ); PVector kick_noise = PVector::fromPolar( drand( 0.0, max_rand ), drand( -M_PI, M_PI ) ); accel += kick_noise; // std::cout << M_stadium.time() // << " Kick " // << M_kick_rand // << " " << power // << " " << pos_rate // << " " << speed_rate // << " " << kick_noise // << " " << kick_noise.r() // << " " << max_rand // << std::endl; M_stadium.kickTaken( *this, accel ); ++M_kick_count; }}voidPlayer::goalieCatch( double dir ){ if ( ! M_command_done ) { M_command_done = true; M_state |= CATCH; //pfr: we should only be able to catch in PlayOn mode //tom: actually the goalie can catch the ball in any playmode, but //infringements should be awarded. Maybe later. if ( ! this->isGoalie() || M_goalie_catch_ban > 0 || ( M_stadium.playmode() != PM_PlayOn && ! Referee::isPenaltyShootOut( M_stadium.playmode() ) ) ) /* M_stadium.playmode() == PM_BeforeKickOff || M_stadium.playmode() == PM_AfterGoal_Left || M_stadium.playmode() == PM_AfterGoal_Right || M_stadium.playmode() == PM_OffSide_Left || M_stadium.playmode() == PM_OffSide_Right || M_stadium.playmode() == PM_Back_Pass_Left || M_stadium.playmode() == PM_Back_Pass_Right || M_stadium.playmode() == PM_Free_Kick_Fault_Left || M_stadium.playmode() == PM_Free_Kick_Fault_Right ) */ { M_state |= CATCH_FAULT; return; } // Tom: Catches can now occur an any position, but the ref will award and infringement if the ball is outside of the penalty area // static RArea p_l( PVector( -PITCH_LENGTH/2+PENALTY_AREA_LENGTH/2.0, 0.0 ), // PVector( PENALTY_AREA_LENGTH, PENALTY_AREA_WIDTH )) ; // static RArea p_r( PVector( +PITCH_LENGTH/2-PENALTY_AREA_LENGTH/2.0, 0.0 ), // PVector( PENALTY_AREA_LENGTH, PENALTY_AREA_WIDTH ) ) ; // switch (this->team->side) // { // case LEFT: // if ( !(p_l.inArea(this->pos)) ){ // alive |= CATCH_FAULT; // return; // } // break; // case RIGHT: // if ( !(p_r.inArea(this->pos)) ){ // alive |= CATCH_FAULT; // return; // } // break ; // }#if 0 RArea catchable( PVector( ServerParam::instance().catchAreaLength()*0.5, 0.0 ), PVector( ServerParam::instance().catchAreaLength(), ServerParam::instance().catchAreaWidth() ) ); PVector rotated_pos = M_stadium.ball().pos() - this->pos(); rotated_pos.rotate( -( angleBodyCommitted() + NormalizeMoment( dir ) ) ); if ( ! catchable.inArea( rotated_pos ) || drand( 0, 1 ) >= ServerParam::instance().catchProb() ) { M_state |= CATCH_FAULT; return; } M_goalie_catch_ban = ServerParam::instance().catchBanCycle(); { PVector new_pos = M_stadium.ball().pos() - this->pos(); double mag = new_pos.r(); // I would much prefer to cache the message of the catch command // to the end of the cycle and then do all the movements and // playmode changes there, but I feel that would be too much of a // depature from the current behaviour. mag -= ServerParam::instance().ballSize() + M_player_type->playerSize(); new_pos.normalize( mag ); M_pos += new_pos; M_angle_body = new_pos.th(); M_vel = PVector(); } M_goalie_moves_since_catch = 0; // reset the number of times the goalie moved M_stadium.ballCaught( *this );#else // 2008-02-08 akiyama // TEST version catch model based on the Sebastian Marian's proposal // 2008-02-18 akiyama: catch_area_l variables should be used for gcc-3.3.6 const double catch_area_l = ServerParam::instance().catchAreaLength(); const double reliable_catch_area_l = ServerParam::instance().reliableCatchAreaLength(); const RArea catch_area( PVector( catch_area_l * 0.5, 0.0 ), PVector( catch_area_l, ServerParam::instance().catchAreaWidth() ) ); const RArea reliable_catch_area( PVector( reliable_catch_area_l * 0.5, 0.0 ), PVector( reliable_catch_area_l, ServerParam::instance().catchAreaWidth() ) ); PVector rotated_pos = M_stadium.ball().pos() - this->pos(); rotated_pos.rotate( -( angleBodyCommitted() + NormalizeMoment( dir ) ) ); if ( ! catch_area.inArea( rotated_pos ) || drand( 0, 1 ) >= ServerParam::instance().catchProb() ) { M_state |= CATCH_FAULT; return; } M_goalie_catch_ban = ServerParam::instance().catchBanCycle(); bool success = true; if ( ! reliable_catch_area.inArea( rotated_pos ) ) { double diagonal = std::sqrt( std::pow( catch_area_l, 2.0 ) + std::pow( ServerParam::instance().catchAreaWidth()*0.5, 2.0 ) ); double reliable_diagonal = std::sqrt( std::pow( reliable_catch_area_l, 2.0 ) + std::pow( ServerParam::instance().catchAreaWidth()*0.5, 2.0 ) ); double ball_dist = rotated_pos.r(); const double alpha = 0.75; double max_fail_prob = 1.0 - ServerParam::instance().minCatchProbability(); double speed_rate = max_fail_prob * alpha *( M_stadium.ball().vel().r() / ( ServerParam::instance().ballSpeedMax() * ServerParam::instance().ballDecay() ) ); double dist_rate = max_fail_prob * ( 1.0 - alpha ) * ( ( ball_dist - reliable_diagonal ) / ( diagonal - reliable_diagonal ) ); double fail_prob = rcss::bound( 0.0, speed_rate + dist_rate, 1.0 );// std::cerr << M_stadium.time() << ": Unreliable catch"// << " speed_rate=" << speed_rate// << " dist_rate=" << dist_rate// << " fail_prob=" << fail_prob << std::endl; boost::bernoulli_distribution<> rng( fail_prob ); boost::variate_generator< rcss::random::DefaultRNG &, boost::bernoulli_distribution<> > dst( rcss::random::DefaultRNG::instance(), rng ); if ( dst() ) { success = false; } } if ( success ) { PVector new_pos = M_stadium.ball().pos() - this->pos(); double mag = new_pos.r(); // I would much prefer to cache the message of the catch command // to the end of the cycle and then do all the movements and // playmode changes there, but I feel that would be too much of a // depature from the current behaviour. mag -= ServerParam::instance().ballSize() + M_player_type->playerSize(); new_pos.normalize( mag ); M_pos += new_pos; M_angle_body = new_pos.th(); M_vel = PVector(); M_goalie_moves_since_catch = 0; // reset the number of times the goalie moved M_stadium.ballCaught( *this ); }#endif ++M_catch_count; }}voidPlayer::say( std::string message ){ if ( message.length() > ServerParam::instance().sayMsgSize() ) { return; } M_stadium.sendPlayerAudio( *this, message.c_str() ); ++M_say_count;}voidPlayer::sense_body(){ M_body_observer->sendBody();}voidPlayer::score(){ M_init_observer->sendScore();}void
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?