 |  |
|
난이도 : 초급 Alisdair Owens, Student, University of Southampton
2002 년 5 월 01 일 반중력 운동(Anti-gravity movement)은 대부분의 Robocoder 전문가들이 선택하는 움직임 유형이다. 이를 사용하여 지도상에서 피할 수 있는 지점을 설정하고 움직임 패턴을 만들며 적의 총알을 피할 수 있다. Alisdair Owens는 이 유용한 기술의 구현 방법을 설명하고 테스트 구동을 위해 로봇 예제도 제공한다.
반중력 운동(Anti-gravity movement)은 유연성이 뛰어난 기술로서 전투장 내에서 피신할
수 있는 특별한 지점 (중력 지점-gravity points)을 정의하여 패턴 분석 로봇을
혼란에 빠트린다. 각각의 중력 지점(gravity point)은 세기(strength)에 따라 할당된다.
x와 y의 방향에서 세기의 요소를 결정하여 모든 적군 로봇을 피할 수 있다. ("반중력(Anti-gravity) 용어정리" 참조)
반중력 운동의 수학원리
반중력에 내포된 수학은 실제로 매우 간단하다. 삼각법만 알면 된다.
그림 1에서 "F"라는 화살은 Crazy로 부터 AntiGravityBot에 가해지는 힘의 방향을 나타낸다.
힘은 다른 두 개의 화살에서 보이듯이 x와 y에 있는 컴포넌트로 간주될 수 있다. 힘을 결정하여 x와 y
방향의 모든 중력 지점에서 모든 힘을 한데 모을 수 있다 .
 |
