728x90
이번 글은 내전용 봇 개발의 마지막 글이다.
구현하고자하는 기능은 반드시 필요한 일꾼과 인구수를 계속 보충하는 기능을 구현하고자한다.
// 일꾼 계속 추가 생산
public void executeWorkerTraining() {
// InitialBuildOrder 진행중에는 아무것도 하지 않습니다
if (!isInitialBuildOrderFinished) {
return;
}
if (MyBotModule.Broodwar.self().minerals() >= 50) {
// workerCount = 현재 일꾼 수 + 생산중인 일꾼 수
int workerCount = MyBotModule.Broodwar.self().allUnitCount(InformationManager.Instance().getWorkerType());
if (MyBotModule.Broodwar.self().getRace() == Race.Zerg) {
for (Unit unit : MyBotModule.Broodwar.self().getUnits()) {
if (unit.getType() == UnitType.Zerg_Egg) {
// Zerg_Egg 에게 morph 명령을 내리면 isMorphing = true,
// isBeingConstructed = true, isConstructing = true 가 된다
// Zerg_Egg 가 다른 유닛으로 바뀌면서 새로 만들어진 유닛은 잠시
// isBeingConstructed = true, isConstructing = true 가
// 되었다가,
if (unit.isMorphing() && unit.getBuildType() == UnitType.Zerg_Drone) {
workerCount++;
}
}
}
}
else {
for (Unit unit : MyBotModule.Broodwar.self().getUnits()) {
if (unit.getType().isResourceDepot()) {
if (unit.isTraining()) {
workerCount += unit.getTrainingQueue().size();
}
}
}
}
// 최소 12마리, 최대 40마리
if (workerCount <= 12 * InformationManager.mapSelfMainBuilding.size() && workerCount <= 40) {
for (Unit unit : MyBotModule.Broodwar.self().getUnits()) {
if (unit.getType().isResourceDepot()) {
if (!unit.isTraining() || unit.getLarva().size() > 0) {
// 빌드큐에 일꾼 생산이 1개는 있도록 한다
if (BuildManager.Instance().buildQueue.getItemCount(InformationManager.Instance().getWorkerType(), null) == 0) {
// std.cout + "worker enqueue" + std.endl;
BuildManager.Instance().buildQueue.queueAsLowestPriority(new MetaType(InformationManager.Instance().getWorkerType()), false);
}
}
}
}
}
}
}
코드 해석은 주석으로도 충분히 해석이 가능하나, 설명을 하자면
빌드큐에 반드시 일꾼을 생성하도록하였다.
위 코드는 저그이기에 최대 값을 40으로 하였으나, 프로토스나 테란일 때에는 최대 60으로 하는 것이 좋으며, 동시에
위 코드와 달리 작성해가면서 여러 테스트를 거쳐 최적의 코드를 찾으시길 바란다.
// 인구수 자동 생산
private void supplyManagement() {
if (!isInitialBuildOrderFinished)
return;
if (MyBotModule.Broodwar.self().supplyTotal() <= 400) {
// 서플라이가 다 꽉찼을때 새 서플라이를 지으면 지연이 많이 일어나므로, supplyMargin (게임에서의 서플라이 마진 값의 2배)만큼
// 부족해지면 새 서플라이를 짓도록 한다
// 이렇게 값을 정해놓으면, 게임 초반부에는 서플라이를 너무 일찍 짓고, 게임 후반부에는 서플라이를 너무 늦게 짓게 된다
int supplyMargin = 12;
// currentSupplyShortage 를 계산한다
int currentSupplyShortage = MyBotModule.Broodwar.self().supplyUsed() + supplyMargin - MyBotModule.Broodwar.self().supplyTotal();
if (currentSupplyShortage > 0) {
// 생산 / 건설 중인 supply를 센다
int onBuildingSupplyCount = 0;
// 저그 종족인 경우, 생산중인 Zerg_Overlord (Zerg_Egg) 를 센다. Hatchery 등 건물은 세지 않는다
if (MyBotModule.Broodwar.self().getRace() == Race.Zerg) {
for (Unit unit : MyBotModule.Broodwar.self().getUnits()) {
if (unit.getType() == UnitType.Zerg_Egg && unit.getBuildType() == UnitType.Zerg_Overlord) {
onBuildingSupplyCount += UnitType.Zerg_Overlord.supplyProvided();
}
// 갓태어난 Overlord 는 아직 SupplyTotal 에 반영안되어서, 추가 카운트를 해줘야함
if (unit.getType() == UnitType.Zerg_Overlord && unit.isConstructing()) {
onBuildingSupplyCount += UnitType.Zerg_Overlord.supplyProvided();
}
}
}
// 저그 종족이 아닌 경우, 건설중인 Protoss_Pylon, Terran_Supply_Depot 를 센다. Nexus, Command
// Center 등 건물은 세지 않는다
else {
onBuildingSupplyCount += ConstructionManager.Instance().getConstructionQueueItemCount(InformationManager.Instance().getBasicSupplyProviderUnitType(), null) * InformationManager.Instance().getBasicSupplyProviderUnitType().supplyProvided();
}
if (currentSupplyShortage > onBuildingSupplyCount) {
// BuildQueue 최상단에 SupplyProvider 가 있지 않으면 enqueue 한다
boolean isToEnqueue = true;
if (!BuildManager.Instance().buildQueue.isEmpty()) {
BuildOrderItem currentItem = BuildManager.Instance().buildQueue.getHighestPriorityItem();
if (currentItem.metaType.isUnit() && currentItem.metaType.getUnitType() == InformationManager.Instance().getBasicSupplyProviderUnitType()) {
isToEnqueue = false;
}
}
if (isToEnqueue) {
BuildManager.Instance().buildQueue.queueAsHighestPriority(UnitType.Zerg_Overlord, BuildOrderItem.SeedPositionStrategy.MainBaseLocation, true);
}
}
}
}
}
위 코드는 인구수를 자동으로 채워주는 데 인구수가 12(인게임내에서는 6) 남았을 때 인구수를 채울 수 있는 Unit을 큐에 넣는다.
필자가 코드 전체를 작성할 수 없기에 개인적으로 꼭 필요하다 느끼는 것만 작성하였다.
추후 내전이 끝난 이후 작성할 15번째 글의 필자의 깃헙 주소를 참고하길 바라며, 마지막으로 리플레이 파일를 남겨두겠다. (내전은 8월 말 입니다.)
여러 아쉬운 점들이 더러 있고, 저프전이 가장 아쉬운 것 같다.
(초반 러쉬는 막으나, 중후반전에서 본진까지 뚫는것이 너무 아쉽다)
'스타봇' 카테고리의 다른 글
스타크래프트 봇 동아리. 봇 모듈 만들기 (#0) (0) | 2021.09.13 |
---|---|
스타크래프트 봇 동아리, 내전용 봇 개발 (#15) (0) | 2021.09.13 |
스타크래프트 봇 동아리, 내전용 봇 개발 (#13) (0) | 2021.07.24 |
스타크래프트 봇 동아리, 내전용 봇 개발 (#12) | 디파일러 파트 (2) (0) | 2021.07.23 |
스타크래프트 봇 동아리, 내전용 봇 개발 (#11) | 디파일러 파트 (1) (0) | 2021.07.22 |