📄 sensory.cpp
字号:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "client.h"
#include "sensory.h"
#include "stopwatch.h"
#include "utils.h"
#include "worldmodel.h"
#include "perceptron.h"
#include "skill.h"
#include "log.h"
#include "agent.h"
#include "netif.h"
using namespace World;
/***************************** Sensory *******************************/
void Sensory::Initialize(){
latestsenseinfo = 0;
LastSightTime = -1;
LastSenseTime = -1;
PrevSenseTime = -1;
LastSoundTime = -1;
LastClosestMarker = No_Marker;
dir_time = -1;
int i;
for(i = 0; i < ClientParam::num_divisions; i ++){
FieldInfo.dir_conf[i] = 0.0f;
}
desire_viewidth = VW_Normal;
desire_quality = VQ_High;
}
void Sensory::StopClock(bool value){
situation.ClockStopped = value;
/* Stop log when colck is stopped and restore when open */
Log::rec.PauseLog(value);
Log::recmsg.PauseLog(value);
}
/***************************** Parse **********************************/
/* This Parse Module is transgrafted from CMU99 publication code. We owe special
thanks to CMU's great effort */
void Sensory::Parse(char *SensoryInfo)
{
SenseType sense_type;
Time time;
PrevInterruptTime = LatestTime;
switch ( SensoryInfo[3] ){
case 'e': sense_type = See_Msg; break; /* see */
case 'n': sense_type = Sense_Msg; break; /* sense */
case 'r':
switch(SensoryInfo[1]){
case 's': sense_type = SP_Msg; break; /* server params */
default: sense_type = No_Msg; /* maybe (error,warning...) */
}
break;
case 'a': /* hear, player params or player types */
switch( SensoryInfo[1]){
case 'c': sense_type = CPT_Msg; break; /*change player type */
case 'h': sense_type = Hear_Msg; break; /* hear */
case 'p': /* player params or player types */
switch(SensoryInfo[8]){
case 'p': sense_type = PP_Msg; break; /* palyer params */
case 't': sense_type = PT_Msg; break; /* player types */
default : sense_type = No_Msg;
}
break;
default: sense_type = No_Msg;
}
break;
case 'o':
sense_type = SC_Msg;
break;
case 'l':
sense_type = FI_Msg;
break;
default: sense_type = No_Msg;
}
switch ( sense_type ){
/* sense */
case Sense_Msg:
// extract time info
time = get_int(&SensoryInfo);
if(LatestTime == time){
StopClock(true);
}else if(situation.ClockStopped){
StopClock(false);
}
LatestTime = time;
stopwatch.IdentifyCachetime(SW_CycleStart, time);//when the cycle starts
Parse_Sense(time, SensoryInfo);
LastSenseTime = time;
NewSenseInfo = true;
break;
/* see */
case See_Msg:
#ifdef _Up_FState
return;
#endif
stopwatch.IdentifyCachetime(SW_Recv_Visualinfo, LatestTime);
Make_ViewModeDecision();
// extract time info
time = get_int(&SensoryInfo);
PrevSightTime = LastSightTime;
LastSightTime = time;
/* Don't parse a second sight from the a cycle prior to the latest one*/
if (time <= PrevSightTime) break;/*&& !situation.ClockStopped*///abort sight info when clock stopped
Parse_Sight(time, SensoryInfo);
if(TwiceSight) Reset();//too much may result int out of array limit
if(NewSight) TwiceSight = true;
else NewSight = true;
break;
case FI_Msg:
time = get_int(&SensoryInfo);
PrevSightTime = LastSightTime;
LastSightTime = time;
Parse_Fullstate(time, SensoryInfo);
stopwatch.IdentifyCachetime(SW_Recv_Fullstateinfo, sensory.LatestTime);
break;
/* hear */
case Hear_Msg:
// extract time info
time = get_int(&SensoryInfo);
nonempty_msg = false;
Parse_Sound(time, SensoryInfo);
LastSoundTime = time;
NewSound = true;
break;
case SP_Msg:
Parse_ServerParams(SensoryInfo + 13);
break;
case PP_Msg:
Parse_PlayerParams(SensoryInfo +13);
break;
case PT_Msg:
Parse_PlayerTypes(SensoryInfo + 12);
break;
case CPT_Msg:
//Format "change_player_type 3 1"
Parse_PlayerTypeChange(SensoryInfo + 20);
break;
case SC_Msg://scorez
break;
}
LastSenseType = sense_type;
}
void Sensory::Parse_Sense(Time time, char *SenseInfo)
{
get_word(&SenseInfo);
SenseInfo += 10; /* "view_mode " */
switch ( SenseInfo[0] )
{
case 'h': ViewQuality = VQ_High; break; /* high */
case 'l': ViewQuality = VQ_Low; break; /* low */
default: my_error("Unknown view quality");
}
LastViewWidth = ViewWidth;
get_next_word(&SenseInfo);
switch ( SenseInfo[1] )
{
case 'o': ViewWidth = VW_Normal; break; /* normal */
case 'a': ViewWidth = VW_Narrow; break; /* narrow */
case 'i': ViewWidth = VW_Wide; break; /* wide */
default: my_error("Unknown view quality");
}
float stamina = get_float(&SenseInfo); /* stamina */
float effort = get_float(&SenseInfo); /* effort */
float speed = get_float(&SenseInfo); /* speed */
float rel_spd_angle = get_float(&SenseInfo); /* rel_spd_angle */
float head_angle = get_float(&SenseInfo); /* head angle */
int kicks = get_int(&SenseInfo); /* kicks */
int dashes = get_int(&SenseInfo); /* dashes */
int turns = get_int(&SenseInfo); /* turns */
int says = get_int(&SenseInfo); /* says */
int turn_necks = get_int(&SenseInfo); /* turn_necks */
int catchs = get_int(&SenseInfo);
int moves = get_int(&SenseInfo);
int chang_view = get_int(&SenseInfo);
SetMySensedInfo(ViewWidth, ViewQuality,stamina,effort,speed,rel_spd_angle,head_angle,kicks,dashes,turns,says,turn_necks,time);
if (ServerParam::version >=8.0f){
if ( LastSenseTime == time && !situation.ClockStopped) return;
int ArmMoveable = get_int(&SenseInfo);
int ArmExpires = get_int(&SenseInfo);
Vector ArmTarget(get_float(&SenseInfo),get_float(&SenseInfo));
int Arms = get_int(&SenseInfo);
int Focus = -1;
SenseInfo +=18;
char side;
switch(*SenseInfo){
case 'n':
Focus = -1;
break;
default:
side = *SenseInfo;
Focus = get_int(&SenseInfo);
if(side != situation.MySide){
Focus += SP_team_size;
}
break;
}
int Focuses = get_int(&SenseInfo);
int TackleExpire = get_int(&SenseInfo);
int Tackles = get_int(&SenseInfo);
sensebodyinfo[latestsenseinfo].setvalues(
ArmMoveable, ArmExpires, ArmTarget, Arms,
Focus, Focuses, TackleExpire, Tackles);
}
}
void Sensory::SetMyNumber(UNum no){
Agent::MyNumber = no;
Log::rec.SetID(no);
Log::recmsg.SetID(no);
}
bool Sensory::Parse_initialize_message(char* pstr){
char mode[100];
if (!(strncmp(pstr, "(init", 5)) ) {
/* It's an init msg */
UNum no;
sscanf(pstr,"(init %c %d %[^)]",&situation.MySide, &no, mode);
SetMyNumber(no);
if (situation.MySide == 'r'){
situation.TheirSide = 'l';
MyGoal = Goal_R;
TheirGoal = Goal_L;
}
else{
situation.TheirSide = 'r';
MyGoal = Goal_L;
TheirGoal = Goal_R;
}
}
else if ( !(strncmp(pstr,"(reconnect",5)) ) {
/* It's a reconnect msg */
sscanf(pstr,"(reconnect %c %[^)]",&situation.MySide, mode);
SetMyNumber(ServerParam::IP_reconnect);
if (situation.MySide == 'r'){
situation.TheirSide = 'l';
MyGoal = Goal_R;
TheirGoal = Goal_L;
}
else{
situation.TheirSide = 'r';
MyGoal = Goal_L;
TheirGoal = Goal_R;
}
}
else {
return false;
}
if ( ClientParam::goalie && FieldParam::FP_goalie_number != Agent::MyNumber )
my_error("goalie number inconsistent with me being goalie");
if ( !ClientParam::goalie && FieldParam::FP_goalie_number == Agent::MyNumber )
my_error("I should be the goalie");
if ( mode[0] == 'b' ){ /* Before_kick_off */
situation.HearMode(PM_Before_Kick_Off);
if ( situation.MySide == 'l' )
situation.SetKickOffMode(KickOff_Mine);
else
situation.SetKickOffMode(KickOff_Theirs);
}
else /* Act as if the game's in progress */
situation.HearMode(PM_Play_On);
return true;
}
/********************Set Sensed Infomation******************************************/
void Sensory::SetMySensedInfo(VIEWWIDTH viewidth, VIEWQUALITY viewqual, float stamina,float effort,float speed,AngleDeg rel_spd_angle,
AngleDeg head_angle,int kicks,int dashes,int turns,int says,int turn_necks,Time time){
if ( LastSenseTime == time && !situation.ClockStopped)
return;
PrevSenseTime = LastSenseTime;
LastSenseTime = time;
latestsenseinfo = !latestsenseinfo;
sensebodyinfo[latestsenseinfo].setvalues(viewidth, viewqual, stamina,effort,speed,rel_spd_angle,head_angle,kicks,dashes,
turns,says,turn_necks,time);
}
SenseBodyInfo& Sensory::GetSenseBodyInfo(Time time){
return (time == LastSenseTime) ? sensebodyinfo[latestsenseinfo] : sensebodyinfo[!latestsenseinfo];
}
/*******************************************************************************/
void Sensory::Update(){
//Update Time
situation.UpdateTime(LatestTime);
Log::rec.SetTime(LatestTime);
Log::recmsg.SetTime(LatestTime);
if ( NewSight && LastSightTime < situation.CurrentTime - 1 && !situation.ClockStopped){
/* Special case--ignore sights from just before change to play_on_mode
if they seem to be 2 cycles ago. Better would be to adjust the sight
time, but then sight times of all other objects also need to be adjusted */
/* process only recent cycles */
//cancel by yjy
//NewSight = false;
//rec_sight_info.Data(LastSightTime) = false;
if ( LastSightTime < situation.CurrentTime - 2 )
my_error("Last sight shouldn't be so out of date");
}
Skill::action.ActionsInvalidation(); // is the last cycle actions taking effect?
Self.update(situation.CurrentTime); // update self
Update_others(situation.CurrentTime);
Update_dirconf(situation.CurrentTime, NewSight);
Skill::action.PreProcess();
if (situation.ClockStopped)
situation.ClockStoppedTime ++;
Reset();
situation.SightTime = sensory.LastSightTime;
situation.UpdateMode();
visualsystem.PredictNextSightInf();
}
void Sensory::Update_dirconf(Time time, bool NewSight){
int i;
#ifdef _Up_FState
for(i = 0; i < ClientParam::num_divisions; i ++){
FieldInfo.dir_conf[i] = ClientParam::conf_max;
}
dir_time = time;
return;
#endif
for(i = 0; i < ClientParam::num_divisions; i ++){
FieldInfo.dir_conf[i] *= Exp(ClientParam::conf_decay, (float)(time - dir_time));
}
if (NewSight){
for(i = 0; i < ClientParam::num_divisions; i ++){
if (fabs(NormalizeAngle((i + 0.5f) * ClientParam::division - Self.Headfacing(LastSightTime))) < 0.8f * Self.MyViewAngle()){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -