机器人足球仿真第一次作业
机器人足球仿真是一门与RoboCup有关的一门课程,讲到了有关球员的决策,球队的开发等知识。
这是老师布置的第一次作业,基本任务就是解析字符串,其功能相当于uva中Prase的功能。
作业内容及要求
要求:编写程序解析球员所看到和听到的信息。
示例:(hear 1022 -30 passto(23,24))(see 1022 ((ball) -20 20 1 -2) ((player hfut1 2) 45 23 0.5 1 22
40 ) ((goal r) 12 20) ((Line r) -30))
输出:
在 1022 周期 hear 从 -30 方向 听到了 passto(23,24); 在 1022 周期 see Ball 距离我的 Direction 是 -20, Distance 是 20,DistChng 是 1,DirChng
是-2;player hfut 2 距离我的 Direction 是 45, Distance 是 23,DistChng 是 0.5,DirChng 是 1,它的 BodyDir 是 22 和 HeadDir 是 44;goal r 距离我的 Direction 是 12,Distance 是 20。
Line r 和我的角度是-30 度
不过这里我觉得示例输出有些问题,因为信息的格式为
(hear Time Sender Message)
(see Time ObjInfo ObjInfo …)
ObjInfo 表示了可视对象的信息。其格式为:
(ObjName Direction Distance DirChng DistChng BodyDir HeadDir)
所以示例中的(see 1022 ((ball) -20 20 1 -2) ((player hfut1 2) 45 23 0.5 1 22 40 ) 其中 1 -2 以及 0.5 1 应分别为方向改变量,距离改变量。
解决思路
球员接收到的信息可分为“听到的”“看到的”,听到的信息为:传来信息的人(即方向),和信息的内容;看到的信息又可以分为:球员信息,球的信息,球门信息,直线的信息。定义类将这些信息封装,用类的成员函数对信息解析并输出。
代码
头文件:
/*file: robocup2d1st.h
brief:各个类的定义(接收到的信息类)*/
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
class Player{ //有关接收到的球员信息类
public:
Player(vector<char*> &vecChar);
~Player();
void showPlayer(); //打印接收到的球员的信息
private:
string playerName; //判断是哪边的球员
double dirPlayer; //距离观察者的相对方向
double distPlayer; //距离观察者的距离
double dirChngPlayer; //方向的改变量
double distChngPlayer; //距离的改变量
double bodyDir; //该球员相对于观察者身体的角度
double headDir; //该球员相对于观察者头的角度
};
class Ball{ //有关球的信息内容
public:
Ball(vector<char*> &vecChar);
~Ball();
void showBall(); //打印接收到的球的信息
private:
double dirBall; //球距离观察者的相对方向
double distBall; //球距离观察者的距离
double distChngBall; //球方向的改变量
double dirChngBall; //球距离的改变量
};
class Goal{ //有关球门的信息内容
public:
Goal(vector<char*> &vecChar);
~Goal();
void showGoal();
private:
string typeGoal; //判断是哪边的球门r or l
double dirGoal; //球门与观察者的相对方向
double distGoal; //球门距离观察者的距离
};
class Line{ //有关线的信息内容
public:
Line(vector<char*> &vecChar);
~Line();
void showLine();
private:
string typeLine; //r or l
double angleLine; //该线相对于观察者的角度
};
.cpp文件
/*file:robocup2d1st.cpp
compiler: VS Code
function: parsing information
*/
#include<iostream>
#include<stdlib.h>
#include"robocup2d1st.h"
using namespace std;
Player::Player(vector<char*> &vecChar){
vector<char*>::iterator it;
string s{"player"};
it = find(vecChar.begin(), vecChar.end(), s);
//若接收到的信息中没有player的信息
if(it == vecChar.end()) {
cout<<"No information about player"<<endl;
}else {
it++;
it++;
playerName = *(it++);
dirPlayer = atof(*(it++));
distPlayer = atof(*(it++));
dirChngPlayer = atof(*(it++));
distChngPlayer = atof(*(it++));
bodyDir = atof(*(it++));
headDir = atof(*(it++));
}
}
Player::~Player(){}
void Player::showPlayer(){
cout<<" player hfut "<<playerName
<<"距离我的 Direction是 "<<dirPlayer
<<",Distance 是"<<distPlayer
<<",DirChng 是 "<<dirChngPlayer
<<",DistChng 是 "<<distChngPlayer
<<",它的 BodyDir 是 "<<bodyDir
<<",HeadDir 是 "<<headDir<<";";
}
Ball::Ball(vector<char*> &vecChar){
vector<char*>::iterator it;
string s{"ball"};
it = find(vecChar.begin(), vecChar.end(), s);
if(it == vecChar.end()){
cout<<"No information about ball"<<endl;
}else {
it++;
dirBall = atof(*(it++));
distBall = atof(*(it++));
dirChngBall = atof(*(it++));
distChngBall = atof(*(it++));
}
}
Ball::~Ball(){}
void Ball::showBall(){
cout<<"Ball 距离我的 Direction是 "<<dirBall
<<",Distance 是 "<<distBall
<<",DirChng 是 "<<dirChngBall
<<",DistChng 是 "<<distChngBall;
}
Goal::Goal(vector<char*> &vecChar){
vector<char*>::iterator it;
string s{"goal"};
it = find(vecChar.begin(), vecChar.end(), s);
if(it == vecChar.end()) {
cout<<"No information about goal"<<endl;
}else {
it++;
typeGoal = *(it++);
dirGoal = atof(*(it++));
distGoal = atof(*(it++));
}
}
void Goal::showGoal(){
cout<<" goal "<<typeGoal
<<"距离我的 Direction是 "<<dirGoal
<<",Distance 是 "<<distGoal<<";";
}
Goal::~Goal(){}
Line::Line(vector<char*> &vecChar){
vector<char*>::iterator it;
string s{"Line"};
it = find(vecChar.begin(), vecChar.end(), s);
if(it == vecChar.end()) {
cout<<"No information about Line"<<endl;
}else {
it++;
typeLine = *(it++);
angleLine = atof(*(it++));
}
}
Line::~Line(){}
void Line::showLine(){
cout<<" Line "<<typeLine
<<" 和我的角度是 "<<angleLine
<<" 度";
}
//用特定的分隔符分割字符串,并将分割后的字符串存储在vector中
void cutString(char *ch, vector<char*> &vecChar){
const char *mark = "( )";
char *p = strtok(ch, mark);
while(p){
vecChar.push_back(p);
p = strtok(NULL, mark);
}
return ;
}
//处理字符串
void dealWithStr(vector<char*> &vecChar){
Player p(vecChar); //声明各个信息类的对象
Ball b(vecChar);
Goal g(vecChar);
Line l(vecChar);
vector<char*>::iterator it = vecChar.begin();
string s1{"hear"};
it = find(vecChar.begin(), vecChar.end(), s1);
//听到的信息
if(it == vecChar.end()) {
cout<<"Didn't hear anything"<<endl; //若没有听到信息
}else {
it++;
cout<<"在"<<*(it++)<<"周期 hear "
<<"从"<<*(it++)<<"方向 听到了 "<<*(it++)
<<"("<<*(it++)<<")"<<endl;
}
string s2{"see"};
it = find(vecChar.begin(), vecChar.end(), s2);
//看到的信息
if(it == vecChar.end()) {
cout<<"Didn't see anything"<<endl; //若没有看到信息
}else {
it++;
cout<<"在"<<*(it++)<<"周期 see ";
b.showBall();
p.showPlayer();
g.showGoal();
l.showLine();
}
return ;
}
int main(){
vector<char*> vecChar;
char ch[2000] = "(hear 1022 -30 passto(23,24))(see 1022 ((ball) -20 20 1 -2) ((player hfut1 2) 45 23 0.5 1 22 40 ) ((goal r) 12 20) ((Line r) -30))";
cutString(ch, vecChar);
dealWithStr(vecChar);
return 0;
}
输出:(使用VS Code 编译运行)
我的思路是把信息封装到类里,这样对于不同信息的处理方式就会比较相似,但是这种处理办法也比较麻烦繁琐,其实也可以直接处理字符串输出。该思路仅供参考,欢迎大家指正!