《机器人技术》第一次作业
题目: 在机器人足球比赛中,server和球员client之间通过发送字符串来进行信息交互,其中server要把某球员的听觉和视觉信息发送给该球员,信息的格式如下所示:
(hear Time Sender Message)
(see Time ObjInfo ObjInfo …)
其中
(hear Time Sender Message)的具体含义如下:
- Time:前的仿真周期。
- Sender
- 如果是其他球员发送的消息,那么是发送者的相当方向(Direction)
- self:发送者是自己本人。
- referee:裁判是发送者。
- online_coach_left 或者online_coach_ringt:发送者是在线教练。
- Message:消息内容。
(see Time ObjInfo ObjInfo …)的具体含义如下:
- Time:当前时间。
- ObjInfo表示了可视对象的信息。其格式为:
(ObjName Distance Direction DistChng DirChng BodyDir HeadDir)
¡ ObjName = (player Teamname Unum)
- |(goal Side)
- |(ball)
- |(flag c)
- |(flag [ l | c | r] [ t | b ])
- |(flag p [ l | r] [ t | c | b ])
- |(flag [ t | b] [ l | r ] [10 | 20 | 30 | 40 |50 ])
- |(flag [ l | r] [ t | b ] [10 | 20 | 30 ])
- |(flag [ l | r | t | b ] 0)
- |(line [ l | r | t | b ])
¡ Distance,Direction表示目标的相对距离和相对方向
¡ DistChng和DirChng分别表示目标距离和方向的相对变化,如果是固定物体(球和球员以外的所有对象)则没有改项值
¡ BodyDir 和HeadDir,分别是被观察球员相对观察者的身体和头部的相对角度,只有是球队对象才有这一项值。
要求:编写程序解析球员所看到和听到的信息。
示例:(hear 1022 -30 passto(23,24))(see 1022 ((ball) 20 -20 1 -2) ((player hfut1 2) 23 45 0.5 1 22 40 ) ((goal r) 12 20))
输出:
在1022周期 hear 从 -30 方向 听到了 passto(23,24);
在1022周期 see Ball 距离我的 Distance 是 20, Direction是 -20,DistChng是1,DirChng是-2;player hfut 2距离我的Distance 是 23, Direction是 45,DistChng是0.5,DirChng是1,它的BodyDir是 22和HeadDir 是 44;goal r 距离我的Distance 是 12, Direction是 20。
一些参考建议:
场上对象: (f r b 10)表示场上某个点,具体见教材28页,教材上写的是(flag r b 10),大家写程序的时候以f为准。
本示例中左右2边的名称分别为hfut1和hfut2, 大家写程序的时候hfut1的球员信息存储在在队友里面,hfut2存储在对手里面。
Java源码:
就是对字符串的简单解析。
package RobatHomework1;
public class Getmessage {
public static void main(String args[]) {
String text = "(hear 1022 -30 passto(23,24)) (see 1022 ((ball) 20 -20 1 -2) ((player hfut1 2) 23 45 0.5 1 22 40 ) ((goal r) 12 20))";
String text2 = "(hear 8888 referee 好球!)(see 8888 ((ball) 121 -210.1 12 -22) ((player hfut1 5) 223 445 0.15 1 22 40 ) ((goal r) 12 20) ((f r b 10) 23 45))";
String text3 = "(hear 1022 -30 passto(23,24))(see 1022 ((ball) 20 -20 1 -2) ((player hfut1 2) 23 45 0.5 1 22 40 ) ((g r) 12 20))";
String text4 = "(hear 2021 self \"I'm numb5\")(see 0 ((g r) 64.1 13) ((f r t) 64.5 -16) ((f r b) 79 38) ((f p r t) 46.1 -6) ((f p r c) 48.1 18) ((f p r b) 58 37) ((l r ) 62.8 -89))";
String text5 = "(hear 1024 referee corner_kick_r)(see 0 ((g r) 64.1 13) ((f r t) 64.5 -16) ((f r b) 79 38) ((f p r t) 46.1 -6) ((f p r c) 48.1 18) ((f p r b) 58 37) ((l r ) 62.8 -89))";
Parting a = new Parting();
Parting b = new Parting();
Parting c = new Parting();
Parting d = new Parting();
Parting e = new Parting();
System.out.println("测试数据1:");
a.GetHS(text);
// 测试System.out.println(a.HearMessage);
// 测试System.out.println(a.SeeMessage);
a.ReturnHear();
a.ReturnSee();
System.out.println("测试数据2:");
b.GetHS(text2);
b.ReturnHear();
b.ReturnSee();
System.out.println("测试数据3:");
c.GetHS(text3);
c.ReturnHear();
c.ReturnSee();
System.out.println("测试数据4:");
d.GetHS(text4);
d.ReturnHear();
d.ReturnSee();
System.out.println("测试数据5:");
e.GetHS(text5);
e.ReturnHear();
e.ReturnSee();
}
}
class Parting {
String HearMessage;
String SeeMessage;
// 初步获取信息,将信息分割成hear和see两块
void GetHS(String MyMessage) {
this.HearMessage = MyMessage.substring(MyMessage.indexOf("hear") - 1, MyMessage.indexOf("see") - 1);
this.SeeMessage = MyMessage.substring(MyMessage.indexOf("see") - 1, MyMessage.length());
this.HearMessage.trim();
this.SeeMessage.trim();
}
//解析hear内容
void ReturnHear() {
String[] hemes;
// 去除无关信息,将听到的内容格式化,使其以括号组形式存在
String Hearme = this.HearMessage.substring(this.HearMessage.indexOf("(") + 1,
this.HearMessage.lastIndexOf(")"));
// 用空格进行分割 因为经过上面的处理,剩余的信息是() () () 这样括号组以空格分割的形式
hemes = Hearme.split(" ");
/*
* 测试 for(int i =0;i<=3;i++){ System.out.println(hemes[i]); }
*/
Boolean strResult = hemes[2].matches("-?[0-9]+.?[0-9]*"); // 正则表达式,判断是否是数字
// 如果是数字就需要加方向
if (strResult == true) {
System.out.print("在" + hemes[1] + "周期 hear从" + hemes[2] + "方向听到了");
for (int i = 3; i < hemes.length; i++) {
System.out.print(hemes[i] + " ");
}
System.out.println();
} else {
System.out.print("在" + hemes[1] + "周期 hear从" + hemes[2] + "听到了");
for (int i = 3; i < hemes.length; i++) {
System.out.print(hemes[i] + " ");
}
System.out.println();
}
}
//对看见的信息进行处理
void ReturnSee() {
// 去除无关信息,留下以括号组存在的格式化信息
String temp = this.SeeMessage.substring(this.SeeMessage.indexOf("(", 2), this.SeeMessage.lastIndexOf(")"));
temp.trim();// 去空格
// System.out.println(temp);
String time1 = this.SeeMessage.substring(5, this.SeeMessage.indexOf("(", 2) - 1);
time1.trim();
// System.out.println(time1);
String messages[] = new String[20];
int count = 0, begin = 0, end = 0, count1 = 0;
// 看到了多个信息,每个信息以括号组形式存在,下面提取出来
for (int i = 0; i < temp.length(); i++) {
if (count == 0) {
begin = i;
}
if (temp.charAt(i) == '(') {
count++;
}
if (temp.charAt(i) == ')') {
count--;
if (count == 0) {
end = i + 1;
messages[count1] = temp.substring(begin, end);
count1++;
}
}
}
System.out.print("在" + time1 + "周期see ");
for (int j = 0; j < count1; j++) {
// System.out.println(messages[j]);
// 下面确认信息源,因为球 球员以及固定物的格式化信息是不同的,需要分别处理
if (messages[j].contains("player")) {
// 下面是提取信息源名称后面的信息,并分割。
String[] playermessage = (messages[j]
.subSequence(messages[j].indexOf(')') + 1, messages[j].lastIndexOf(')')).toString().trim())
.split(" ");
/*
* int k = 0; for(k=0;k<playermessage.length;k++) {
* System.out.println(playermessage[k]);
*
* }
*/
System.out.println(
messages[j].substring(2, messages[j].indexOf(')')) + " 距离我的 Distance 是" + playermessage[0]
+ ",Direction是 " + playermessage[1] + ",DistChng是" + playermessage[2] + ",DirChng是"
+ playermessage[3] + ",它的BodyDir是" + playermessage[4] + "和HeadDir是" + playermessage[5]);
} else if (messages[j].contains("ball")) {
String[] ballmessage = (messages[j]
.subSequence(messages[j].indexOf(')') + 1, messages[j].lastIndexOf(')')).toString().trim())
.split(" ");
/*
* int k = 0;
*
* for(k=0;k<ballmessage.length;k++) { System.out.println(ballmessage[k]); }
*/
System.out.println(messages[j].substring(2, messages[j].indexOf(')')) + " 距离我的 Distance 是"
+ ballmessage[0] + ",Direction是 " + ballmessage[1] + ",DistChng是" + ballmessage[2] + ",DirChng是"
+ ballmessage[3]);
} else {
String[] Fixturemessage = (messages[j]
.subSequence(messages[j].indexOf(')') + 1, messages[j].lastIndexOf(')')).toString().trim())
.split(" ");
/*
* int k = 0; for(k=0;k<Fixturemessage.length;k++) {
* System.out.println(Fixturemessage[k]); }
*/
System.out.println(messages[j].substring(2, messages[j].indexOf(')')) + " 距离我的 Distance 是"
+ Fixturemessage[0] + ",Direction是 " + Fixturemessage[1]);
}
}
}
}
运行效果:
注:第一、三、四、五组为课本或作业举例信息,第二组为自行虚拟信息,均能成功解析,解析的hear数据各自储存在hemes数组,解析see的数据各自储存messages数组中,非常易于重新提取或赋值给其他对象。