I want to save the results of the game in the folder which is located here C:123train_data (i.e. data should be saved in the folder train_data).
But I can’t I get this error
Traceback (most recent call last):
File "c:123sc2.txt", line 259, in <module>
run_game(maps.get("(2)BurialGrounds"), [
File "C:Usersbakshsh{AppDataLocalPackagesPythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0LocalCachelocal-packagesPython311site-packagessc2main.py", line 325, in run_game
result = asyncio.get_event_loop().run_until_complete(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0Libasynciobase_events.py", line 654, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:UsersbakshthAppDataLocalPackagesPythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0LocalCachelocal-packagesPython311site-packagessc2main.py", line 253, in _host_game
result = await _play_game(players[0], client, realtime, portconfig, step_time_limit, game_time_limit, rgb_render_config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:UsersbakshthAppDataLocalPackagesPythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0LocalCachelocal-packagesPython311site-packagessc2main.py", line 223, in _play_game
result = await _play_game_ai(client, player_id, player.ai, realtime, step_time_limit, game_time_limit)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:UsersbakshshAppDataLocalPackagesPythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0LocalCachelocal-packagesPython311site-packagessc2main.py", line 127, in _play_game_ai
ai.on_end(client._game_result[player_id])
File "c:123sc2.txt", line 29, in on_end
np.save("train_data/{}.npy".format(str(int(int(time.time()))), np.array(self.train_data)))
^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (24, 2) + inhomogeneous part.
And here’s my code
import cv2
import numpy as np
import sc2
from sc2 import run_game, maps, Race, Difficulty, position, Result
from sc2.player import Bot, Computer
from sc2.constants import HATCHERY, DRONE, LARVA, OVERLORD, EXTRACTOR, SPAWNINGPOOL, ROACHWARREN, ZERGLING, ROACH
import random
import time
HEADLESS = True
class AloKostBot(sc2.BotAI):
def __init__(self):
self.ITERATIONS_PER_MINUTE = 165
self.MAX_WORKERS = 88
self.do_something_after = 0
self.train_data = []
def on_end(self, game_result):
print('--- on_end called ---')
print(game_result)
if game_result == Result.Victory:
np.save("train_data/{}.npy".format(str(int(time.time()))), np.array(self.train_data))
async def on_step(self, iteration):
self.iteration = iteration
await self.scout()
await self.distribute_workers()
await self.build_workers()
await self.build_overlords()
await self.build_extractor()
await self.expand()
await self.offensive_force_buildings()
await self.build_offensive_force()
await self.intel()
await self.attack()
def random_location_variance(self, enemy_start_location):
x = enemy_start_location[0]
y = enemy_start_location[1]
x += ((random.randrange(-20, 20))/100) * enemy_start_location[0]
y += ((random.randrange(-20, 20))/100) * enemy_start_location[1]
if x < 0:
x = 0
if y < 0:
y = 0
if x > self.game_info.map_size[0]:
x = self.game_info.map_size[0]
if y > self.game_info.map_size[1]:
y = self.game_info.map_size[1]
go_to = position.Point2(position.Pointlike((x,y)))
return go_to
async def scout(self):
if len(self.units(ZERGLING)) > 0:
scout = self.units(ZERGLING)[0]
if scout.is_idle:
enemy_location = self.enemy_start_locations[0]
move_to = self.random_location_variance(enemy_location)
print(move_to)
await self.do(scout.move(move_to))
else:
for l in self.units(LARVA).ready.noqueue:
if self.can_afford(ZERGLING):
await self.do(l.train(ZERGLING))
async def intel(self):
game_data = np.zeros((self.game_info.map_size[1], self.game_info.map_size[0], 3), np.uint8)
draw_dict = {
HATCHERY: [15, (0, 255, 0)],
DRONE: [1, (55, 200, 0)],
EXTRACTOR: [2, (55, 200, 0)],
SPAWNINGPOOL: [3, (200, 100, 0)],
ROACHWARREN: [3, (150, 150, 0)],
ROACH: [3, (20, 235, 0)],
#ZERGLING: [3, (255, 255, 255)],
}
for unit_type in draw_dict:
for unit in self.units(unit_type).ready:
pos = unit.position
cv2.circle(game_data, (int(pos[0]), int(pos[1])), draw_dict[unit_type][0], draw_dict[unit_type][1], -1)
main_base_names = ["nexus", "supplydepot", "hatchery"]
for enemy_building in self.known_enemy_structures:
pos = enemy_building.position
if enemy_building.name.lower() not in main_base_names:
cv2.circle(game_data, (int(pos[0]), int(pos[1])), 5, (200, 50, 212), -1)
for enemy_building in self.known_enemy_structures:
pos = enemy_building.position
if enemy_building.name.lower() in main_base_names:
cv2.circle(game_data, (int(pos[0]), int(pos[1])), 15, (0, 0, 255), -1)
for enemy_unit in self.known_enemy_units:
if not enemy_unit.is_structure:
worker_names = ["probe",
"scv",
"drone"]
pos = enemy_unit.position
if enemy_unit.name.lower() in worker_names:
cv2.circle(game_data, (int(pos[0]), int(pos[1])), 1, (55, 0, 155), -1)
else:
cv2.circle(game_data, (int(pos[0]), int(pos[1])), 3, (50, 0, 215), -1)
for z in self.units(ZERGLING).ready:
pos = z.position
cv2.circle(game_data, (int(pos[0]), int(pos[1])), 1, (255, 255, 255), -1)
line_max = 50
mineral_ratio = self.minerals / 1500
if mineral_ratio > 1.0:
mineral_ratio = 1.0
vespene_ratio = self.vespene / 1500
if vespene_ratio > 1.0:
vespene_ratio = 1.0
population_ratio = self.supply_left / self.supply_cap
if population_ratio > 1.0:
population_ratio = 1.0
plausible_supply = self.supply_cap / 200.0
military_weight = len(self.units(ROACH)) / (self.supply_cap-self.supply_left)
if military_weight > 1.0:
military_weight = 1.0
cv2.line(game_data, (0, 19), (int(line_max*military_weight), 19), (250, 250, 200), 3) # worker/supply ratio
cv2.line(game_data, (0, 15), (int(line_max*plausible_supply), 15), (220, 200, 200), 3) # plausible supply (supply/200.0)
cv2.line(game_data, (0, 11), (int(line_max*population_ratio), 11), (150, 150, 150), 3) # population ratio (supply_left/supply)
cv2.line(game_data, (0, 7), (int(line_max*vespene_ratio), 7), (210, 200, 0), 3) # gas / 1500
cv2.line(game_data, (0, 3), (int(line_max*mineral_ratio), 3), (0, 255, 25), 3)
self.flipped = cv2.flip(game_data, 0)
if not HEADLESS:
resized = cv2.resize(self.flipped, dsize=None, fx=2, fy=2)
cv2.imshow('Intel', resized)
cv2.waitKey(1)
async def build_workers(self):
if (len(self.units(HATCHERY)) * 16) > len(self.units(DRONE)) and len(self.units(DRONE)) < self.MAX_WORKERS:
for larva in self.units(LARVA).ready.noqueue:
if self.can_afford(DRONE):
await self.do(larva.train(DRONE))
async def build_overlords(self):
if self.supply_left < 10:
for larva in self.units(LARVA).ready.noqueue:
if self.can_afford(OVERLORD):
await self.do(larva.train(OVERLORD))
async def build_extractor(self):
for hatchery in self.units(HATCHERY).ready:
vaspenes = self.state.vespene_geyser.closer_than(15.0, hatchery)
for vaspene in vaspenes:
if not self.can_afford(EXTRACTOR):
break
worker = self.select_build_worker(vaspene.position)
if worker is None:
break
if not self.units(EXTRACTOR).closer_than(1.0, vaspene).exists:
await self.do(worker.build(EXTRACTOR, vaspene))
async def expand(self):
if self.units(HATCHERY).amount < (self.iteration / self.ITERATIONS_PER_MINUTE) and self.can_afford(HATCHERY):
await self.expand_now()
async def offensive_force_buildings(self):
if self.units(HATCHERY).ready.exists:
hatchery = self.units(HATCHERY).ready.random
if self.units(HATCHERY).ready.exists and not self.units(SPAWNINGPOOL):
if self.can_afford(SPAWNINGPOOL) and not self.already_pending(SPAWNINGPOOL):
await self.build(SPAWNINGPOOL, near=hatchery)
elif len(self.units(HATCHERY)) < ((self.iteration / self.ITERATIONS_PER_MINUTE)/2):
if self.can_afford(HATCHERY) and not self.already_pending(HATCHERY):
await self.build(HATCHERY, near=hatchery)
if self.units(SPAWNINGPOOL).ready.exists and not self.units(ROACHWARREN):
if self.can_afford(ROACHWARREN) and not self.already_pending(ROACHWARREN):
await self.build(ROACHWARREN, near=hatchery)
async def build_offensive_force(self):
for l in self.units(LARVA).ready.noqueue:
#if not self.units(ZERGLING).amount > self.units(ROACH).amount:
#if self.can_afford(ZERGLING) and self.supply_left > 0:
#await self.do(l.train(ZERGLING))
if self.can_afford(ROACH) and self.supply_left > 0:
await self.do(l.train(ROACH))
def find_target(self, state):
if len(self.known_enemy_units) > 0:
return random.choice(self.known_enemy_units)
elif len(self.known_enemy_structures) > 0:
return random.choice(self.known_enemy_structures)
else:
return self.enemy_start_locations[0]
async def attack(self):
if len(self.units(ROACH).idle) > 0:
choice = random.randrange(0, 4)
target = False
if self.iteration > self.do_something_after:
if choice == 0:
# no attack
wait = random.randrange(20, 165)
self.do_something_after = self.iteration + wait
elif choice == 1:
#attack_unit_closest_nexus
if len(self.known_enemy_units) > 0:
target = self.known_enemy_units.closest_to(random.choice(self.units(HATCHERY)))
elif choice == 2:
#attack enemy structures
if len(self.known_enemy_structures) > 0:
target = random.choice(self.known_enemy_structures)
elif choice == 3:
#attack_enemy_start
target = self.enemy_start_locations[0]
if target:
for vr in self.units(ROACH).idle:
await self.do(vr.attack(target))
y = np.zeros(4)
y[choice] = 1
print(y)
self.train_data.append([y,self.flipped])
run_game(maps.get("(2)BurialGrounds"), [
Bot(Race.Zerg, AloKostBot()),
Computer(Race.Protoss, Difficulty.Easy)
], realtime=False)
I am not good at programming, but I tried to change both the destination and the direction to the folder, but nothing works.
New contributor
AloKost is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.