반중력(Anti-gravity) 용어정리
중력 지점(Gravity points): 공격하기 원하는 장소로 정의된 Robocode
전투장 내의 장소들.
힘(Forces): 각각의 중력 지점은 힘(force) 또는 세기(strength)를
할당 받는다. 값이 클수록 로봇은 그 지점에서 힘을 만들어 내면서 공격할 수 있다.
힘의 컴포넌트: 각각의 힘은 x (수평) 방향과 , y (수직) 방향에서 작동하는
컴포넌트를 갖고있다. 45도 각도는 x와 y 방향에서 동등한 컴포넌트를 갖고있다. 90도 각도는
x 방향에서 전적으로 작동한다.
힘 결정하기: 여러 힘들이 작동할 때 만들어진 모든 힘을 산정하는 과정이다.
예를 들어 x 방향에서 작동하는 -200의 힘이 있고 또한 x 방향에서 300의 힘이 있다면 만들어진
힘의 전체는 100이다.
|
|
그림 1. 힘 결정하기
로봇이 멀리있는 로봇에 의해 영향받지 않도록 하려면, 세기(strength)가 중력 지점의
힘이고 거리(distance)가 중력 지점과 로봇 사이의 거리인 곳에서 force
= strength/Math.pow(distance,2) 함수를 사용하여 중력 지점으로부터
로봇에 가해지는 힘을 계산해야한다.
코드
다음 코드는 기본적인 시스템 코드이다. Listing 1은 반중력의 주요 함수를 보여주고 있다. 한 벡터
내에서 모든 중력 지점을 통해 순환하고 힘을 결정하며 정확한 방향으로 로봇을 움직인다. 적군 로봇들이 격퇴
지점에 가있도록 할 것을 권장하는 바이다. 이렇게 하려면 전투장 모양을 항상 업데이트 해야한다.
Listing 1.반중력의 일꾼: antiGravMove()
void antiGravMove() {
double xforce = 0;
double yforce = 0;
double force;
double ang;
GravPoint p;
for(int i = 0;i<gravpoints.size();i++) {
p = (GravPoint)gravpoints.elementAt(i);
//Calculate the total force from this point on us
force = p.power/Math.pow(getRange(getX(),getY(),p.x,p.y),2);
//Find the bearing from the point to us
ang =
normaliseBearing(Math.PI/2 - Math.atan2(getY() - p.y, getX() - p.x));
//Add the components of this force to the total force in their
//respective directions
xforce += Math.sin(ang) * force;
yforce += Math.cos(ang) * force;
}
/**The following four lines add wall avoidance. They will only
affect us if the bot is close to the walls due to the
force from the walls decreasing at a power 3.**/
xforce += 5000/Math.pow(getRange(getX(),
getY(), getBattleFieldWidth(), getY()), 3);
xforce -= 5000/Math.pow(getRange(getX(),
getY(), 0, getY()), 3);
yforce += 5000/Math.pow(getRange(getX(),
getY(), getX(), getBattleFieldHeight()), 3);
yforce -= 5000/Math.pow(getRange(getX(),
getY(), getX(), 0), 3);
//Move in the direction of our resolved force.
goTo(getX()-xforce,getY()-yforce);
}
|
Listing 2의 helper 메소드는 가장 효율적인 방법으로 어떤 지점으로 움직일 수 있도록 하면서
로봇과 적군로봇 사이의 거리를 두도록 한다.
Listing 2. Helper 메소드
/**Move in the direction of an x and y coordinate**/
void goTo(double x, double y) {
double dist = 20;
double angle = Math.toDegrees(absbearing(getX(),getY(),x,y));
double r = turnTo(angle);
setAhead(dist * r);
}
/**Turns the shortest angle possible to come to a heading, then returns
the direction the bot needs to move in.**/
int turnTo(double angle) {
double ang;
int dir;
ang = normalisebearing(getHeading() - angle);
if (ang > 90) {
ang -= 180;
dir = -1;
}
else if (ang < -90) {
ang += 180;
dir = -1;
}
else {
dir = 1;
}
setTurnLeft(ang);
return dir;
}
/**/Returns the distance between two points**/
double getRange(double x1,double y1, double x2,double y2) {
double x = x2-x1;
double y = y2-y1;
double range = Math.sqrt(x*x + y*y);
return range;
}
|
마지막으로, Listing 3에서 GravPoint 클래스를 볼 수 있는데 이것은
중력 지점에 대해 우리가 필요로하는 모든 데이터를 보유하고 있다. 격퇴하기 위해서는 power는
마이너스(-)가 되어야한다.
Listing 3. GravPoint class
class GravPoint {
public double x,y,power;
public GravPoint(double pX,double pY,double pPower) {
x = pX;
y = pY;
power = pPower;
}
}
|
작동 향상
Listings 1 부터 3의 코드는 합리적인 작동을 만들어낸다. 하지만 전투 퍼포먼스에는 미치지 못한다.
로봇이 다른 로봇과 일반적으로 멀리 떨어져있으면 벽에 밀착할 경향이 크다. 예를 들어 일단 로봇이 밑쪽
벽에 다다르면 이 보다 아래에 있는 로봇은 없다. 따라서 벽 자체에서 만들어진 반발력을 제외하고는 이것을
밀어낼 힘이 없는 것이다. 벽의 반발력은 제한된 범위이기 때문에 형편없는 작동만 만들어내는 것이다.
이 문제를 해결하기위해서 전투장 주변의 일련의 지점들에 모든 힘을 모으는 시스템을 사용한다. 그런다음
평균보다 큰 힘을 가진 지점들에 반발력 값을 할당하고 평균 힘보다 낮은 값을 가진 지점에 견인력 값을 할당한다.
그런 다음 로봇에 새로운 지점들의 힘을 할당한다. 견인 지점을 할당할 때 조심해야한다. 로봇이 견인 지점에
가까이 갈 때 근방을 배회하면서 결코 떠나지 않을 것이다. 이런 문제 때문에 중간 지점에 무작위로 위치를
할당하고 위치를 정기적으로 바꾼다.
추가적인 작동 향상
반중력은 놀랍도록 융통성이 있는 기술이다. 우리가 만들 수 있는 전체 작동 범위를 논하는 것은 불가능하다.
다음은 그 중 흥미로운 것들이다:
목표 선택: 공격하기 편하거나 힘이 약한 목표물에 낮은 반발력 값을 할당하여 그 목표물에
가까이 가서 공격할 수 있다.
불규칙성(Randomisation): 규칙성을 기본으로 하고, x와 y 힘에서 임의의 수를
더하거나 빼어서 좀더 임의적인 움직임을 만들어내고 때때로 멈추기도 하며 적군의 타겟 시스템을 속일 수도
있다.
총알 피하기 : 적군이 자신에게 발사할 때를 안다면 반중력 지점으로 발사되는 총알을 모델링할
수 있다. 예를 들어 선형 타케팅으로 발사된다면 매 순서마다 중력 지점의 위치를 업데이트 하여 총알을 피할
수 있다.
리더(leader)를 따르기: 자신의 로봇이 따라갈 "매력적인" 지점을
만드는 것이다. 이 지점을 움직여서 원하는 모든 패턴을 만들 수 있다.
참고자료
필자소개  | |  | Alisdair Owens는 University of Southampton에서 컴퓨터 공학을 전공하는 학생이다.
|
기사에 대한 평가
|  |