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 + -
显示快捷键?