📄 strategy.cpp
字号:
/*
Copyright (C) 2001 Tsinghuaeolus
Authors : ChenJiang, YaoJinyi, CaiYunpeng, Lishi
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
If you make any changes or have any comments we would appreciate a
message to yjy01@mails.tsinghua.edu.cn.
*/
#include "stdafx.h"
#include "global.h"
#include "strategy.h"
/********************* Situation *************************/
/************** Keep record of situation *******************************/
Situation::Situation():MyScore(0),TheirScore(0),CurrentTime(-1),playmode(PM_No_Mode),
LastInterruptTime(-1),InterruptsThisCycle(0),ClockStopped(false),ModeChangedTime(-1),
Sense_Interval(0){
mode_changed = false;
num_hearmodes = 0;
}
Time Situation::LastCycle(){
return (!ClockStopped || situation.ClockStoppedTime == 0) ?
situation.CurrentTime - 1 : situation.CurrentTime;
}
void Situation::HearMode(PlayMode playmode){
if(num_hearmodes >= CP_max_hearmodes){
num_hearmodes = 0;
}
heardmode[num_hearmodes ++] = playmode;
mode_changed = true;
}
void Situation::UpdateMode(){
if(mode_changed){
DoLog(LOG_UPDATE, "mode changed");
for(int i = 0; i < num_hearmodes; i++){
SetPlayMode(heardmode[i]);
}
num_hearmodes = 0;
mode_changed = false;
}
}
void Situation::SetPlayMode(PlayMode playmode){
this->playmode = playmode;
OnChangeMode(playmode);
}
void Situation::ForgetAll(){
for(int i=1; i<= SP_team_size; i++){
MyPlayer(i).Setvalid(false);
MyPlayer(i).pos_conf = 0;
TheirPlayer(i).Setvalid(false);
TheirPlayer(i).pos_conf = 0;
}
}
void Situation::OnChangeMode(PlayMode playmode){
ModeChangedTime = CurrentTime;
if( ClockStopped){
ClockStopped = false;
}
if(playmode != PM_Play_On)
ForgetAll();
switch (playmode){
case PM_Before_Kick_Off :
case PM_My_Offside_Kick :
IsGoalieKick = false;
PlaceKickState=SPST_Initialize;
DoLog(LOG_SETPLAY,"initialized");
ClockStopped = true;
ClockStoppedTime = 0;
break;
case PM_Play_On:
break;
case PM_My_Goalie_Free_Kick:
IsGoalieKick = true;
fm.goalieplacekick.movecount=SP_goalie_max_moves;
break;
case PM_My_Goal_Kick :
IsGoalieKick = true;
case PM_My_Kick_Off :
case PM_My_Corner_Kick :
case PM_My_Kick_In :
case PM_My_Free_Kick :
DoLog(LOG_SETPLAY,"Mode Changed");
PlaceKickState=SPST_Initialize;
break;
case PM_Their_Offside_Kick :
ClockStopped = true;
ClockStoppedTime = 0;
break;
case PM_Drop_Ball :
DoLog(LOG_SETPLAY,"Drop Ball");
PlaceKickState=SPST_AfterExec;
ball.forget();
situation.IsGoalieKick = false;
break;
default:
break;
}
}
void Situation::LogGameState(){
switch (PlaceKickState){
case SPST_Initialize:
DoLog(18,"Initialization");
break;
case SPST_Prego:
DoLog(18,"PreExecute Going");
break;
case SPST_ExecWait:
DoLog(18,"Waiting For Execute");
break;
case SPST_Executing:
DoLog(18,"Executing");
break;
case SPST_AfterExec:
DoLog(18,"Play Mode");
break;
default:
DoLog(18,"UnExpected");
break;
}
if (IsGoalieKick)
DoLog(18,"Is Goalie Kick");
}
GameState Situation::JudgeGameState(){
float CP_playon_ball_speed_min = 0.3f;
if (situation.IsPlaceKick()&& (playmode==PM_Play_On||playmode==PM_My_Goal_Kick&&PlaceKickState > SPST_Prego)
&&(situation.BallFree||ball.pos_valid() && motion.Num_TheirVisiblePlayers()>0&&motion.TheirPlayer_Close2Ball(0).pos.dist(ball.pos)<7))
{
DoLog(18,"Change To Playing");
situation.ChangeSetPlay(SPST_AfterExec);
situation.IsGoalieKick = false;
}
switch (playmode)
{
case PM_Before_Kick_Off :
gamestate = GS_Before_Kick_Off;
break;
case PM_Their_Kick_Off :
case PM_Their_Kick_In :
case PM_Their_Corner_Kick :
case PM_Their_Goal_Kick :
case PM_Their_Free_Kick :
DoLog(18,"Their kick");
PlaceKickState = SPST_AfterExec;
IsGoalieKick = false;
gamestate = GS_Their_PlaceKick;
break;
case PM_My_Kick_Off :
case PM_My_Kick_In :
case PM_My_Corner_Kick :
case PM_My_Goal_Kick :
case PM_My_Free_Kick :
if (IsPlaceKick())
gamestate = GS_My_PlaceKick;
else
gamestate = GS_Playing;
break;
case PM_Play_On :
if (!situation.IsGoalieKick)
{
situation.ChangeSetPlay(SPST_AfterExec);
gamestate = GS_Playing;
}
break;
case PM_Half_Time :
case PM_Time_Up :
case PM_Extended_Time :
case PM_My_Offside_Kick :
case PM_Their_Offside_Kick :
default :
gamestate = GS_Other;
break;
}
situation.LogGameState();
return gamestate;
}
void Situation::UpdateScore(char Side){
if(Side == MySide)
MyScore++;
else
TheirScore++;
}
void Situation::SetKickOffMode(KickOff_Mode kickoff_mode){
this->kickoff_mode = kickoff_mode;
}
void Situation::UpdateTime(Time time){
CurrentTime = time;
}
void Situation::JudgeSituation(){
int num, i;
motion.SetArounds();
//Judge about control of the ball
num_my_ballcontrollers = 0;
num_their_ballcontrollers = 0;
if(ball.distance < 30.0f || ball.pos_conf > 0.9f){
num = motion.Num_MyVisiblePlayers();
for(i = 0; i < num; i ++){
if (motion.MyPlayer_Close2Ball(i).balldist > 4.0f){
//to far to be the controller of ball
break;
}
if (motion.MyPlayer_Close2Ball(i).Iscontrolball){
My_Ballcontrollers[num_my_ballcontrollers++] = motion.MyPlayers_Close2Ball[i];
}
}
num = motion.Num_TheirVisiblePlayers();
for(i =0; i < num; i ++){
if (motion.TheirPlayer_Close2Ball(i).balldist > 4.0f){
//to far to be the controller of ball
break;
}
if (motion.TheirPlayer_Close2Ball(i).Iscontrolball){
Their_Ballcontrollers[num_their_ballcontrollers++] = motion.TheirPlayers_Close2Ball[i];
}
}
DoLog(LOG_SEE, "judge 1");
}
num_ballcontrollers = num_my_ballcontrollers + num_their_ballcontrollers;
//for the sake of compatibility
if (num_their_ballcontrollers > 0){
ballcontroller = Their_Ballcontrollers[0];
if (ballcontroller <= SP_team_size)
ballcontroller += SP_team_size;
}
else if (num_my_ballcontrollers > 0){
ballcontroller = My_Ballcontrollers[0];
}
else if (ball.kickable()){
ballcontroller = MyNumber;
}
else{
ballcontroller = -1;
}
BallFree = bool(ballcontroller == -1);
//TeamControl
conf_of_control = ball.pos_conf;
if(!BallFree){
if (num_their_ballcontrollers > 0){
if (num_my_ballcontrollers > 0 || ball.kickable()){
Team_Control = 0.5f;
}
else{
Team_Control = 0.0f;
}
}
else{
Team_Control = 1.0f;
}
}
else{
DoLog(LOG_SEE, "judge 2");
motion.SetInterceptionInfo();
}
if (Self.attackness > 0.5f)
IsAttack = bool(Team_Control >= 0.5f);
else
IsAttack = bool(Team_Control >= 0.6f);
if(!BallFree){
DoLog(LOG_SITUATION, "Ball is controlled by %d", ballcontroller);
}
else{
DoLog(LOG_SITUATION, "most promising contoller is %d at (%.2f %.2f)", most_promising_controller, GetPlayer(situation.most_promising_controller).pos.x,
GetPlayer(situation.most_promising_controller).pos.y);
}
}
bool Situation::Ballwithincontrol(char side, UNum No){
if (ball.pos_conf < 0.85 || GetPlayer(side, No).pos_conf < 0.8) return false;
return bool(GetPlayer(side, No).balldist < CP_control_margin);
}
bool Situation::IsControllerOrFutureController(char side, UNum No){
if (side == TheirSide && No > 0 && No <= SP_team_size){
return IsControllerOrFutureController(No + SP_team_size);
}
return IsControllerOrFutureController(No);
}
bool Situation::IsControllerOrFutureController(UNum No){
return (No == ballcontroller || No == most_promising_controller) && No > 0;
}
Vector Situation::NextControlBallPos(){
return (!BallFree || ball.speed_conf < 0.8f || !IsValidNo(most_promising_controller)) ? ball.pos : next_interception_point;
}
/*************** Role ******************/
Role::Role(float attackness, float leftness, float aggressiveness, float creative){
SetRole(attackness, leftness, aggressiveness, creative);
}
void Role::SetRole(float attackness, float leftness, float aggressiveness, float creative){
this->attackness = attackness;
this->leftness = leftness;
this->aggressiveness = aggressiveness;
this->creativeness = creativeness;
}
bool Role::RoleMatched(Role& role){
return bool(attackness == role.attackness && leftness == role.leftness);
}
/***************** Set Play ****************************/
void Set_Play::AddRole(float attackness, float leftness, const Vector& pos){
roles[total_roles].attackness = attackness;
roles[total_roles].leftness = leftness;
roles[total_roles].strategical_pos = pos;
total_roles ++;
}
void Set_Play::AddRole(UNum No, const Vector& pos){
roles[total_roles].No = No;
roles[total_roles].strategical_pos = pos;
total_roles ++;
}
bool Set_Play::IsRole(UNum No){
for(int i = 0; i< total_roles; i++){
if(No == roles[i].No) return true;
}
return false;
}
bool Set_Play::IsExecutor(UNum No){
return bool(No == Executor);
}
Vector Set_Play::GetSetPlayPos(UNum No){
for(int i = 0; i< total_roles; i++){
if (No == roles[i].No){
return roles[i].strategical_pos;
}
}
return Vector(-1, -1);
}
Vector Set_Play::GetMySetPlayPos(){
return GetSetPlayPos(CP_Number);
}
bool Set_Play::RecentSeen(){
return bool(situation.SightTime>situation.CurrentTime-2);
}
/******************** Before Kick Off **********************/
void BeforeKickOff::set_roles(){
total_roles=0;
Counter =0;
AddRole(1, Vector(-47.0f,0.0f));
AddRole(3, Vector(-25.0f,-12.0f));
AddRole(5, Vector(-25.0f,12.0f));
AddRole(2, Vector(-20.0f,20.0f));
AddRole(4, Vector(-20.0f,-20.0f));
AddRole(7, Vector( -5.0f,8.0f));
AddRole(8, Vector( -5.0f,-8.0f));
if (situation.kickoff_mode == KickOff_Mine)
{
AddRole(6, Vector(-15.0f,0.0f));
AddRole(10, Vector(-0.5f, 0.0f));
AddRole(9, Vector(-0.1f,18.0f));
AddRole(11,Vector(-0.1f,-18.0f));
}
else{
AddRole(6,Vector(-15.0f,0.0f));
AddRole(10, Vector(-10.0f, 0.0f));
AddRole(9, Vector(-0.5f,18.0f));
AddRole(11,Vector(-0.5f,-18.0f));
}
situation.ChangeSetPlay(SPST_Prego);
}
void BeforeKickOff ::going(){
if (situation.IsSetPlayState(SPST_Initialize)){
set_roles();
}
Vector initialpos = GetMySetPlayPos();
if (!motion.infield(initialpos))
return;
if (!motion.within_range(initialpos)){
if (fill_pos_move_time >= 8){
action.move(initialpos);
fill_pos_move_time = 0;
}
fill_pos_move_time ++;
}
}
/***************** Formation ***************************/
Formation::Formation(){
}
Vector Formation::GetOffensivePoint(float attackness, float leftness, Vector ballpos){
input[0] = ballpos.x / SP_semi_pitch_length;
input[1] = -fabs(ballpos.y) / SP_semi_pitch_width;
input[2] = attackness;
if (ballpos.y < 0)
input[3] = leftness;
else
input[3] = 1 - leftness;
FMOffenseNet.SimulateNet(&input[0], &output[0]);
if (ballpos.y > 0)
output[1] *=-1;
return Vector(float(SP_semi_pitch_length * output[0]), float(SP_semi_pitch_width * output[1]));
}
Vector Formation::GetDefensivePoint(const Role & role, Vector ballpos){
return GetDefensivePoint(role.attackness, role.leftness, ballpos);
}
Vector Formation::GetDefensivePoint(float attackness, float leftness, Vector ballpos){
Vector fm_defense_point;
pose_limitation(ballpos.x, - SP_semi_pitch_length, SP_semi_pitch_length);
pose_limitation(ballpos.y, - SP_semi_pitch_width, SP_semi_pitch_width);
input[0] = ballpos.x / SP_semi_pitch_length;
input[1] = fabs(ballpos.y) / SP_semi_pitch_width;
input[2] = attackness;
if (ballpos.y < 0)
input[3] = leftness;
else
input[3] = 1 - leftness;
FMDefenseNet.SimulateNet(&input[0], &output[0]);
if (ballpos.y > 0){
fm_defense_point = Vector(SP_semi_pitch_length * float(output[0]), SP_semi_pitch_width * float(output[1]));
}
else{
fm_defense_point = Vector(SP_semi_pitch_length * float(output[0]), -SP_semi_pitch_width * float(output[1]));
}
return fm_defense_point;
}
Vector Formation::GetFormationPoint(const Player& player){
Vector ballpos = situation.NextControlBallPos();
if (situation.IsAttack){
return GetOffensivePoint(player.attackness, player.leftness, ballpos);
}
else{
return GetDefensivePoint(player.attackness, player.leftness, ballpos);
}
}
Vector Formation::GetFormationPoint(){
return GetFormationPoint(Self);
}
float Formation::CalcRelativeDegree(){
float distance = ball.pos.dist(GetFormationPoint());
if (distance < 7.0f)
return 1.0f;
else if (distance < 20.0f)
return 1.0f - 0.5f / 13 * distance;
else
return 0.5f - 0.5f / 10 *distance > 0 ? 0.5f - 0.5f / 10 *distance : 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -