?? offclient.cpp
字號:
//#ifdef _OffClient
/* -*- Off Client -*-
* Custom initialization and destruction
* Only one thread is created to both parse server info and do decision-making.
* To capture the desired cycle in ExecuteAI.
*/
#include "client.h"
#include "stopwatch.h"
#include "log.h"
#include "worldmodel.h"
#include <fstream>
#include "perceptron.h"
#include "skill.h"
#include "agent.h"
#include "utils.h"
#include "netif.h"
using namespace World;
#ifndef WIN32
#include <time.h>
#include <pthread.h>
#include <iostream>
#endif
#ifdef WIN32
#include <process.h>
HANDLE sigoffclient = NULL;
#else // _LINUX
pthread_t sigoffclient;
#endif
FILE *fp_mat = NULL;
#ifdef WIN32
unsigned int WINAPI OffProcWindows(LPVOID lpParameter);
#endif
void * OffProc(void *);
void ExecuteAI();
void Assitant(char* buf);
int Readline(char* &buf);
/*This function is called in the same order with behave() in normal client mode.
*/
void ExecuteAI(){
Agent::behave();
}
void Assistant(char* buf){
int type;
int subtype, time;
float x,y, power;
UniformTime ut;
TIME_T tt;
int width, quality;
type = get_int(&buf);
switch(type){
case Ass_Vinfo:
subtype = get_int(&buf);
visualsystem.Vinfo_coming = bool(subtype == 1);
if(visualsystem.Vinfo_coming){
visualsystem.Vcominginfo_angle = get_float(&buf);
visualsystem.Vcominginfo_width = get_float(&buf);
}
break;
case Ass_ActEffect:
subtype = get_int(&buf);
time = get_int(&buf);
switch(subtype){
case CMD_kick:
x = get_float(&buf); y = get_float(&buf); power = get_float(&buf);
Skill::action.SetKickEffect(x, y, power, time);
break;
case CMD_dash:
x = get_float(&buf); y = get_float(&buf); power = get_float(&buf);
Skill::action.SetDashEffect(x, y, power, time);
break;
case CMD_turn:
x = get_float(&buf);
Skill::action.SetTurnEffect(x, time);
break;
case CMD_turn_neck:
x = get_float(&buf);
Skill::action.SetTurnNeckEffect(x, time);
break;
case CMD_change_view:
Self.NextViewCycle = get_int(&buf);
sensory.NextViewWidth = VIEWWIDTH(get_int(&buf));
}
break;
case Ass_Chview:
#ifdef WIN32
sscanf(buf, "%d %I64d %d %d", &subtype, &ut.QuadPart, &width, &quality);
#else // _LINUX
sscanf(buf, "%d %lld %d %d", &subtype, &ut.QuadPart, &width, &quality);
#endif
tt = stopwatch.DeFormatTime(ut);
stopwatch.SetRawData_Event(tt, subtype);
if(!situation.ClockStopped){
float nextsight_time;
int LatestTime = sensory.LatestTime;
//note: if no change view, the nextviewwidth is just my current viewwidth.
nextsight_time = sensory.SightInterval((VIEWWIDTH)width, (VIEWQUALITY)quality) - stopwatch.MsFromEvent(SW_Event_ChangeView, SW_CycleStart, LatestTime);
Self.NextViewCycle=LatestTime + nextsight_time / ServerParam::simulator_step;
}
break;
}
}
void SetWatch(char* buf){
UniformTime tmp;
#ifdef WIN32
sscanf(buf,"%I64d", &tmp.QuadPart);
#else //_LINUX
sscanf(buf,"%lld", &tmp.QuadPart);
#endif
//set into cache time identified in the following parse
TIME_T t = stopwatch.DeFormatTime(tmp);
stopwatch.SetRawData_Cache(t);
}
/*Read a valid line from mat file, return state and valuable buffer point.
*
* Return Value:
* -1:fail
* LM_Init: init info
* LM_Info: Msg received from server
* LM_Ctrl: Log when Ctrl proc start to update
* buf: point to valuable msg (log label has been stripped)
*/
int Readline(char* &buf){
while(true){
if(fgets(StringBuffer::matbuf, MAXMESG, fp_mat) == NULL)
return -1;
//string format "(p%d,t%d)[label] info..."
buf = StringBuffer::matbuf;
//advance to '['
while(*buf != '[' && *buf != 0) buf ++;
if(*buf != 0) break;
}
buf ++;
//look label
char* channel_str[] = LM_Channel_Label;
for(int i=0; i<LM_Num_Channels; i++){
int len = strlen(channel_str[i]);
if(!strncmp(buf, channel_str[i], len)){
buf += len;
buf ++;
return LM_Channel(i);
}
}
return -1;
}
#ifdef WIN32
/*Offclient process
* Simulate Match on the basis of mat file
*/
unsigned int WINAPI OffProcWindows(LPVOID lpParameter){
OffProc(NULL);
_endthreadex(0);
return 0;
}
#endif
extern int NoResponseFromServer;
void * OffProc(void *){
char* buf;
int state;
while(true){
state = Readline(buf);
switch(state){
case LM_Init:
case LM_Info:
sensory.Parse(buf);
break;
case LM_Upd:
DoLog(LOG_NONE, "******** Cycle %d **********", sensory.LatestTime);
sensory.Update();
break;
case LM_Exec:
ExecuteAI();
break;
case LM_Ass:
Assistant(buf);
break;
case LM_Watch:
SetWatch(buf);
break;
case -1:
#ifdef WIN32
PostMessage(hWND, WM_DESTROY, 0, 0);
#else //_LINUX
pthread_exit(0);
#endif
return 0;
default :
break;
}
}
}
/* Initialization of OffClient Mode
* prepare the mat file, and create thread.
*/
int InitInstance_E(){
Log::InitLog();
Network::sock = NULL;
fp_mat = fopen(ClientParam::matfile, "r");
if(fp_mat == NULL) return 0;
char* buf;
//1)read team name from mat file
if(Readline(buf) != LM_Init) return 0;
int buflen = strlen(buf);
buf[buflen-1] = 0; //skip the newline character
strcpy(MyTeamName, buf);
MyTeamNameLen = strlen(MyTeamName);
//2)read init infos (including server's and players' param)
if(Readline(buf) != LM_Init) return 0;
if(!sensory.Parse_initialize_message(buf)){
return 0;
}
my_error("Connected!");
Agent::Initialize();
#ifdef WIN32
sigoffclient = (HANDLE)_beginthreadex(NULL, 0, OffProcWindows, NULL, 0, NULL);
if(sigoffclient == NULL){
my_error("create thread off error");
return false;
}
SetThreadPriority(sigoffclient,THREAD_PRIORITY_BELOW_NORMAL);
#else // _LINUX
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&sigoffclient, &attr, OffProc, NULL) != 0){
my_error("create thread error");
return false;
}
pthread_join(sigoffclient, NULL);
#endif
return true;
}
/* Desctruction
* Terminate thread and Close mat file.
*/
void destruction_E(){
#ifdef WIN32
if(sigoffclient){
CloseHandle(sigoffclient);
}
#endif
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -