전체 글 200

압생트(Absinthe)봇 만들기 (#7)

이번에 구현하고자 하는 것은 차원관문 업그레이드입니다. 차원관문은 스2에서만 존재하는 특별한 기능 중 하나입니다.관문을 통하여 생산하는 유닛이고, 동력이 통하는 곳이라면 어디서든지 생산이 가능하게 만드는 기능입니다.또, 생산속도 역시 빨라집니다. 차원관문을 업그레이드 중이 아니고 인공제어소가 있다면 업그레이드하도록 하는 것이 로직입니다. async def warpgate_research(self): if ( self.structures(UnitTypeId.CYBERNETICSCORE).ready and self.can_afford(AbilityId.RESEARCH_WARPGATE) and self.already_pending_upgrade(UpgradeId.WARPGATERESEARCH) == 0 ): ..

압생트(Absinthe)봇 만들기 (#6)

이번에 구현하고자 하는 것은 시간 증폭입니다. 시간증폭은 건물에 적용하여 일정시간동안 빠르게 가동시키는 능력으로연결체에서 사용가능합니다.에너지는 50이 사용되지만 약 20초(보통 시간 기준으로는 28초입니다)정도 시간을 빠르게 흐르게 하는 능력입니다.초반에는 탐사정을 더욱 빠르게 생산가능하므로 연결체에게 사용하도록 하였습니다.추후 코드는 충분히 변경될 수 있습니다.(업그레이드등을 하여야할 때에는 빠르게 진행하는 것이 중요하기 때문입니다.) async def chrono(self): if self.structures(UnitTypeId.PYLON): nexus = self.townhalls.ready.random if ( self.structures(UnitTypeId.PYLON).amount > 0 ):..

압생트(Absinthe)봇 만들기 (#5)

이번에 구현하고자 하는 것은 유닛 생산입니다. 사실 유닛 생산하는 것과 공격하는 것까지 구현했다면 스타크래프트에서는 반은 완성했다고 생각하면 됩니다. 개인적으로 광전사들을 뽑기를 생각하였으나, 난이도 어려움을 이기기에서 광전사들로 만 하여 이기는 것은 꽤 어려움이 있을 것이라고 판단하였습니다.(물론 광전사의 돌진과 컨트롤들을 만들면 안 될 거야 없긴 하지만 귀찮으니까요) 그래서 어떤 유닛을 생산할지를 고민하다가 가장 적절한 유닛이 떠올랐습니다. 추적자입니다. 원거리 유닛이고 중장갑한테도 나름 큰 피해를 줄 수 있기 때문에 추적자만을 뽑도록 하였습니다.(귀차니즘이 위험한 이유) 로직도 대충 생각하는 데로 적어도 작동하는 데에는 큰 문제가 없습니다. 게이트가 있고, 게이트가 아무것도 생산 중이 아니라면 추적..

압생트(Absinthe)봇 만들기 (#4)

이번에 구현하고자 하는 것은 사이버네틱스 코어 (인공 제어소) 건설입니다. 테크를 진행하는 건물 중 하나이자, 스타크래프트 2에서 프로토스를 더 포크로 만들어준 기능을 업그레이드를 할 수 있는 건물입니다. 공중 업그레이드와 차원관문을 업그레이드할 수 있습니다. 간단한 로직을 세워봅시다. 먼저 인공 제어소는 수정탑과 관문이 있어야지만 건설 가능한 건물입니다. 역시 당연하게도 주변에 동력이 공급되어야지만 건설 가능합니다. 이를 토대로 한 코드가 아래와 같습니다. async def build_core(self): if self.structures(UnitTypeId.PYLON).ready: pylons = self.structures(UnitTypeId.PYLON).ready.random if self.str..

압생트(Absinthe)봇 만들기 (#3)

이번에 구현하고자 하는 것은 어시밀레이터(융화소) 건설입니다. 미네랄(광물) 외에도 스타크래프트에 존재하는 또 다른 자원이 하나 있습니다. 바로 '가스'입니다. 가스로 더 강력한 유닛을 생산하고 테크를 가는 데에 있어 필수입니다. 한 마디로 요약하자면, 가스 없이는 고급 테크를 가지 못하고, 고급 테크를 가지 못한다면 고급 유닛을 생산할 수 없다는 의미입니다. 간단한 로직부터 세워보자면 넥서스 가까이에 존재하는 두 간헐천에 건설하도록 하는 것이 목표입니다. 먼저 가스의 경우에는 어떠한 제약도 없습니다. 미리 먼저 어떤 건물이 있어야 건설된다거나 하는 조건이 없다는 의미입니다. 또, 연결체, 수정탑과 더불어 동력 없이 건설되는 건물 중 하나입니다. 위 로직대로 작성한 코드는 아래와 같습니다. async d..

압생트(Absinthe)봇 만들기 (#2)

이번에 구현하고자 하는 것은 게이트웨이(관문) 건설입니다. 공격 유닛을 생산하는 가장 기본적인 건물인 게이트웨이는 질럿(광전사), 파수기, 추적자, 사도 등 기본적인 유닛을 생산할 수 있는 건물입니다. 주변에 동력을 공급해주는 파일런(수정탑)이 있어야 합니다. 간단한 로직을 세워보자면 먼저 게이트웨이를 짓기 위해서는 넥서스(연결체)와 파일런(수정탑)이 각각 1개씩 있어야 건설할 수 있습니다. 또, 미네랄(광물)이 150이 요구되며, 해당 건물을 지을 프로브(탐사정)가 1기 요구됩니다. 건설 위치에는 반드시 동력이 공급되는 위치여야 합니다. 현재는 게이트웨이를 하나만 건설하도록 게이트웨이가 건설된 적이 없을 때에만 건설하도록 하였습니다. 위 로직대로 작성한 최종 코드는 이러합니다. async def bui..

압생트(Absinthe)봇 만들기 (#1)

이번에 구현하고자 하는 것은 파일런(수정탑) 건설입니다. 스타크래프트를 플레이했던 유저라면 파일런(수정탑)은 프로토스의 인구수를 늘려주는 동시에 넥서스를 비롯하여 에너지(정확히는 동력) 없이 지을 수 있는 유일한 건물로 주변에 에너지를 공급해주는 기능을 합니다. 그런 건물을 건설하도록 구현하겠습니다. 먼저 말하자면 PySC2와 달리 따로 일꾼을 선택하도록 구현할 필요 없이 건설한 요청 하면 알아서 API에서 처리하여, 실행하기 때문에 귀찮지 않다는 것을 참고해주길 바랍니다. 넥서스에서 가깝게 짓는 것이 낫기에 넥서스 중 하나를 선택하여 해당 위치 앞쪽으로 x값은 적군 쪽과 가까운 최적의 x값을 가져오되, y값은 10 정도만 이동한 위치에서 최적의 위치로 정합니다. nexus = self.townhalls..

압생트(Absinthe)봇 만들기 (#0)

다시금 스타크래프트 2 봇을 만들게 된 워커홀릭 개발자입니다. 저번에 너무 빨리 마무리를 지은 감이 있고, 저 역시 새로운 도전을 하고 어느 정도 목표를 이루고자 하는 마음이 있기에 새로 봇을 만들기로 하였습니다. 종족은 프로토스로 쉬운 종족을 택하였습니다. 먼저 가장 기본적인 틀은 필자의 깃허브를 참고하시길 바랍니다. eschampstudio/python-sc2-bot-template 을 참고하였습니다. 워낙에 정보를 찾기 어려운 PySC2를 사용하지 않고 정보가 많은 sc2를 사용하기로 하였습니다. 먼저 가장 기초적인 작업부터 구현을 하고자 합니다. 바로 프로브 생산입니다. 일꾼을 많이 생산하여, 그만큼 자원을 모아야하기에 가장 기초적인 작업입니다. 먼저 코딩을 하기 앞서 세팅부터 합시다. 세팅은 매..

스타크래프트2 인공지능 봇을 만들어보자 (#6)

이전까지 작성하였던 모든 코드를 적용시키고자한다. from pysc2.env import sc2_env from pysc2.agents import base_agent from pysc2.lib import actions,units,features import random from absl import app MAPNAME = 'Simple64' APM = 300 APM = int(APM / 18.75) UNLIMIT = 0 VISUALIZE = True REALTIME = True PLAYER_SELF =features.PlayerRelative.SELF SCREEN_SIZE = 84 MINIMAP_SIZE = 64 MOVE_MINIMAP = 332 BUILD_SUPPLYDEPOT = 91 BUILD_..

스타크래프트2 인공지능 봇을 만들어보자 (#5)

본격적인 공격 유닛인 마린(해병)을 생산해보고자 한다. barracks = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.Barracks] elif len(barracks) == 1 and not self.unit_type_is_selected(obs,units.Terran.Barracks): barrack = barracks[0] return actions.FUNCTIONS.select_point("select",(brrack.x,brrack.y)) elif self.unit_type_is_selected(obs,units.Terran.Barracks) and self.can_do(obs,TRAIN_MA..