referee.cpp
来自「2009 ROBOCUP 仿真2DSERVER 源码」· C++ 代码 · 共 2,262 行 · 第 1/5 页
CPP
2,262 行
// -*-c++-*-/*************************************************************************** referee.h Refereeing module ------------------- begin : 16-May-2002 copyright : (C) 2001 by The RoboCup Soccer Server Maintenance Group. email : sserver-admin@lists.sourceforge.net***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU LGPL as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any * * later version. * * * ***************************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "referee.h"#include "field.h"#include "player.h"#include "team.h"#include "random.h"#include <limits>#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endifconst char * KeepawayRef::trainingMsg = "training Keepaway 1";const int KeepawayRef::TURNOVER_TIME = 4;PVectorReferee::truncateToPitch( PVector ball_pos ){ ball_pos.x = std::min( ball_pos.x, + ServerParam::PITCH_LENGTH * 0.5 ); ball_pos.x = std::max( ball_pos.x, - ServerParam::PITCH_LENGTH * 0.5 ); ball_pos.y = std::min( ball_pos.y, + ServerParam::PITCH_WIDTH * 0.5 ); ball_pos.y = std::max( ball_pos.y, - ServerParam::PITCH_WIDTH * 0.5 ); return ball_pos;}PVectorReferee::moveOutOfPenalty( const Side side, PVector ball_pos ){ if ( side != RIGHT ) { if ( ball_pos.x <= ( - ServerParam::PITCH_LENGTH * 0.5 + ServerParam::PENALTY_AREA_LENGTH ) && std::fabs( ball_pos.y ) <= ServerParam::PENALTY_AREA_WIDTH * 0.5 ) { ball_pos.x = - ServerParam::PITCH_LENGTH * 0.5 + ServerParam::PENALTY_AREA_LENGTH + EPS; if ( ball_pos.y > 0 ) { ball_pos.y = +ServerParam::PENALTY_AREA_WIDTH * 0.5 + EPS; } else { ball_pos.y = -ServerParam::PENALTY_AREA_WIDTH * 0.5 - EPS; } } } if ( side != LEFT ) { if ( ball_pos.x >= ( ServerParam::PITCH_LENGTH * 0.5 - ServerParam::PENALTY_AREA_LENGTH ) && std::fabs( ball_pos.y ) <= ServerParam::PENALTY_AREA_WIDTH * 0.5 ) { ball_pos.x = ServerParam::PITCH_LENGTH * 0.5 - ServerParam::PENALTY_AREA_LENGTH - EPS; if( ball_pos.y > 0 ) { ball_pos.y = +ServerParam::PENALTY_AREA_WIDTH * 0.5 + EPS; } else { ball_pos.y = -ServerParam::PENALTY_AREA_WIDTH * 0.5 - EPS; } } } return ball_pos;}PVectorReferee::moveIntoPenalty( Side side, PVector pos ){ if ( side != RIGHT ) { if ( pos.x > ( -ServerParam::PITCH_LENGTH * 0.5 + ServerParam::PENALTY_AREA_LENGTH + ServerParam::instance().ballSize() ) ) { pos.x = -ServerParam::PITCH_LENGTH * 0.5 + ServerParam::PENALTY_AREA_LENGTH + ServerParam::instance().ballSize(); } if ( std::fabs( pos.y ) > ( ServerParam::PENALTY_AREA_WIDTH * 0.5 + ServerParam::instance().ballSize() ) ) { if ( pos.y > 0 ) { pos.y = ServerParam::PENALTY_AREA_WIDTH * 0.5 + ServerParam::instance().ballSize(); } else { pos.y = -ServerParam::PENALTY_AREA_WIDTH * 0.5 - ServerParam::instance().ballSize(); } } } if ( side != LEFT ) { if ( pos.x < ( ServerParam::PITCH_LENGTH * 0.5 - ServerParam::PENALTY_AREA_LENGTH - ServerParam::instance().ballSize() ) ) { pos.x = ServerParam::PITCH_LENGTH * 0.5 - ServerParam::PENALTY_AREA_LENGTH - ServerParam::instance().ballSize(); } if ( std::fabs( pos.y ) > ( ServerParam::PENALTY_AREA_WIDTH * 0.5 + ServerParam::instance().ballSize() ) ) { if ( pos.y > 0 ) { pos.y = ServerParam::PENALTY_AREA_WIDTH * 0.5 + ServerParam::instance().ballSize(); } else { pos.y = -ServerParam::PENALTY_AREA_WIDTH * 0.5 - ServerParam::instance().ballSize(); } } } return pos;}voidReferee::awardFreeKick( const Side side, PVector pos ){ pos = truncateToPitch( pos ); pos = moveOutOfPenalty( (Side)(-side), pos ); if( side == LEFT ) { M_stadium.placeBall( PM_FreeKick_Left, LEFT, pos ); } else if( side == RIGHT ) { M_stadium.placeBall( PM_FreeKick_Right, RIGHT, pos ); }}voidReferee::awardGoalKick( const Side side, PVector pos ){ if ( pos.y > 0 ) { pos.y = ServerParam::GOAL_AREA_WIDTH * 0.5; } else { pos.y = -ServerParam::GOAL_AREA_WIDTH * 0.5; } M_stadium.clearBallCatcher(); if ( side == LEFT ) { pos.x = - ServerParam::PITCH_LENGTH * 0.5 + ServerParam::GOAL_AREA_LENGTH; M_stadium.placeBall( PM_GoalKick_Left, LEFT, pos ); } else { pos.x = ServerParam::PITCH_LENGTH * 0.5 - ServerParam::GOAL_AREA_LENGTH; M_stadium.placeBall( PM_GoalKick_Right, RIGHT, pos ); }}voidReferee::awardDropBall( PVector pos ){ M_stadium.clearBallCatcher(); pos = truncateToPitch( pos ); pos = moveOutOfPenalty( NEUTRAL, pos ); M_stadium.placeBall( PM_Drop_Ball, NEUTRAL, pos ); M_stadium.placePlayersInField(); if( ! isPenaltyShootOut( M_stadium.playmode() ) ) { M_stadium.change_play_mode( PM_PlayOn ); }}voidReferee::awardKickIn( const Side side, PVector pos ){ M_stadium.clearBallCatcher(); pos = truncateToPitch( pos ); if ( side == LEFT ) { M_stadium.placeBall( PM_KickIn_Left, LEFT, pos ); } else { M_stadium.placeBall( PM_KickIn_Right, RIGHT, pos ); }}voidReferee::awardCornerKick( const Side side, PVector pos ){ M_stadium.clearBallCatcher(); if ( pos.y > 0 ) { pos.y = ServerParam::PITCH_WIDTH * 0.5 - ServerParam::instance().cornerKickMargin(); } else { pos.y = -ServerParam::PITCH_WIDTH * 0.5 + ServerParam::instance().cornerKickMargin(); } if ( side == LEFT ) { pos.x = ServerParam::PITCH_LENGTH * 0.5 - ServerParam::instance().cornerKickMargin(); M_stadium.placeBall( PM_CornerKick_Left, LEFT, pos ); } else { pos.x = -ServerParam::PITCH_LENGTH * 0.5 + ServerParam::instance().cornerKickMargin(); M_stadium.placeBall( PM_CornerKick_Right, RIGHT, pos ); }}boolReferee::inPenaltyArea( const Side side, const PVector & pos ){ if ( side != RIGHT ) { // according to FIFA the ball is catchable if it is at // least partly within the penalty area, thus we add ball size static RArea pen_area( PVector( - ServerParam::PITCH_LENGTH/2 + ServerParam::PENALTY_AREA_LENGTH/2.0, 0.0 ), PVector( ServerParam::PENALTY_AREA_LENGTH + ServerParam::instance().ballSize() * 2, ServerParam::PENALTY_AREA_WIDTH + ServerParam::instance().ballSize() * 2 ) ) ; if ( pen_area.inArea( pos ) ) { return true; } } if ( side != LEFT ) { // according to FIFA the ball is catchable if it is at // least partly within the penalty area, thus we add ball size static RArea pen_area( PVector( +ServerParam::PITCH_LENGTH/2 - ServerParam::PENALTY_AREA_LENGTH/2.0, 0.0 ), PVector( ServerParam::PENALTY_AREA_LENGTH + ServerParam::instance().ballSize() * 2, ServerParam::PENALTY_AREA_WIDTH + ServerParam::instance().ballSize() * 2 ) ) ; if ( pen_area.inArea( pos ) ) { return true; } } return false;}boolReferee::isPenaltyShootOut( const PlayMode pm, const Side side ){ bool bLeft = false, bRight = true; switch( pm ) { case PM_PenaltySetup_Left: case PM_PenaltyReady_Left: case PM_PenaltyTaken_Left: case PM_PenaltyMiss_Left: case PM_PenaltyScore_Left: bLeft = true; break; case PM_PenaltySetup_Right: case PM_PenaltyReady_Right: case PM_PenaltyTaken_Right: case PM_PenaltyMiss_Right: case PM_PenaltyScore_Right: bRight = true; break; default: return false; } if ( side == NEUTRAL && ( bLeft == true || bRight == true ) ) { return true; } else if ( side == LEFT && bLeft == true ) { return true; } else if ( side == RIGHT && bRight == true ) { return true; } else { return false; }}boolReferee::crossGoalLine( const Side side, const PVector & prev_ball_pos ){ if ( prev_ball_pos.x == M_stadium.ball().pos().x ) { // ball cannot have crossed gline // std::cout << time << ": vertcal movement\n"; return false; } if ( std::fabs( M_stadium.ball().pos().x ) <= ServerParam::PITCH_LENGTH*0.5 + ServerParam::instance().ballSize() ) { // ball hasn't crossed gline // std::cout << time << ": hasn't crossed\n"; return false; } if ( std::fabs( prev_ball_pos.x ) > ServerParam::PITCH_LENGTH*0.5 + ServerParam::instance().ballSize() ) { // ball already over the gline // std::cout << time << ": already crossed\n"; return false; } if ( ( side * M_stadium.ball().pos().x ) >= 0 ) { //ball in wrong half // std::cout << time << ": wrong_half\n"; return false; } if ( std::fabs( prev_ball_pos.y ) > ( ServerParam::instance().goalWidth()*0.5 + ServerParam::instance().goalPostRadius() ) && std::fabs( prev_ball_pos.x ) > ServerParam::PITCH_LENGTH*0.5 ) { // then the only goal that could have been scored would be // from going behind the goal post. I'm pretty sure that // isn't possible anyway, but just in case this function acts // as a double check // std::cout << time << ": behind_half\n"; return false; } double delta_x = M_stadium.ball().pos().x - prev_ball_pos.x; double delta_y = M_stadium.ball().pos().y - prev_ball_pos.y; // we already checked above that ball->pos.x != prev_ball_pos.x, so delta_x cannot be zero. double gradient = delta_y / delta_x; double offset = prev_ball_pos.y - gradient * prev_ball_pos.x; // determine y for x = ServerParam::PITCH_LENGTH*0.5 + ServerParam::instance().ballSize() * -side double x = ( ServerParam::PITCH_LENGTH*0.5 + ServerParam::instance().ballSize() ) * -side; double y_intercept = gradient * x + offset; // std::cout << time << ": prev = " << prev_ball_pos << std::endl; // std::cout << time << ": curr = " << ball->pos << std::endl; // std::cout << time << ": delta_x = " << delta_x << std::endl; // std::cout << time << ": delta_y = " << delta_y << std::endl; // std::cout << time << ": grad = " << gradient << std::endl; // std::cout << time << ": off = " << offset << std::endl; // std::cout << time << ": x = " << x << std::endl; // std::cout << time << ": y_inter = " << y_intercept << std::endl; return std::fabs( y_intercept ) <= ( ServerParam::instance().goalWidth()*0.5 + ServerParam::instance().goalPostRadius() );}//**********// TimeRef//**********voidTimeRef::analyse(){ static int s_half_time_count = 0; const PlayMode pm = M_stadium.playmode(); if ( pm == PM_BeforeKickOff || pm == PM_TimeOver || pm == PM_AfterGoal_Right || pm == PM_AfterGoal_Left
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?