티스토리 뷰
지난 번에는 개발 환경과 함께 간단하게 메시지를 화면에 출력하는 것을 했습니다. 이번에는 간단한 미네랄 채취를 하도록 하겠습니다.
우선 저번 코드가 너무 지저분하였기 때문에 조금 객체지향적으로 하기 위해 메인코드와 봇 클래스를 둘로 나누었습니다.
import bwapi.*;
public class MineralGatherBot extends DefaultBWListener {
private BWClient bwClient;
private Game game;
public void gameStart() {
bwClient = new BWClient(this);
bwClient.startGame();
}
@Override
public void onStart() {
game = bwClient.getGame();
}
@Override
public void onFrame() {
Player player = game.self();
game.drawTextScreen(20, 20, String.format("%s has %d minerals",
player.getName(), player.minerals()));
}
@Override
public void onUnitComplete(Unit unit) {
if (unit.getType().isWorker()) {
Unit closestMineral = null;
int closestDistance = Integer.MAX_VALUE;
for (Unit mineral : game.getMinerals()) {
int distance = unit.getDistance(mineral);
if (distance < closestDistance) {
closestMineral = mineral;
closestDistance = distance;
}
}
unit.gather(closestMineral); // Gather the closest mineral
}
}
}
봇 코드는 위와 같습니다. 여기서 새로운 BWAPI 이벤트를 볼 수 있습니다. onUnitComplete라는 이벤트입니다.
해당 이벤트는 유닛(중립, 적, 아군 할 거 없이 모든 유닛을 가르킵니다. 건물과 마법 역시 유닛 취급합니다.)이 완전히 생성되었을 때 발생하는 이벤트입니다. 예를 들면 SCV(테란 측, 일꾼)이 완전히 생성되어 커맨드 센터(테란 측, 건물)에서 나온 순간에 onUnitComplete 이벤트가 발생합니다. 해당 이벤트가 발생하면 추가적으로 어떻게 처리할 것인지를 작성하면 됩니다. 해당 이벤트가 발생하면 미네랄을 채취하도록 하였는 데, 이 로직은 다음과 같습니다.
- 현재 완전히 생성된 유닛의 종류가 일꾼인가?
- 일꾼이라면 현재 인게임에 존재하는 모든 미네랄 중 가장 가까운 미네랄을 지정한다.
- 해당 미네랄을 채취 명령한다.
그리고 Player라는 클래스가 존재하는 데, 해당 클래스는 크게 3가지 부류가 존재합니다. 본인, 적군, 중립으로 구분됩니다.
실행을 해보면 다음과 같이 나오게 됩니다.
하지만 위 코드는 작동은 하나 다음과 같은 문제점들이 있습니다.
- 한 미네랄 당 일꾼은 최대 2기까지 밖에 채취하지 못한다. 하지만 많은 일꾼들이 단 하나의 가장 가까운 미네랄을 채취하여 딜레이가 다소 존재한다.
- 일꾼을 강제로 다른 곳으로 이동한다면 본진 근처가 아닌 현재 가장 가까운 미네랄을 채취한다.
이 두 가지를 해결하는 것은 다음 글에 다루도록 하겠습니다.
'스타크래프트 봇' 카테고리의 다른 글
[스타크래프트 봇] 스타크래프트 봇을 자바로 개발해보자 (3) (0) | 2022.07.30 |
---|---|
[스타크래프트 봇] 스타크래프트 봇을 자바로 개발해보자 (2) (0) | 2022.07.23 |
[스타크래프트 봇] 스타크래프트 봇을 자바로 개발해보자 (0) (0) | 2022.07.09 |
댓글