Welcome to pysc2

์ด ์žฅ์—์„œ ๋ฐฐ์šธ ๊ฒƒ

์ด ์žฅ์—์„œ๋Š” ์•„์ฃผ ๊ธฐ์ดˆ์ ์ธ Pysc2๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฒ•์„ ์•Œ์•„๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋„๊ตฌ๊ฐ€ ๊ทธ๋ ‡๋“ฏ, ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„  ๊ทธ๊ฒƒ์„ ์•Œ์•„๊ฐ€๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•Œ์•„๊ฐ€๋Š” ๊ณผ์ •์€ ํ•ญ์ƒ ๋‚ฏ์„ค์ง€๋งŒ ์ธ๋‚ด์‹ฌ์„ ๊ฐ€์ง€๊ณ  ํฅ๋ฏธ๋ฅผ ๋ถ™์ธ๋‹ค๋ฉด ์‰ฝ๊ฒŒ ๋„˜์–ด์˜ค์‹ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ Basic about pysc2์—์„œ ๊ณผํ•˜๊ฒŒ ๋“ค์–ด๊ฐ€๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”๋ฐ(์ƒ๊ฐ๋ณด๋‹ค ๋‹ค๋ฃจ๋Š”๊ฒŒ ๊นŒ๋‹ค๋กœ์› ์–ด์„œ) ์ดํ•ด๊ฐ€ ์•ˆ๋˜๊ฑฐ๋‚˜ ๋„ˆ๋ฌด ๊นŠ๋‹ค ์‹ถ์œผ๋ฉด ๊ณผ๊ฐํ•˜๊ฒŒ ๋ฒ„๋ฆฌ์…”๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

Pysc2๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ ๋‘๋ฒˆ์œผ๋กœ ๋‚˜๋ˆ„์—ˆ๋Š”๋ฐ, ์ด ์ฒซ๋ฒˆ์งธ pysc2 handling ์žฅ์—์„œ ๋ฐฐ์šธ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ธฐ๋ณธ์ ์ธ ํ™˜๊ฒฝ ์„ธํŒ… ๋ฐ ํ™˜๊ฒฝ ๋™์ž‘ ์›๋ฆฌ ์ดํ•ด

    • Simple64 ๋งต์—์„œ ํ…Œ๋ž€ ์ข…์กฑ์„ ์ด์šฉํ•ด rule base๋กœ ๊ฑด๋ฌผ์„ ์ง“๊ณ  ์•„์ฃผ์‰ฌ์›€ ๋ชจ๋“œ์˜ ๋ด‡์„ ์ด๊ธฐ๋Š” ๊ฒƒ ๊นŒ์ง€๊ฐ€ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

  • Mini game ์„ ์œ„ํ•œ ํ™˜๊ฒฝ ์„ค์ •

    • FindAndDefeatZerglings ๋งต์„ ํ•™์Šตํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ดˆ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Pysc2 ๋ฅผ ํ†ตํ•œ ๊ธฐ์ดˆ ํ™˜๊ฒฝ ์„ธํŒ…

๋จผ์ € ํ•ด์•ผํ•  ๊ฒƒ์€ pysc2์—์„œ environment๋ฅผ ์„ธํŒ…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ pysc2.env๋ฅผ import ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

from pysc2.env import sc2_env

์ด๋ฅผ ๊ฐ€์ง€๊ณ , ๋งต, ํ”Œ๋ ˆ์ด์–ด์„ธํŒ…(๋งŒ๋“ค์–ด์ง„ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ™˜๊ฒฝ์— ์˜ฌ๋ ค๋†“๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ํ”Œ๋ ˆ์ด์–ด๋Š” base_agent๋ฅผ ์ƒ์†๋ฐ›์•„ ํด๋ž˜์Šค๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.), ์ธํ„ฐํŽ˜์ด์Šค ํฌ๊ธฐ, ์‹œ๊ฐํ™” ์—ฌ๋ถ€, realtime ์—ฌ๋ถ€, APM ์„ค์ •๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜๋‚˜ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋ณด๋ฉด, Map์€ tutorial์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ๋“ฑ์žฅํ•˜๋Š” Simple64๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

MAPNAME = 'Simple64'

ํ”Œ๋ ˆ์ด์–ด๋Š” ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ๋งŒ๋“ค Agent๋ฅผ ๋„ฃ์„ ๊ฒƒ์ด๊ณ , ํ•˜๋‚˜๋Š” Bot์„ ๋„ฃ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ…Œ๋ž€์ข…์กฑ์„, ๋ด‡์€ ์ €๊ทธ๋ฅผ ๋„ฃ๊ณ  ์•„์ฃผ ์‰ฌ์šด ๋‚œ์ด๋„๋ฅผ ์„ ํƒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

players = [sc2_env.Agent(sc2_env.Race.terran),\
           sc2_env.Bot(sc2_env.Race.zerg,\
           sc2_env.Difficulty.very_easy)]

interface๋Š” map์„ ๋ช‡๋“ฑ๋ถ„ํ• ์ง€, minimap์„ ๋ช‡๋“ฑ๋ถ„ํ• ์ง€ ์ •ํ•ฉ๋‹ˆ๋‹ค. int๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ์ •์‚ฌ๊ฐํ˜•์˜ interface๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ use_feature_units๋ฅผ ํ†ตํ•ด ๋ณด์ด๋Š” unit์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ง์ ‘ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import pysc2.lib import features
SCREEN_SIZE = 84
MINIMAP_SIZE = 64
 
interface = features.AgentInterfaceFormat(\
                feature_dimensions = features.Dimensions(\
                screen = SCREEN_SIZE, minimap = MINIMAP_SIZE), use_feature_units = True)
                

APM, max episode length๋ฅผ unlimit์„ ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’ ์„ค์ •๊ณผ, visualize ์„ค์ •, realtime ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

APM = 300
APM = int(APM / 18.75)
UNLIMIT = 0
VISUALIZE = True
REALTIME = True

์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ๊ฐ€์ง€๊ณ , sc2_env๋‚ด์˜ SC2Env๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

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:
                pass

environment๋ฅผ ์—ด์–ด๋†“๊ณ  ํ™˜๊ฒฝ์„ ์ปจํŠธํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์œ ์ €๊ฐ€ Controlํ•  Agent๋ฅผ ๋งŒ๋“ค๋ฉด,

from pysc2.agents import base_agent
from pysc2.lib import actions

class Agent(base_agent.BaseAgent):
    def step(self,obs):
        super(Agent,self).step(obs)
        return actions.FUNCTIONS.no_op()
agent = Agent()

๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. Agent๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด base_agent๋ฅผ importํ•˜๊ณ , Agent๊ฐ€ ํ–‰๋™ํ•  ์ˆ˜ ์žˆ๋Š” ํ–‰๋™๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด actions๋ฅผ importํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋งŒ๋“ , ์•„๋ฌด action๋„ ์ทจํ•˜์ง€ ์•Š๋Š” agent๋ฅผ ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Agent๋Š” environment์—์„œ ์„ค์ •๋œ ํ‹ฑ๋งˆ๋‹ค step์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ, ์ด๋•Œ action๋“ค์„ ๋‹ด๊ณ ์žˆ๋Š” actions๋ฅผ ๋ถˆ๋Ÿฌ์™€ no_op()์„ ์‹คํ–‰์‹œ์ผœ ์•„๋ฌด ํ–‰๋™๋„ ์•ˆํ•˜๋„๋ก Agent๋ฅผ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์œ„์—์„œ ๋งŒ๋“  ๊ฒƒ๋“ค์„ ์ข…ํ•ฉํ•˜

from pysc2.env import sc2_env
from pysc2.lib import features 
from pysc2.agents import base_agent
from pysc2.lib import actions

from absl import app

MAPNAME = 'Simple64'
APM = 300
APM = int(APM / 18.75)
UNLIMIT = 0
VISUALIZE = True
REALTIME = True

SCREEN_SIZE = 84
MINIMAP_SIZE = 64

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 step(self,obs):
        super(Agent,self).step(obs)
        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)

์œ„์™€ ๊ฐ™์ด ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์ด์ œ agent์™€ environment๋ฅผ setup๊ณผ reset์„ ํ•˜๋ฉด ์ค€๋น„๊ฐ€ ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

agent.setup(env.observation_spec(), env.action_spec())
timestep = env.reset()
agent.reset()

๊ฒŒ์ž„๋™์•ˆ while๋ฌธ์„ ๋Œ๋ฉฐ, agent์˜ step function์„ callํ•˜๋ฉด๋˜๋Š”๋ฐ, ์ด agent.step()์€ step์„ ํ†ตํ•ด ์–ป์€ ์ •๋ณด๋“ค์„ ๋‹ด๊ณ ์žˆ๊ณ , agent๋Š” environment์˜ observation์„ parameter๋กœ ๋ฐ›๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

while True:
    step_actions = [agent.step(timestep[0])]
    print(timestep[0])
    if timestep[0].last():
        break
    timestep = env.step(step_actions)

์ด์ œ ์ „์ฒด๋ฅผ ํ•œ๋ฒˆ ๊ตฌ์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

from pysc2.env import sc2_env
from pysc2.lib import features 
from pysc2.agents import base_agent
from pysc2.lib import actions

from absl import app

MAPNAME = 'Simple64'
APM = 300
APM = int(APM / 18.75)
UNLIMIT = 0
VISUALIZE = True
REALTIME = True

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 = 64, minimap = 16), use_feature_units = True)

class Agent(base_agent.BaseAgent):
    def step(self,obs):
        super(Agent,self).step(obs)
        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])]
                print(timestep[0])
                if timestep[0].last():
                    break
                timestep = env.step(step_actions)
    except KeyboardInterrupt:
        pass
app.run(main)

try except๋ฌธ๊ณผ absl์„ ํ†ตํ•œ app์‹คํ–‰๋งŒ ์ถ”๊ฐ€๋˜์—ˆ๊ณ  ์ „๋ถ€ ์œ„์—์„œ ํ™•์ธํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹คํ–‰๋˜์—ˆ๋‹ค๋ฉด ์ •์ƒ์ž…๋‹ˆ๋‹ค.

Last updated

Was this helpful?