728x90
지난 번에는 기본적으로 스타크래프트2 봇을 테스트를 해보았습니다.
이번에는 일꾼 생산 및 보급고 건설을 해볼 겁니다.
일단 일꾼 생산 같은 경우에는
onUnitIdle 메소드를 오버라이딩하여
일하는 유닛들을 가져옵니다.
UnitInPool 이라는 클래스가 어떤 클래스인지 그리고 어떤 방식으로 진행이 되어가는 지
잘 파악하지 못하였기때문에
원리를 제가 이해한 방식대로 한다면
UnitPool에 저장되고, UnitInPool에 인스턴스화된 것들을 가지고 오는 것
같습니다.
SCV 생산
@Override
public void onUnitIdle(UnitInPool unitInPool) {
Unit unit = unitInPool.unit(); // 아직도 이해 못함 원리를
switch ((Units) unit.getType()) {
case TERRAN_COMMAND_CENTER:
actions().unitCommand(unit, Abilities.TRAIN_SCV, false);
break;
default:
break;
}
}
일하지 않고 놀고 있는 유닛을 가져와서 해당 유닛이 CommandCenter이라면
TRAIN_SCV (SCV 생산)을 행동하는 것 같습니다.
보급고 건설
private boolean tryBuildSupplyDepot() {
if (observation().getFoodUsed() <= observation().getFoodCap() - 2) {
return false;
}
return tryBuildStructure(Abilities.BUILD_SUPPLY_DEPOT, Units.TERRAN_SCV);
}
먼저 인구수를 늘릴 필요가 있는 지부터 확인을 합니다.
전체 인구수를 가져오는 getFoodCap에서 2만큼을 뺀 값이
사용된 인구수보다 작다면 요구되지 않습니다.
bwapi는 2배수로 계산해야하는 데에 반해
Ocraft 같은 경우에는 굳이 그럴 필요가 없습니다.
private boolean tryBuildStructure(Abilities abilities, UnitType type) {
if (!observation().getUnits(Alliance.SELF, doesBuildWith(abilities)).isEmpty()) {
return false;
}
Optional<UnitInPool> unitInPool = getRandomUnit(type);
if (unitInPool.isPresent()) {
Unit unit = unitInPool.get().unit();
actions().unitCommand(
unit,
abilities,
unit.getPosition().toPoint2d().add(Point2d.of(getRandomScalar(), getRandomScalar()).mul(15f)),
false
);
return true;
}
else {
return false;
}
}
인구수 확장을 해야한다면
이미 보급고를 건설 중이라면 굳이 또 건설할 필요가 없기때문에
false를 반환합니다.
랜덤한 위치에서 SCV를 가져와서
해당 SCV에게 보급고 건설 명령을 하달합니다.
private Predicate<UnitInPool> doesBuildWith(Ability ability) {
return unitInPool -> unitInPool.unit()
.getOrders()
.stream()
.anyMatch(unitOrder -> ability.equals(unitOrder.getAbility()));
}
해당 행동을 수행 중인지를 파악합니다.
private Optional<UnitInPool> getRandomUnit(UnitType type) {
List<UnitInPool> units = observation().getUnits(Alliance.SELF, UnitInPool.isUnit(type));
return units.isEmpty()
? Optional.empty()
: Optional.of(units.get(ThreadLocalRandom.current().nextInt(units.size())));
}
랜덤한 유닛을 가져옵니다.
private float getRandomScalar() {
return ThreadLocalRandom.current().nextFloat() * 2 - 1;
}
랜덤한 숫자를 반합환니다.
이상입니다.
'스타크래프트2 봇' 카테고리의 다른 글
스타크래프트 2 봇 개발 일지-3(Ocraft) (0) | 2022.01.03 |
---|---|
스타크래프트 2 봇 개발 일지-2(Ocraft) (0) | 2022.01.03 |
스타크래프트 2 봇 개발 일지-1(Ocraft) (0) | 2022.01.01 |
스타크래프트 2 봇 개발 일지-0 (0) | 2021.12.31 |
압생트(Absinthe)봇 만들기 (#11) (0) | 2021.08.20 |