로보코드(코드) 문제 유형
Last updated
Last updated
학습진행 장에서 실습화면 인터페이스를 확인하지 않으셨다면 아래 링크를 먼저 확인하시기를 권장합니다.
로보코드(코드) 문제는 로봇의 움직임을 프로그래밍하여 상대 로봇을 이기는 문제 형태입니다. 수강자님께서는 주어진 문제 내용과 로보코드에서 제공하는 함수를 확인하여, 이를 기반으로 프로그램을 작성하게 됩니다.
Javascript를 이용하여 프로그램을 작성할 수 있습니다.
로보코드는 Javascript로 로봇을 움직이는 코드를 작성하여 전장내의 다른 로봇을 파괴하는 게임입니다.
로봇의 기본 체력은 100입니다. 미사일을 맞거나 충돌이 발생하면 로봇의 체력이 감소하고, 0보다 낮아지면 파괴됩니다.
게임에서 로봇이 1개가 남았을 때 게임이 종료되며, 승리 조건은 단판승, 다전제, 점수제가 있습니다.
단판승: 단 1라운드의 경기로 승/패가 결정되는 방식입니다.
다전제: 3라운드 이상의 경기를 진행하며, 모든 라운드가 끝났을 때 더 많은 라운드에서 승리한 로봇이 최종 승리합니다.
점수제: 1라운드 이상의 경기에서 각 라운드마다 게임 내용에 의해 점수가 결정되고, 모든 라운드가 끝났을 때 점수의 합계가 높은 로봇이 승리합니다. 점수 계산에 대한 자세한 정보는 6번 항목 점수표에서 확인할 수 있습니다.
로봇은 1턴 단위로 움직이게되며, 기본 게임속도는 1초에 30턴이 진행되는 속도입니다. 예를들어 10만큼 이동하라는 명령어를 수행한다면, 1턴에 10만큼 이동하는 것이 아닌, 조건에 의해 여러 턴동안 10만큼 움직이게 됩니다.
마찬가지로 20만큼 회전하라는 명령어는 조건에 의해 여러 턴 동안 20만큼 회전합니다. 이 개념은 더 나은 로봇을 만들기 위해서 이해가 필요합니다.
로보코드는 이벤트에 의해 동작합니다. 기본적으로 onIdle
이라는 기본함수가 반복적으로 동작하면서,
특정 상황에 이벤트가 발생한다면 해당 이벤트를 우선으로 로보코드가 동작합니다.
예를 들어 대기 중일때 로봇을 회전하면서 적을 찾게되면, onEnemySpot
이라는 이벤트가 발생하여,
해당 이벤트의 함수들을 우선적으로 동작시킵니다.
만약 기본함수 내의 함수들과 이벤트 내의 함수가 동시에 실행할 수 있는 함수라면
(직진과 회전) 동시에 실행됩니다.
각 이벤트에는 우선순위가 지정되어있습니다. 우선순위는 아래와 같습니다.
onHit
(미사일에 맞았을 때) - 40onWallCollide
(벽에 충돌했을 때) - 30onRobotCollide
(다른 로봇과 충돌했을 때) - 20onEnemySpot
(다른 로봇을 발견했을 때) - 10
이에 대한 설명은 아래와 같습니다.
1. A 이벤트가 동작중일 때, A보다 우선순위가 높은 B 이벤트가 발생한다면, A는 중지되고 B이벤트가 동작한다. 2. A 이벤트가 동작중일 때, A보다 우선순위가 낮은 B 이벤트가 발생한다면, B는 동작하지 않는다. 3. 2개의 이벤트가 한 턴에 동시에 발생한다면, 우선순위가 높은 이벤트가 실행된다.
설명이 어려울 수 있지만, 직접 해본다면 쉽게 알 수 있을 것입니다.
로보코드에서 위치는 (x, y)로 표시됩니다. 전장의 가장 왼쪽 위가 (0, 0)이며, 오른쪽으로 갈수록 x값이 증가하며, 아래로 갈수록 y값이 증가합니다.
로보코드에서 각도는 (0 <= 각도 < 360) 로 표시됩니다. 북쪽이 0도이며, 시계방향으로 증가합니다. 즉, 동쪽은 90도, 남쪽은 180도, 서쪽은 270도입니다.
로봇은 이동함수(this.moveForwards
, this.moveBackwards
)에 의해 움직입니다.
속도가 증가할때는 최대 1씩 증가하며, 감소할때는 최대 2씩 감소합니다. 최대 속도는 8입니다.
만약 정지상태에서 this.moveForwards(100)
의 함수로 100만큼 움직이게 했다면,
속도는 0부터 8까지 1씩 증가하여 8인상태 (1턴당 8만큼 움직임)로 움직이다가
정지할때쯤 2씩 감소하여 0의 속도가 되어 정지하게됩니다.
로봇은 벽이나 다른 로봇과 충돌할 때 피해를 입습니다. 벽에 부딪힌다면 체력이 0.2 감소하고, 다른 로봇과 부딪힌다면 체력이 0.6 감소합니다.
위의 함수는 이벤트가 아닌 로봇의 기본 동작함수로서, 로봇이 다른 이벤트가 없을 때 기본적으로 계속 반복되는 함수입니다.
이곳에 코드를 작성하면 로봇이 대기중인 상태에서의 동작을 구현할 수 있습니다.
위의 이벤트는 로봇이 벽에 충돌하는 상황에서 발생하는 이벤트입니다. 이곳에 코드를 작성하면 로봇이 벽에 충돌했을 때의 동작을 구현할 수 있습니다.
위의 이벤트는 로봇이 다른 로봇과 충돌하는 상황에서 발생하는 이벤트입니다. 이곳에 코드를 작성하면 로봇이 다른 로봇과 충돌했을 때의 동작을 구현할 수 있습니다.
위의 이벤트는 로봇이 미사일에 맞았을 때 발생하는 이벤트입니다. 이곳에 코드를 작성하면 로봇이 다른 로봇과 충돌했을 때의 동작을 구현할 수 있습니다.
위의 이벤트는 로봇이 미사일에 맞았을 때 발생하는 이벤트입니다. 이곳에 코드를 작성하면 다른 로봇을 발견했을 때의 동작을 구현할 수 있습니다.
이 이벤트에서 사용 할 수 있는 함수가 추가적으로 있습니다. 자세히 알아보려면 하단 5번 항목을 참조하시기 바랍니다.
this.moveForwards(입력값);
입력값(거리)만큼 로봇을 전진시키는 함수입니다.
this.moveBackwards(입력값);
입력값(거리)만큼 로봇을 후진시키는 함수입니다.
this.turnRight(입력값);
입력값(각도)만큼 로봇을 오른쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 왼쪽으로 회전합니다.
1턴에 회전할 수 있는 각도는 최대 10도입니다. (10 - 속도 * 0.75)
this.turnLeft(입력값);
입력값(각도)만큼 로봇을 왼쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 오른쪽으로 회전합니다.
1턴에 회전할 수 있는 각도는 최대 10도입니다. (10 - 속도 * 0.75)
this.turnTurretRight(입력값);
입력값(각도)만큼 대포를 오른쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 왼쪽으로 회전합니다.
1턴에 회전할 수 있는 각도는 최대 20도입니다.
this.turnTurretLeft(입력값);
입력값(각도)만큼 대포를 왼쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 오른쪽으로 회전합니다.
한번에 회전할 수 있는 각도는 최대 20도입니다.
this.turnRadarRight(입력값);
입력값(각도)만큼 레이더를 오른쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 왼쪽으로 회전합니다.
1턴에 회전할 수 있는 각도는 최대 45도입니다.
this.turnRadarLeft(입력값);
입력값(각도)만큼 레이더를 왼쪽으로 회전시키는 함수입니다. 만약 입력값이 0보다 작으면 오른쪽으로 회전합니다.
1턴에 회전할 수 있는 각도는 최대 45도입니다.
this.shoot(입력값);
입력값에 의해 결정된 공격력과 속도를 갖는 미사일을 발사합니다.
1. 입력값만큼 내 로봇의 체력이 소모됩니다.
2. 입력값 * 4 (만약 입력값이 1이상이면 2 * (입력값 - 1) 추가) 의 공격력을 갖습니다.
3. 20 - 3 * 입력값 만큼의 속도를 갖습니다. 4. 미사일이 명중하면 적은 공격력만큼의 체력이 감소합니다.
5. 미사일이 명중하면 내 로봇은 공격력 * 3 만큼의 체력을 회복합니다.
6. (입력값 / 5) + 1 만큼 대포가 가열됩니다. (대포는 1턴에 0.1만큼 식고, 가열이 0이되어야 미사일을 발사 할 수 있습니다.)
this.setMaxVelocity(입력값);
로봇의 최대 속도를 입력값으로 설정하는 함수입니다. 입력값은 0보다 크고 8보다 같거나 작아야 합니다.
this.setMaxTurnRate(입력값);
로봇의 최대 회전각도를 입력값으로 설정하는 함수입니다. 로봇의 최대 회전각도는 입력값과 속도에 의해 결정된 값 중 작은값으로 결정됩니다.
입력값은 0보다 크고 10보다 같거나 작아야합니다.
this.setTurnRight(입력값);
로봇의 다음 이동 함수가 실행될 때 동시에 로봇을 입력값만큼 오른쪽으로 회전시키는 함수입니다.
this.setTurnRight(20);
을 호출하고 그 뒤에this.moveForwards(100);
을 호출한다면
로봇이 100을 이동함과 동시에 로봇을 20도만큼 오른쪽으로 회전시킵니다.
this.setTurnLeft(입력값);
로봇의 다음 이동함수가 실행될 때 동시에 로봇을 입력값만큼 왼쪽으로 회전시키는 함수입니다.
this.setTurnTurretRight(입력값);
로봇의 다음 이동함수가 실행될 때 동시에 대포를 입력값만큼 오른쪽으로 회전시키는 함수입니다.
this.setTurnTurretLeft(입력값);
로봇의 다음 이동함수가 실행될 때 동시에 대포를 입력값만큼 왼쪽으로 회전시키는 함수입니다.
this.setTurnRadarRight(입력값);
로봇의 다음 이동함수가 실행될 때 동시에 레이더를 입력값만큼 오른쪽으로 회전시키는 함수입니다.
this.setTurnRadarLeft(입력값);
로봇의 다음 이동함수가 실행될 때 동시에 레이더를 입력값만큼 왼쪽으로 회전시키는 함수입니다.
this.getBattleFieldWidth();
전장의 가로 크기를 가져오는 함수입니다.
this.getBattleFieldHeight();
전장의 세로 크기를 가져오는 함수입니다.
this.getHp();
내 로봇의 현재 체력을 가져오는 함수입니다.
this.getHeading();
내 로봇이 바라보는 방향을 각도(0 <= 각도 < 360)로 가져오는 함수입니다.
this.getTurretHeading();
내 대포가 바라보는 방향을 각도(0 <= 각도 < 360)로 가져오는 함수입니다.
this.getRadarHeading();
내 레이더가 바라보는 방향을 각도(0 <= 각도 < 360)로 가져오는 함수입니다.
this.getVelocity();
내 로봇의 현재 속도를 가져오는 함수입니다.
this.getX();
내 로봇의 x좌표를 가져오는 함수입니다.
this.getY();
내 로봇의 y좌표를 가져오는 함수입니다.
prototype.onEnemySpot = function(e) {};
와 같은 형태로 onEnemySpot 이벤트에
파라미터를 받아온다면 아래와 같은 함수를 쓸 수 있습니다.
e.getDistance();
발견한 적과 내 로봇의 거리를 가져오는 함수입니다.
e.getHp();
발견한 적의 현재 체력을 가져오는 함수입니다.
e.getVelocity();
발견한 적의 속도를 가져오는 함수입니다.
e.getHeading();
발견한 적의 로봇이 바라보는 방향을 각도(0 <= 각도 < 360)로 가져오는 함수입니다.
e.getBearing();
발견한 적의 방향과 내 로봇이 바라보는 방향의 차이를 각도로 가져오는 함수입니다. (-180 < 각도 <= 180)
만약 내 로봇이 20도방향을 바라보고 있는데 적 로봇이 50도의 위치에서 감지된다면 결과는 30이되고, 만약 내 로봇이 270도 방향을 바라보고 있는데 적 로봇이 180도 위치에서 감지된다면, 결과는 -90이 됩니다.
점수제 게임에서의 점수계산항목은 다음과 같습니다.
총 점수: 다른 모든 항목들의 점수를 더한 점수입니다. 이 점수로 승패가 결정됩니다.
생존 점수: 각 라운드에서 다른 로봇이 파괴될 때 마다 살아있는 모든 로봇은 50점을 얻습니다.
생존 보너스: 각 라운드에서 마지막으로 살아남은 로봇은 그 라운드에서 파괴된 로봇 수 * 10점을 얻습니다.
대포 점수: 대포를 발사해 다른 로봇을 명중시킬때 로봇에게 입힌 피해만큼 점수를 얻습니다.
대포 보너스: 대포를 발사해 다른 로봇을 명중시켜, 그 로봇이 파괴되면 해당 라운드에서 그 로봇에게 입힌 피해 * 0.2 만큼 점수를 얻습니다.
충돌 점수: 다른 로봇에게 일방적으로 접근하여 충돌을 발생시키면 충돌로 입힌 피해 * 2 만큼 점수를 얻습니다.
충돌 보너스 다른 로봇에게 일방적으로 접근하여 충돌을 발생시켜, 그 로봇이 파괴되면 해당 라운드에서 그 로봇에게 입힌 피해 * 0.3 만큼 점수를 얻습니다.
해당 문제가 포함된 시험에서 얻을 수 있는 점수의 비율은 시험 점수 * 나의 총 점수 / 적 로봇중 가장 높은 순위의 로봇의 총점수 입니다. 즉, 위의 표대로라면 30점을 얻을 수 있는 시험에서 30 * 50/110 = 약 13.63점을 얻게됩니다.
this.debug(내용);
위 함수를 통해 하단 터미널에서 확인하고 싶은 내용을 출력할 수 있습니다. 문자, 숫자, boolean만 출력 가능합니다.
아래와 같이 스크래치를 이용하여 로보코드 문제를 작성할 수 있습니다.