Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ModuleNotFoundError: No module named 'sc2' #188

Open
Douilol opened this issue Dec 22, 2023 · 2 comments
Open

ModuleNotFoundError: No module named 'sc2' #188

Douilol opened this issue Dec 22, 2023 · 2 comments
Labels
question Further information is requested

Comments

@Douilol
Copy link

Douilol commented Dec 22, 2023

For some reason, in this code, the modules sc2 is not found:

import sc2
from sc2 import maps
from sc2.bot_ai import BotAI
from sc2.data import Difficulty, Race
from sc2.ids.ability_id import AbilityId
from sc2.ids.buff_id import BuffId
from sc2.ids.unit_typeid import UnitTypeId
from sc2.main import run_game
from sc2.player import Bot, Computer
import random
import cv2
import math
import numpy as np
import sys
import pickle
import time

SAVE_REPLAY = True

total_steps = 10000
steps_for_pun = np.linspace(0, 1, total_steps)
step_punishment = ((np.exp(steps_for_pun**3)/10) - 0.1)*10

class IncrediBot(BotAI): # inhereits from BotAI (part of BurnySC2)
async def on_step(self, iteration: int): # on_step is a method that is called every step of the game.
no_action = True
while no_action:
try:
with open('state_rwd_action.pkl', 'rb') as f:
state_rwd_action = pickle.load(f)

                if state_rwd_action['action'] is None:
                    #print("No action yet")
                    no_action = True
                else:
                    #print("Action found")
                    no_action = False
        except:
            pass


    await self.distribute_workers() # put idle workers back to work

    action = state_rwd_action['action']
    '''
    0: expand (ie: move to next spot, or build to 16 (minerals)+3 assemblers+3)
    1: build stargate (or up to one) (evenly)
    2: build voidray (evenly)
    3: send scout (evenly/random/closest to enemy?)
    4: attack (known buildings, units, then enemy base, just go in logical order.)
    5: voidray flee (back to base)
    '''
    # 0: expand (ie: move to next spot, or build to 16 (minerals)+3 assemblers+3)
    if action == 0:
        try:
            found_something = False
            if self.supply_left < 4:
                # build pylons. 
                if self.already_pending(UnitTypeId.PYLON) == 0:
                    if self.can_afford(UnitTypeId.PYLON):
                        await self.build(UnitTypeId.PYLON, near=random.choice(self.townhalls))
                        found_something = True

            if not found_something:

                for nexus in self.townhalls:
                    # get worker count for this nexus:
                    worker_count = len(self.workers.closer_than(10, nexus))
                    if worker_count < 22: # 16+3+3
                        if nexus.is_idle and self.can_afford(UnitTypeId.PROBE):
                            nexus.train(UnitTypeId.PROBE)
                            found_something = True

                    # have we built enough assimilators?
                    # find vespene geysers
                    for geyser in self.vespene_geyser.closer_than(10, nexus):
                        # build assimilator if there isn't one already:
                        if not self.can_afford(UnitTypeId.ASSIMILATOR):
                            break
                        if not self.structures(UnitTypeId.ASSIMILATOR).closer_than(2.0, geyser).exists:
                            await self.build(UnitTypeId.ASSIMILATOR, geyser)
                            found_something = True

            if not found_something:
                if self.already_pending(UnitTypeId.NEXUS) == 0 and self.can_afford(UnitTypeId.NEXUS):
                    await self.expand_now()

        except Exception as e:
            print(e)


    #1: build gateway
    elif action == 1:
        try:
            for nexus in self.townhalls:
                # is there is not a gateway close:
                if not self.structures(UnitTypeId.GATEWAY).closer_than(10, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.GATEWAY) and self.already_pending(UnitTypeId.GATEWAY) == 0:
                            # build forge
                        await self.build(UnitTypeId.GATEWAY, near=nexus)
        except Exception as e:
            print(e)

    #build a forge
    elif action == 2:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if not self.structures(UnitTypeId.FORGE).closer_than(10, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.FORGE) and self.already_pending(UnitTypeId.FORGE) == 0:
                            # build forge
                        await self.build(UnitTypeId.FORGE, near=nexus)
        except Exception as e:
            print(e)

    #3: send scout
    elif action == 3:
        # are there any idle probes:
        try:
            self.last_sent
        except:
            self.last_sent = 0

        # if self.last_sent doesnt exist yet:
        if (iteration - self.last_sent) > 200:
            try:
                if self.units(UnitTypeId.PROBE).idle.exists:
                    # pick one of these randomly:
                    probe = random.choice(self.units(UnitTypeId.PROBE).idle)
                else:
                    probe = random.choice(self.units(UnitTypeId.PROBE))
                # send probe towards enemy base:
                probe.attack(self.enemy_start_locations[0])
                self.last_sent = iteration

            except Exception as e:
                pass


    #4: attack (known buildings, units, then enemy base, just go in logical order.)
    elif action == 4:
        try:
            # take all void rays and attack!
            for voidray in self.units(UnitTypeId.VOIDRAY, UnitTypeId.COLOSSUS, UnitTypeId.ZEALOT, UnitTypeId.STALKER, UnitTypeId.DARKTEMPLAR, UnitTypeId.CARRIER, UnitTypeId.IMMORTAL, UnitTypeId.OBSERVER).idle:
                # if we can attack:
                if self.enemy_units.closer_than(10, voidray):
                    # attack!
                    voidray.attack(random.choice(self.enemy_units.closer_than(10, voidray)))
                # if we can attack:
                elif self.enemy_structures.closer_than(10, voidray):
                    # attack!
                    voidray.attack(random.choice(self.enemy_structures.closer_than(10, voidray)))
                # any enemy units:
                elif self.enemy_units:
                    # attack!
                    voidray.attack(random.choice(self.enemy_units))
                # any enemy structures:
                elif self.enemy_structures:
                    # attack!
                    voidray.attack(random.choice(self.enemy_structures))
                # if we can attack:
                elif self.enemy_start_locations:
                    # attack!
                    voidray.attack(self.enemy_start_locations[0])
        
        except Exception as e:
            print(e)
        
    #5: voidray flee (back to base)
    elif action == 5:
        if self.units(UnitTypeId.VOIDRAY, UnitTypeId.COLOSSUS, UnitTypeId.ZEALOT, UnitTypeId.STALKER, UnitTypeId.DARKTEMPLAR, UnitTypeId.CARRIER, UnitTypeId.IMMORTAL, UnitTypeId.OBSERVER).amount > 0:
            for vr in self.units(UnitTypeId.VOIDRAY, UnitTypeId.COLOSSUS, UnitTypeId.ZEALOT, UnitTypeId.STALKER, UnitTypeId.DARKTEMPLAR, UnitTypeId.CARRIER, UnitTypeId.IMMORTAL, UnitTypeId.OBSERVER):
                vr.attack(self.start_location)

    #build a build a pylon
    elif action == 6:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if not self.structures(UnitTypeId.PYLON).closer_than(5, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.PYLON) and self.already_pending(UnitTypeId.PYLON) == 0:
                            # build forge
                        await self.build(UnitTypeId.PYLON, near=nexus)

        except Exception as e:
            print(e)

    #1: build gateway
    elif action == 7:
        try:
            for nexus in self.townhalls:
                # is there is not a gateway close:
                if self.structures(UnitTypeId.STARGATE).closer_than(20, nexus).exists:
                    if not self.structures(UnitTypeId.FLEETBEACON).closer_than(30, nexus).exists:
                            # if we can afford it:
                        if self.can_afford(UnitTypeId.FLEETBEACON) and self.already_pending(UnitTypeId.FLEETBEACON) == 0:
                                # build forge
                            await self.build(UnitTypeId.FLEETBEACON, near=nexus)
        except Exception as e:
            print(e)        #1: build gateway
    #photoncannon
    elif action == 8:
        try:
            for nexus in self.townhalls:
                # is there is not a gateway close:
                if self.structures(UnitTypeId.PYLON).closer_than(10, nexus).exists:
                            # if we can afford it:
                    if self.can_afford(UnitTypeId.PHOTONCANNON) and self.already_pending(UnitTypeId.PHOTONCANNON) == 0:
                                # build forge
                        await self.build(UnitTypeId.PHOTONCANNON, near=nexus)
        except Exception as e:
            print(e)

    #build a STARGATE
    elif action == 9:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.STARGATE) and self.already_pending(UnitTypeId.STARGATE) == 0:
                            # build forge
                        await self.build(UnitTypeId.STARGATE, near=nexus)
        except Exception as e:
            print(e)


    #build a ROBOTICSBAY
    elif action == 10:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.ROBOTICSBAY) and self.already_pending(UnitTypeId.ROBOTICSBAY) == 0:
                            # build forge
                        await self.build(UnitTypeId.ROBOTICSBAY, near=nexus)
        except Exception as e:
            print(e)

    #build a ROBOTICSBAY
    elif action == 11:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                        # if we can afford it:
                    if self.can_afford(UnitTypeId.ROBOTICSFACILITY) and self.already_pending(UnitTypeId.ROBOTICSFACILITY) == 0:
                            # build forge
                        await self.build(UnitTypeId.ROBOTICSFACILITY, near=nexus)
        except Exception as e:
            print(e)



    #build a TWILIGHTCOUNCIL
    elif action == 12:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                    if self.structures(UnitTypeId.TWILIGHTCOUNCIL).closer_than(20, nexus).exists:
                            # if we can afford it:
                        if self.can_afford(UnitTypeId.TWILIGHTCOUNCIL) and self.already_pending(UnitTypeId.TWILIGHTCOUNCIL) == 0:
                                # build forge
                            await self.build(UnitTypeId.TWILIGHTCOUNCIL, near=nexus)
        except Exception as e:
            print(e)

    #build a DARKSHRINE
    elif action == 13:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                    if self.structures(UnitTypeId.DARKSHRINE).closer_than(20, nexus).exists:
                            # if we can afford it:
                        if self.can_afford(UnitTypeId.DARKSHRINE) and self.already_pending(UnitTypeId.DARKSHRINE) == 0:
                                # build forge
                            await self.build(UnitTypeId.DARKSHRINE, near=nexus)
        except Exception as e:
            print(e)
            
    #2: build Zelot (random gatway)
    elif action == 14:
        try:
            if self.can_afford(UnitTypeId.ZEALOT):
                for sg in self.structures(UnitTypeId.GATEWAY).ready.idle:
                    if self.can_afford(UnitTypeId.ZEALOT):
                        sg.train(UnitTypeId.ZEALOT)
        
        except Exception as e:
            print(e)
            
    #build a CYBERNETICSCORE
    elif action == 15:
        try:
            for nexus in self.townhalls:
                # is there is not a forge close:
                if self.structures(UnitTypeId.NEXUS).closer_than(20, nexus).exists:
                    if self.structures(UnitTypeId.CYBERNETICSCORE).closer_than(20, nexus).exists:
                            # if we can afford it:
                        if self.can_afford(UnitTypeId.CYBERNETICSCORE) and self.already_pending(UnitTypeId.CYBERNETICSCORE) == 0:
                                # build forge
                            await self.build(UnitTypeId.CYBERNETICSCORE, near=nexus)
        except Exception as e:
            print(e)
            
    #2: build Zelot (random stargate)
    elif action == 16:
        try:
            if self.can_afford(UnitTypeId.ZEALOT):
                for sg in self.structures(UnitTypeId.GATEWAY).ready.idle:
                    if self.can_afford(UnitTypeId.ZEALOT):
                        sg.train(UnitTypeId.ZEALOT)
        
        except Exception as e:
            print(e)
            
    #2: build STALKER (random stargate)
    elif action == 17:
        try:
            if self.can_afford(UnitTypeId.STALKER):
                for sg in self.structures(UnitTypeId.GATEWAY).ready.idle:
                    if self.can_afford(UnitTypeId.STALKER):
                        sg.train(UnitTypeId.STALKER)
        
        except Exception as e:
            print(e)
                            
            
    #2: build DARKTEMPLAR (random stargate)
    elif action == 18:
        try:
            if self.can_afford(UnitTypeId.DARKTEMPLAR):
                for sg in self.structures(UnitTypeId.GATEWAY).ready.idle:
                    if self.can_afford(UnitTypeId.DARKTEMPLAR):
                        sg.train(UnitTypeId.DARKTEMPLAR)
        
        except Exception as e:
            print(e)
                            
    #2: build CARRIER (random stargate)
    elif action == 19:
        try:
            if self.can_afford(UnitTypeId.CARRIER):
                for sg in self.structures(UnitTypeId.STARGATE).ready.idle:
                    if self.can_afford(UnitTypeId.CARRIER):
                        sg.train(UnitTypeId.CARRIER)
        
        except Exception as e:
            print(e)                
    #2: build voidrray (random stargate)
    elif action == 20:
        try:
            if self.can_afford(UnitTypeId.VOIDRAY):
                for sg in self.structures(UnitTypeId.STARGATE).ready.idle:
                    if self.can_afford(UnitTypeId.VOIDRAY):
                        sg.train(UnitTypeId.VOIDRAY)
        
        except Exception as e:
            print(e)


    #2: build IMMORTAL (random stargate)
    elif action == 21:
        try:
            if self.can_afford(UnitTypeId.IMMORTAL):
                for sg in self.structures(UnitTypeId.ROBOTICSBAY).ready.idle:
                    if self.can_afford(UnitTypeId.IMMORTAL):
                        sg.train(UnitTypeId.IMMORTAL)
        
        except Exception as e:
            print(e)

    #2: build COLOSSUS (random stargate)
    elif action == 22:
        try:
            if self.can_afford(UnitTypeId.COLOSSUS  ):
                for sg in self.structures(UnitTypeId.ROBOTICSBAY).ready.idle:
                    if self.can_afford(UnitTypeId.COLOSSUS):
                        sg.train(UnitTypeId.COLOSSUS)
        
        except Exception as e:
            print(e)

    #2: build COLOSSUS (random stargate)
    elif action == 23:
        try:
            if self.can_afford(UnitTypeId.OBSERVER  ):
                for sg in self.structures(UnitTypeId.ROBOTICSBAY).ready.idle:
                    if self.can_afford(UnitTypeId.OBSERVER):
                        sg.train(UnitTypeId.OBSERVER)
        
        except Exception as e:
            print(e)





















    map = np.zeros((self.game_info.map_size[0], self.game_info.map_size[1], 3), dtype=np.uint8)

    # draw the minerals:
    for mineral in self.mineral_field:
        pos = mineral.position
        c = [175, 255, 255]
        fraction = mineral.mineral_contents / 1800
        if mineral.is_visible:
            #print(mineral.mineral_contents)
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]
        else:
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [20,75,50]  


    # draw the enemy start location:
    for enemy_start_location in self.enemy_start_locations:
        pos = enemy_start_location
        c = [0, 0, 255]
        map[math.ceil(pos.y)][math.ceil(pos.x)] = c

    # draw the enemy units:
    for enemy_unit in self.enemy_units:
        pos = enemy_unit.position
        c = [100, 0, 255]
        # get unit health fraction:
        fraction = enemy_unit.health / enemy_unit.health_max if enemy_unit.health_max > 0 else 0.0001
        map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]


    # draw the enemy structures:
    for enemy_structure in self.enemy_structures:
        pos = enemy_structure.position
        c = [0, 100, 255]
        # get structure health fraction:
        fraction = enemy_structure.health / enemy_structure.health_max if enemy_structure.health_max > 0 else 0.0001
        map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]

    # draw our structures:
    for our_structure in self.structures:
        # if it's a nexus:
        if our_structure.type_id == UnitTypeId.NEXUS:
            pos = our_structure.position
            c = [255, 255, 175]
            # get structure health fraction:
            fraction = our_structure.health / our_structure.health_max if our_structure.health_max > 0 else 0.0001
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]
        
        else:
            pos = our_structure.position
            c = [0, 255, 175]
            # get structure health fraction:
            fraction = our_structure.health / our_structure.health_max if our_structure.health_max > 0 else 0.0001
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]


    # draw the vespene geysers:
    for vespene in self.vespene_geyser:
        # draw these after buildings, since assimilators go over them. 
        # tried to denote some way that assimilator was on top, couldnt 
        # come up with anything. Tried by positions, but the positions arent identical. ie:
        # vesp position: (50.5, 63.5) 
        # bldg positions: [(64.369873046875, 58.982421875), (52.85693359375, 51.593505859375),...]
        pos = vespene.position
        c = [255, 175, 255]
        fraction = vespene.vespene_contents / 2250

        if vespene.is_visible:
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]
        else:
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [50,20,75]

    # draw our units:
    for our_unit in self.units:     
        # if it is a voidray:
        if our_unit.type_id == UnitTypeId.VOIDRAY or UnitTypeId.COLOSSUS or UnitTypeId.ZEALOT or UnitTypeId.STALKER or UnitTypeId.DARKTEMPLAR or UnitTypeId.CARRIER or UnitTypeId.IMMORTAL or UnitTypeId.OBSERVER:
            pos = our_unit.position
            c = [255, 75 , 75]
            # get health:
            fraction = our_unit.health / our_unit.health_max if our_unit.health_max > 0 else 0.0001
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]


        else:
            pos = our_unit.position
            c = [175, 255, 0]
            # get health:
            fraction = our_unit.health / our_unit.health_max if our_unit.health_max > 0 else 0.0001
            map[math.ceil(pos.y)][math.ceil(pos.x)] = [int(fraction*i) for i in c]

    # show map with opencv, resized to be larger:
    # horizontal flip:

    cv2.imshow('map',cv2.flip(cv2.resize(map, None, fx=4, fy=4, interpolation=cv2.INTER_NEAREST), 0))
    cv2.waitKey(1)

    if SAVE_REPLAY:
        # save map image into "replays dir"
        cv2.imwrite(f"replays/{int(time.time())}-{iteration}.png", map)



    reward = 0

    try:
        attack_count = 0
        # iterate through our void rays:
        for voidray in self.units(UnitTypeId.VOIDRAY, UnitTypeId.COLOSSUS, UnitTypeId.ZEALOT, UnitTypeId.STALKER, UnitTypeId.DARKTEMPLAR, UnitTypeId.CARRIER, UnitTypeId.IMMORTAL, UnitTypeId.OBSERVER):
            # if voidray is attacking and is in range of enemy unit:
            if voidray.is_attacking and voidray.target_in_range:
                if self.enemy_units.closer_than(8, voidray) or self.enemy_structures.closer_than(8, voidray):
                    # reward += 0.005 # original was 0.005, decent results, but let's 3x it. 
                    reward += 0.015  
                    attack_count += 1

    except Exception as e:
        print("reward",e)
        reward = 0

    
    if iteration % 100 == 0:
        print(f"Iter: {iteration}. RWD: {reward}. VR: {self.units(UnitTypeId.VOIDRAY, UnitTypeId.COLOSSUS, UnitTypeId.ZEALOT, UnitTypeId.STALKER, UnitTypeId.DARKTEMPLAR, UnitTypeId.CARRIER, UnitTypeId.IMMORTAL, UnitTypeId.OBSERVER).amount}")

    # write the file: 
    data = {"state": map, "reward": reward, "action": None, "done": False}  # empty action waiting for the next one!

    with open('state_rwd_action.pkl', 'wb') as f:
        pickle.dump(data, f)

