Build Marine! and Attack!
์ด ์ฅ์์ ๋ฐฐ์ธ๊ฒ
์์์ด ๋๋ฉด, supply depot์ ์ง๊ณ , Barrack์ ์ง์ ๋ค, ๊ณต๊ฒฉ๊ฐ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๊ฒ ์ต๋๋ค.
Let's Start!
์ฌ์ค, ์ํ๋ผ์ด ๋ํ ํ๋ ์ง๊ฒํ๋๋ฐ๋ ์๊ทผํ ์๊ฐํด๋ณผ ๊ฒ๋ค์ด ๋ง์ต๋๋ค.
์ํ๋ผ์ด๋ํ์ ์ง๋๋ค.
์ธ๊ตฌ์ ์ฒดํฌ!
์ง๊ธ ์ํ๋ผ์ด๋ํ์ ์ง๊ณ ์๋์ง ํ์ธ!
SCV๊ฐ ๋ ธ๋์ง ์ฒดํฌ!
์์ ํ์ธ!(์ง๊ธ ๊ฐ๋ฅํํ๋์ธ์งํ์ธ!)
SCV๋ฅผ ์ ํํด ์ ๋นํ ์์น์ ์ง๊ธฐ ์์ํด์ผํฉ๋๋ค.
์ด๋ ๊ฒ rule-based๊ฐ ์ด๋ ต์ต๋๋ค ใ ใ . ํ๊บผ๋ฒ์ ์ ์ฉํ ์คํฌ๋ฆฝํธ๋ฅผ ๋ณด๊ณ ๋น ๋ฅด๊ฒ ๋์ด๊ฐ๋๋กํ์ฃ !
class Agent(base_agent.BaseAgent):
def unit_type_is_selected(self,obs,unit_type):
if (len(obs.observation.single_select) > 0 and obs.observation.single_select[0].unit_type == unit_type):
return True
elif (len(obs.observation.multi_select) > 0 and obs.observation.multi_select[0].unit_type == unit_type):
return True
else :
return False
def can_do(self,obs,action_id):
return action_id in obs.observation.available_actions
def selected_units_idle_check(self,obs):
selected_units = [x for x in obs.observation.feature_units if x.is_selected == 1]
if len(selected_units) == 0 :
print("not selected!")
return True
else:
selected_unit = [x.order_length for x in selected_units]
if sum(selected_unit) > 0:
return False
return True
def food_check(self,obs):
food_enough = obs.observation.player.food_cap - obs.observation.player.food_used
if food_enough > 4:
return False
else:
return True
def build_building_now(self,obs,building_id):
units = [unit.build_progress for unit in obs.observation.feature_units if \
(unit.unit_type == building_id)]
if len(units) > 0 :
return True
else:
return False
def step(self,obs):
super(Agent,self).step(obs)
if obs.first():
player_y, player_x = (obs.observation.feature_minimap.player_relative == PLAYER_SELF).nonzero()
xmean = player_x.mean()
ymean = player_y.mean()
if xmean <= MINIMAP_SIZE/2 and ymean <= MINIMAP_SIZE/2:
self.scout_coordinates = (40, 40)
else:
self.scout_coordinates = (20, 20)
scvs = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.SCV]
if len(scvs) > 0 and not self.unit_type_is_selected(obs,units.Terran.SCV):
#์ ๋ ์
๋
scv = scvs[0]
return actions.FUNCTIONS.select_point("select",(scv.x,scv.y))
elif self.can_do(obs,BUILD_SUPPLYDEPOT) and \
self.food_check(obs) and \
(not self.build_building_now(obs,units.Terran.SupplyDepot))\
and [x.order_id_0 for x in obs.observation.feature_units if x.is_selected == 1][0] == \
HARVEST_GATHER_SCV_UNIT:
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_SUPPLYDEPOT,[NOT_QUEUED,[x,y]])
elif self.can_do(obs,BUILD_BARRACKS) and \
(not self.build_building_now(obs,units.Terran.Barracks)) and \
(len([x for x in obs.observation.feature_units if x.unit_type == units.Terran.Barracks]) == 0) and \
self.selected_units_idle_check(obs):
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_BARRACKS,[NOT_QUEUED,[x,y]])
return actions.FUNCTIONS.no_op()
๋ง์ฝ ์ํ๋ผ์ด๋ํ์ ์ง๋ค๊ฐ ํ๋ฉด๋ฐ์ผ๋ก ๋ฒ์ด๋๋ฉด ์ด๋ฌํ rule-based Agent๋ ์ง๊ณ ์๋ ์ํ๋ผ์ด ๋ํ์ ๋ํ ์ ๋ณด๋ ์ป์ ์๊ฐ ์์ด ์ธ๊ตฌ์๊ฐ ๋งํ์ง ์์๋๋ผ๋ ์ ์ํ๋ผ์ด๋ํ์ ์ง์ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค!(์์์ด ๋ง๋ค๋ฉด APM์ด 300์ด๋๊น ์ ์ ๋ค๋ฅธํ๋ฉด์ผ๋ก ํ๋์ํ์๋ค๊ฐ ๋ช์ด๋ง์ ๋ชจ๋ ์ผ๊พผ์ด ์ํ๋ผ์ด ๋ํ์ ์ง๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.)
์ด๋ฒ์ ๋ฐฐ๋ญ์ ์ง์ด๋ณด๊ฒ ์ต๋๋ค!
if (len([x for x in obs.observation.feature_units if x.unit_type == units.Terran.Barracks]) == 1)\
and self.can_do(obs,TRAIN_MARINE_QUICK):
return actions.FunctionCall(TRAIN_MARINE_QUICK,[NOT_QUEUED])
์ด ์คํฌ๋ฆฝํธ๋ ์คํฌ๋ฆฐ์ ๋ฐฐ๋ญ์ด ๋ณด์ด์ง์์ผ๋ฉด ์์ฅ์ฐฝ ์ง์ด์ง๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค..ใ ใ
์ด์ ๋ง๋ฆฐ์ ๊ณ์ํด์ ๋ฝ์๋ณด๊ฒ ์ต๋๋ค.
def step(self,obs):
super(Agent,self).step(obs)
if obs.first():
player_y, player_x = (obs.observation.feature_minimap.player_relative == PLAYER_SELF).nonzero()
xmean = player_x.mean()
ymean = player_y.mean()
if xmean <= MINIMAP_SIZE/2 and ymean <= MINIMAP_SIZE/2:
self.scout_coordinates = (40, 40)
else:
self.scout_coordinates = (20, 20)
scvs = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.SCV]
brracks = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.Barracks]
if len(scvs) > 0 and len(brracks) == 0 and not self.unit_type_is_selected(obs,units.Terran.SCV):
#์ ๋ ์
๋
scv = scvs[0]
return actions.FUNCTIONS.select_point("select",(scv.x,scv.y))
elif self.can_do(obs,BUILD_SUPPLYDEPOT) and \
self.food_check(obs) and \
(not self.build_building_now(obs,units.Terran.SupplyDepot))\
and [x.order_id_0 for x in obs.observation.feature_units if x.is_selected == 1][0] == \
HARVEST_GATHER_SCV_UNIT:
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_SUPPLYDEPOT,[NOT_QUEUED,[x,y]])
elif self.can_do(obs,BUILD_BARRACKS) and \
(not self.build_building_now(obs,units.Terran.Barracks)) and \
(len([x for x in obs.observation.feature_units if x.unit_type == units.Terran.Barracks]) == 0) and \
self.selected_units_idle_check(obs):
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_BARRACKS,[NOT_QUEUED,[x,y]])
elif len(brracks) == 1 and not self.unit_type_is_selected(obs,units.Terran.Barracks):
brrack = brracks[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_MARINE_QUICK):
return actions.FunctionCall(TRAIN_MARINE_QUICK,[NOT_QUEUED])
return actions.FUNCTIONS.no_op()
์ฒ์์ SCV๋ฅผ์ ํํ ๋, ๋ฐฐ๋ญ๋ ์ง์ผ๋ด์ผํ๊ธฐ๋๋ฌธ์ ์ ์ฒด์ ์ฝ๋๋ฅผ ๋ฃ์ด ๋ฐ๋์ ์ ์ฐพ๋๋ก ํ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ๋๋ฉด ๊ณ์ ๋ง๋ฆฐ์ ๋ฝ์ ์ ์๊ฒ ๋์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ ์ ๊ธฐ์ง๋ก ๊ณต๊ฒฉ์ ๋ณด๋ด๊ฒ ์ต๋๋ค.
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_BARRACKS = 42
TRAIN_MARINE_QUICK = 477
HARVEST_GATHER_SCV_UNIT = 359
TRAIN_MARINE_QUICK = 477
NOT_QUEUED = [0]
players = [sc2_env.Agent(sc2_env.Race.terran),\
sc2_env.Bot(sc2_env.Race.zerg,\
sc2_env.Difficulty.very_easy)]
interface = features.AgentInterfaceFormat(\
feature_dimensions = features.Dimensions(\
screen = SCREEN_SIZE, minimap = MINIMAP_SIZE), use_feature_units = True)
class Agent(base_agent.BaseAgent):
def unit_type_is_selected(self,obs,unit_type):
if (len(obs.observation.single_select) > 0 and obs.observation.single_select[0].unit_type == unit_type):
return True
elif (len(obs.observation.multi_select) > 0 and obs.observation.multi_select[0].unit_type == unit_type):
return True
else :
return False
def can_do(self,obs,action_id):
return action_id in obs.observation.available_actions
def selected_units_idle_check(self,obs):
selected_units = [x for x in obs.observation.feature_units if x.is_selected == 1]
if len(selected_units) == 0 :
print("not selected!")
return True
else:
selected_unit = [x.order_length for x in selected_units]
if sum(selected_unit) > 0:
return False
return True
def food_check(self,obs):
food_enough = obs.observation.player.food_cap - obs.observation.player.food_used
if food_enough > 4:
return False
else:
return True
def build_building_now(self,obs,building_id):
units = [unit.build_progress for unit in obs.observation.feature_units if \
(unit.unit_type == building_id)]
if len(units) > 0 :
return True
else:
return False
def step(self,obs):
super(Agent,self).step(obs)
if obs.first():
player_y, player_x = (obs.observation.feature_minimap.player_relative == PLAYER_SELF).nonzero()
xmean = player_x.mean()
ymean = player_y.mean()
if xmean <= MINIMAP_SIZE/2 and ymean <= MINIMAP_SIZE/2:
self.attack_coordinates = (40, 40)
else:
self.attack_coordinates = (20, 20)
scvs = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.SCV]
brracks = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.Barracks]
if len(scvs) > 0 and len(brracks) == 0 and not self.unit_type_is_selected(obs,units.Terran.SCV):
#์ ๋ ์
๋
scv = scvs[0]
return actions.FUNCTIONS.select_point("select",(scv.x,scv.y))
elif self.can_do(obs,BUILD_SUPPLYDEPOT) and \
self.food_check(obs) and \
(not self.build_building_now(obs,units.Terran.SupplyDepot))\
and [x.order_id_0 for x in obs.observation.feature_units if x.is_selected == 1][0] == \
HARVEST_GATHER_SCV_UNIT:
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_SUPPLYDEPOT,[NOT_QUEUED,[x,y]])
elif self.can_do(obs,BUILD_BARRACKS) and \
(not self.build_building_now(obs,units.Terran.Barracks)) and \
(len([x for x in obs.observation.feature_units if x.unit_type == units.Terran.Barracks]) == 0) and \
self.selected_units_idle_check(obs):
x,y = random.randint(0,SCREEN_SIZE),random.randint(0,SCREEN_SIZE)
return actions.FunctionCall(BUILD_BARRACKS,[NOT_QUEUED,[x,y]])
elif len(brracks) == 1 and not self.unit_type_is_selected(obs,units.Terran.Barracks) and not self.unit_type_is_selected(obs,units.Terran.Marine):
brrack = brracks[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_MARINE_QUICK):
return actions.FunctionCall(TRAIN_MARINE_QUICK,[NOT_QUEUED])
elif len([x for x in obs.observation.feature_units if x.unit_type == units.Terran.Marine]) > 3\
and not self.unit_type_is_selected(obs,units.Terran.Marine):
marines = [unit for unit in obs.observation.feature_units if unit.unit_type == units.Terran.Marine]
return actions.FUNCTIONS.select_point("select_all_type",(marines[0].x,marines[0].y))
elif self.unit_type_is_selected(obs,units.Terran.Marine) and self.selected_units_idle_check(obs):
x,y = self.attack_coordinates
return actions.FunctionCall(MOVE_MINIMAP,[NOT_QUEUED,[x,y]])
return actions.FUNCTIONS.no_op()
def main(args):
agent = Agent()
try:
with sc2_env.SC2Env(map_name = MAPNAME, players = players,\
agent_interface_format = interface,\
step_mul = APM, game_steps_per_episode = UNLIMIT,\
visualize = VISUALIZE, realtime = REALTIME) as env:
agent.setup(env.observation_spec(), env.action_spec())
timestep = env.reset()
agent.reset()
while True:
step_actions = [agent.step(timestep[0])]
if timestep[0].last():
break
timestep = env.step(step_actions)
except KeyboardInterrupt:
pass
app.run(main)
๋ง๋ฆฐ ๋ค๊ธฐ๊ฐ ๋๋ฒ ๋๋ฒ ๊ฑธ์ด๊ฐ ์ ์ ๊ณต๊ฒฉํ๋ ๋ณด์ค์ ์์ ๊ฒ์ ๋๋ค!
Last updated
Was this helpful?