result = run_game( # run_game is a function that runs the game.
maps.get("AcropolisLE"), # the map we are playing on
[Bot(Race.Protoss, IncrediBot()), # runs our coded bot, protoss race, and we pass our bot object
Computer(Race.Zerg, Difficulty.Hard)], # runs a pre-made computer agent, zerg race, with a hard difficulty.
realtime=False, # When set to True, the agent is limited in how long each step can take to process.
)

if str(result) == "Result.Victory":
rwd = 500
else:
rwd = -500

with open("results.txt","a") as f:
f.write(f"{result}\n")

map = np.zeros((224, 224, 3), dtype=np.uint8)
observation = map
data = {"state": map, "reward": rwd, "action": None, "done": True} # empty action waiting for the next one!
with open('state_rwd_action.pkl', 'wb') as f:
pickle.dump(data, f)

cv2.destroyAllWindows()
cv2.waitKey(1)
time.sleep(3)
sys.exit()

======================================================================

======================================================================

But in this code, he found the module sc2:

import random

from sc2 import maps
from sc2.bot_ai import BotAI
from sc2.data import Difficulty, Race
from sc2.ids.unit_typeid import UnitTypeId
from sc2.main import run_game
from sc2.player import Bot, Computer

class CannonRushBot(BotAI):

# pylint: disable=R0912
async def on_step(self, iteration):
    if iteration == 0:
        await self.chat_send("(probe)(pylon)(cannon)(cannon)(gg)")

    if not self.townhalls:
        # Attack with all workers if we don't have any nexuses left, attack-move on enemy spawn (doesn't work on 4 player map) so that probes auto attack on the way
        for worker in self.workers:
            worker.attack(self.enemy_start_locations[0])
        return

    nexus = self.townhalls.random

    # Make probes until we have 16 total
    if self.supply_workers < 16 and nexus.is_idle:
        if self.can_afford(UnitTypeId.PROBE):
            nexus.train(UnitTypeId.PROBE)

    # If we have no pylon, build one near starting nexus
    elif not self.structures(UnitTypeId.PYLON) and self.already_pending(UnitTypeId.PYLON) == 0:
        if self.can_afford(UnitTypeId.PYLON):
            await self.build(UnitTypeId.PYLON, near=nexus)

    # If we have no forge, build one near the pylon that is closest to our starting nexus
    elif not self.structures(UnitTypeId.FORGE):
        pylon_ready = self.structures(UnitTypeId.PYLON).ready
        if pylon_ready:
            if self.can_afford(UnitTypeId.FORGE):
                await self.build(UnitTypeId.FORGE, near=pylon_ready.closest_to(nexus))

    # If we have less than 2 pylons, build one at the enemy base
    elif self.structures(UnitTypeId.PYLON).amount < 2:
        if self.can_afford(UnitTypeId.PYLON):
            pos = self.enemy_start_locations[0].towards(self.game_info.map_center, random.randrange(8, 15))
            await self.build(UnitTypeId.PYLON, near=pos)

    # If we have no cannons but at least 2 completed pylons, automatically find a placement location and build them near enemy start location
    elif not self.structures(UnitTypeId.PHOTONCANNON):
        if self.structures(UnitTypeId.PYLON).ready.amount >= 2 and self.can_afford(UnitTypeId.PHOTONCANNON):
            pylon = self.structures(UnitTypeId.PYLON).closer_than(20, self.enemy_start_locations[0]).random
            await self.build(UnitTypeId.PHOTONCANNON, near=pylon)

    # Decide if we should make pylon or cannons, then build them at random location near enemy spawn
    elif self.can_afford(UnitTypeId.PYLON) and self.can_afford(UnitTypeId.PHOTONCANNON):
        # Ensure "fair" decision
        for _ in range(20):
            pos = self.enemy_start_locations[0].random_on_distance(random.randrange(5, 12))
            building = UnitTypeId.PHOTONCANNON if self.state.psionic_matrix.covers(pos) else UnitTypeId.PYLON
            await self.build(building, near=pos)

def main():
run_game(
maps.get("ThunderbirdLE"),
[Bot(Race.Protoss, CannonRushBot(), name="CheeseCannon"),
Computer(Race.Protoss, Difficulty.Medium)],
realtime=False,
)

if name == "main":
main()

Pls someone help me!!!!

OS:windows 11
python: 3.10.11

@cjy513203427
Copy link

cjy513203427 commented Dec 27, 2023

I used PyCharm I did't have this problem. I met this problem before with VSCode

@Nickrader
Copy link

Try the poetry install method, see if that works.

@BurnySc2 BurnySc2 added the question Further information is requested label Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants