From 22861a492f0cbf4cec47eea2b56aa82a56c8b045 Mon Sep 17 00:00:00 2001 From: xluox Date: Thu, 17 Feb 2022 23:48:02 -0500 Subject: [PATCH 01/17] First Commit Support randomly generating maps including walls, obstacles, resources, bases, workers. Conflicting issue remains --- PCG/maps/filename.xml | 1 + PCG/maps/wall-1 | 15 +++++++ PCG/pcg.py | 100 ++++++++++++++++++++++++++++++++++++++++++ gym_microrts/microrts | 2 +- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 PCG/maps/filename.xml create mode 100644 PCG/maps/wall-1 create mode 100644 PCG/pcg.py diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml new file mode 100644 index 00000000..d64ed0d4 --- /dev/null +++ b/PCG/maps/filename.xml @@ -0,0 +1 @@ +1111111111111111111111111111111111111111111111111110000100000111111100000000011111100000001001111110001001010111111000000000011111100000100011111110100000001111111000000100011111100000000001111110000001000111111111111111111111111111111111111111111111111111 \ No newline at end of file diff --git a/PCG/maps/wall-1 b/PCG/maps/wall-1 new file mode 100644 index 00000000..5903a1cd --- /dev/null +++ b/PCG/maps/wall-1 @@ -0,0 +1,15 @@ + + 1111111110000001100000011000000110000001100000011000000111111111 + + + + + + + + + + + + + diff --git a/PCG/pcg.py b/PCG/pcg.py new file mode 100644 index 00000000..16a1ad86 --- /dev/null +++ b/PCG/pcg.py @@ -0,0 +1,100 @@ +import xml.etree.cElementTree as ET +import random + +key = 15 +sections = [] + + +def initiateTerrain(root, tag, wallRings): + terrain = ET.SubElement(root, tag) + eText = '' + + def getObstacles(): + chance = 0.2 * random.random() + if random.random() < chance: + return '1' + else: + return '0' + + for i in range(height): + for y in range(width): + if i in range(0, wallRings) or i in range(height - wallRings, height): + eText += '1' + elif y in range(0, wallRings) or y in range(height - wallRings, height): + eText += '1' + else: + eText += getObstacles() + terrain.text = eText + + +def initiatePlayers(root, tag): + players = ET.SubElement(root, tag) + ET.SubElement(players, "rts.Player", ID="0", resources="5") + ET.SubElement(players, "rts.Player", ID="1", resources="5") + + +def initiateUnits(root, tag, wallRings): + units = ET.SubElement(root, tag) + height = int(root.attrib.get('height')) + width = int(root.attrib.get('width')) + initiateResources(units, "rts.units.Unit", wallRings, height, width) + initiateBases(units, "rts.units.Unit", wallRings, height, width) + initiateWorkers(units, "rts.units.Unit", wallRings, height, width) + + +def initiateResources(root, tag, wallRings, height, width): + resourcesLimit = 4 + num_resource = 4 + + for i in range(num_resource): + x, y = get_xy(i) + ET.SubElement(root, tag, type="Resource", ID=get_unique_key(), player="-1", + x=str(x), y=str(y), resources="25", hitpoints="1") + + +def initiateBases(root, tag, wallRings, height, width): + base_limit = 2 + num_bases = 2 + for i in range(num_bases): + x, y = get_xy(random.randint(0, 3)) + ET.SubElement(root, tag, type="Base", ID=get_unique_key(), + player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="10") + + +def initiateWorkers(root, tag, wallRings, height, width): + worker_limit = 2 + num_worker = 2 + for i in range(num_worker): + x, y = get_xy(random.randint(0, 3)) + ET.SubElement(root, tag, type="Worker", ID=get_unique_key(), player=str(i % 2), + x=str(x), y=str(y), resources="0", hitpoints="1") + + +def get_unique_key(): + global key + key = key + 1 + return str(key) + + +def get_xy(index): + return random.randint(sections[index][0][0], sections[index][0][1]), random.randint(sections[index][1][0], sections[index][1][1]) + + +if __name__ == "__main__": + + root = ET.Element("rts.PhysicalGameState", width="16", height="16") + height = int(root.attrib.get('height')) + width = int(root.attrib.get('width')) + wallRingsLimit = min(height, width) // 2 - 3 + if wallRingsLimit < 0: + wallRingsLimit = 0 + wallRings = random.randint(0, wallRingsLimit) + sections = [((wallRings, (width-1)//2), (wallRings, (height-1)//2)), ( + (width//2, (width-1)-wallRings), (wallRings, (height-1)//2)), ((wallRings, (width-1)//2), (height//2, (height-1)-wallRings)), ((width//2, (width-1)-wallRings), (height//2, (height-1)-wallRings))] + + initiateTerrain(root, "terrain", wallRings) + initiatePlayers(root, "players") + initiateUnits(root, "units", wallRings) + + tree = ET.ElementTree(root) + tree.write("PCG/maps/filename.xml") diff --git a/gym_microrts/microrts b/gym_microrts/microrts index bf077a20..e3dd5bda 160000 --- a/gym_microrts/microrts +++ b/gym_microrts/microrts @@ -1 +1 @@ -Subproject commit bf077a203e10329e0b23f01665d02eb5cfdc77fe +Subproject commit e3dd5bda771896f10b3c8dcc3b85a7b0d391056c From 6e8887fa733dfe97d8f2e908ab2899bdca6b66bc Mon Sep 17 00:00:00 2001 From: xluox Date: Fri, 18 Feb 2022 00:44:09 -0500 Subject: [PATCH 02/17] Fix conflicting issue between units and walls --- PCG/maps/filename.xml | 2 +- PCG/pcg.py | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml index d64ed0d4..078d2240 100644 --- a/PCG/maps/filename.xml +++ b/PCG/maps/filename.xml @@ -1 +1 @@ -1111111111111111111111111111111111111111111111111110000100000111111100000000011111100000001001111110001001010111111000000000011111100000100011111110100000001111111000000100011111100000000001111110000001000111111111111111111111111111111111111111111111111111 \ No newline at end of file +0001000000010000000000000000000000000000000000000000000000100001000000000000001000000000000000010000000100000000001000000000000000000000000001000000000000000000000000100100000000000000010000001000010000001000010000000001000100000000000000000000001000010000 \ No newline at end of file diff --git a/PCG/pcg.py b/PCG/pcg.py index 16a1ad86..cd0e260f 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -3,27 +3,35 @@ key = 15 sections = [] +unit_location_records = [] def initiateTerrain(root, tag, wallRings): terrain = ET.SubElement(root, tag) eText = '' + global unit_location_records - def getObstacles(): + def getObstacle(): chance = 0.2 * random.random() if random.random() < chance: return '1' else: return '0' - for i in range(height): - for y in range(width): - if i in range(0, wallRings) or i in range(height - wallRings, height): + for y in range(height): + for x in range(width): + if y in range(0, wallRings) or y in range(height - wallRings, height): eText += '1' - elif y in range(0, wallRings) or y in range(height - wallRings, height): + unit_location_records.append((x, y)) + elif x in range(0, wallRings) or x in range(height - wallRings, height): eText += '1' + unit_location_records.append((x, y)) else: - eText += getObstacles() + obstacle = getObstacle() + eText += obstacle + if obstacle == 1: + unit_location_records.append((x, y)) + terrain.text = eText @@ -77,7 +85,15 @@ def get_unique_key(): def get_xy(index): - return random.randint(sections[index][0][0], sections[index][0][1]), random.randint(sections[index][1][0], sections[index][1][1]) + global unit_location_records + + x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( + sections[index][1][0], sections[index][1][1]) + while((x, y) in unit_location_records): + x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( + sections[index][1][0], sections[index][1][1]) + unit_location_records.append((x, y)) + return x, y if __name__ == "__main__": From b560ec2b623f2cea0b8d3cb87733dd0f12406437 Mon Sep 17 00:00:00 2001 From: xluox Date: Mon, 21 Feb 2022 22:33:13 -0500 Subject: [PATCH 03/17] Fixed bug of conflicting, fix the format --- PCG/maps/filename.xml | 2 +- PCG/pcg.py | 59 +++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml index 078d2240..e7ec70d0 100644 --- a/PCG/maps/filename.xml +++ b/PCG/maps/filename.xml @@ -1 +1 @@ -0001000000010000000000000000000000000000000000000000000000100001000000000000001000000000000000010000000100000000001000000000000000000000000001000000000000000000000000100100000000000000010000001000010000001000010000000001000100000000000000000000001000010000 \ No newline at end of file +1111111111111111111111111111111111111111111111111111111111111111111101000010111111110000000011111111000000001111111111000000111111110000000011111111000000001111111100000000111111110000001011111111111111111111111111111111111111111111111111111111111111111111 \ No newline at end of file diff --git a/PCG/pcg.py b/PCG/pcg.py index cd0e260f..4d169494 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,5 +1,5 @@ -import xml.etree.cElementTree as ET import random +import xml.etree.cElementTree as ET key = 15 sections = [] @@ -8,28 +8,28 @@ def initiateTerrain(root, tag, wallRings): terrain = ET.SubElement(root, tag) - eText = '' + eText = "" global unit_location_records def getObstacle(): chance = 0.2 * random.random() if random.random() < chance: - return '1' + return "1" else: - return '0' + return "0" for y in range(height): for x in range(width): if y in range(0, wallRings) or y in range(height - wallRings, height): - eText += '1' + eText += "1" unit_location_records.append((x, y)) elif x in range(0, wallRings) or x in range(height - wallRings, height): - eText += '1' + eText += "1" unit_location_records.append((x, y)) else: obstacle = getObstacle() eText += obstacle - if obstacle == 1: + if obstacle == "1": unit_location_records.append((x, y)) terrain.text = eText @@ -43,39 +43,39 @@ def initiatePlayers(root, tag): def initiateUnits(root, tag, wallRings): units = ET.SubElement(root, tag) - height = int(root.attrib.get('height')) - width = int(root.attrib.get('width')) + height = int(root.attrib.get("height")) + width = int(root.attrib.get("width")) initiateResources(units, "rts.units.Unit", wallRings, height, width) initiateBases(units, "rts.units.Unit", wallRings, height, width) initiateWorkers(units, "rts.units.Unit", wallRings, height, width) def initiateResources(root, tag, wallRings, height, width): - resourcesLimit = 4 num_resource = 4 for i in range(num_resource): x, y = get_xy(i) - ET.SubElement(root, tag, type="Resource", ID=get_unique_key(), player="-1", - x=str(x), y=str(y), resources="25", hitpoints="1") + ET.SubElement( + root, tag, type="Resource", ID=get_unique_key(), player="-1", x=str(x), y=str(y), resources="25", hitpoints="1" + ) def initiateBases(root, tag, wallRings, height, width): - base_limit = 2 num_bases = 2 for i in range(num_bases): x, y = get_xy(random.randint(0, 3)) - ET.SubElement(root, tag, type="Base", ID=get_unique_key(), - player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="10") + ET.SubElement( + root, tag, type="Base", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="10" + ) def initiateWorkers(root, tag, wallRings, height, width): - worker_limit = 2 num_worker = 2 for i in range(num_worker): x, y = get_xy(random.randint(0, 3)) - ET.SubElement(root, tag, type="Worker", ID=get_unique_key(), player=str(i % 2), - x=str(x), y=str(y), resources="0", hitpoints="1") + ET.SubElement( + root, tag, type="Worker", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="1" + ) def get_unique_key(): @@ -88,10 +88,12 @@ def get_xy(index): global unit_location_records x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( - sections[index][1][0], sections[index][1][1]) - while((x, y) in unit_location_records): + sections[index][1][0], sections[index][1][1] + ) + while (x, y) in unit_location_records: x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( - sections[index][1][0], sections[index][1][1]) + sections[index][1][0], sections[index][1][1] + ) unit_location_records.append((x, y)) return x, y @@ -99,18 +101,25 @@ def get_xy(index): if __name__ == "__main__": root = ET.Element("rts.PhysicalGameState", width="16", height="16") - height = int(root.attrib.get('height')) - width = int(root.attrib.get('width')) + height = int(root.attrib.get("height")) + width = int(root.attrib.get("width")) wallRingsLimit = min(height, width) // 2 - 3 if wallRingsLimit < 0: wallRingsLimit = 0 wallRings = random.randint(0, wallRingsLimit) - sections = [((wallRings, (width-1)//2), (wallRings, (height-1)//2)), ( - (width//2, (width-1)-wallRings), (wallRings, (height-1)//2)), ((wallRings, (width-1)//2), (height//2, (height-1)-wallRings)), ((width//2, (width-1)-wallRings), (height//2, (height-1)-wallRings))] + sections = [ + ((wallRings, (width - 1) // 2), (wallRings, (height - 1) // 2)), + ((width // 2, (width - 1) - wallRings), (wallRings, (height - 1) // 2)), + ((wallRings, (width - 1) // 2), (height // 2, (height - 1) - wallRings)), + ((width // 2, (width - 1) - wallRings), + (height // 2, (height - 1) - wallRings)), + ] initiateTerrain(root, "terrain", wallRings) initiatePlayers(root, "players") initiateUnits(root, "units", wallRings) + print(unit_location_records) + tree = ET.ElementTree(root) tree.write("PCG/maps/filename.xml") From 432e2a161dbbd17c6b887c5d75b7e80eb5747ef2 Mon Sep 17 00:00:00 2001 From: xluox Date: Wed, 23 Feb 2022 22:32:28 -0500 Subject: [PATCH 04/17] Tied workers to be in the same section as the base. Fix the formatting --- PCG/maps/filename.xml | 2 +- PCG/pcg.py | 85 +++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml index e7ec70d0..1e1fed26 100644 --- a/PCG/maps/filename.xml +++ b/PCG/maps/filename.xml @@ -1 +1 @@ -1111111111111111111111111111111111111111111111111111111111111111111101000010111111110000000011111111000000001111111111000000111111110000000011111111000000001111111100000000111111110000001011111111111111111111111111111111111111111111111111111111111111111111 \ No newline at end of file +1111111111111111111111111111111111111111111111111111111111111111111111111111111111111000100111111111100000011111111110000001111111111000000111111111100000011111111110000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111 \ No newline at end of file diff --git a/PCG/pcg.py b/PCG/pcg.py index 4d169494..8ad2e16f 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,17 +1,19 @@ import random import xml.etree.cElementTree as ET -key = 15 -sections = [] -unit_location_records = [] +KEY = 15 +SECTIONS = [] +UNIT_LOCATION_RECORDS = [] +SECTIONS_CHOICES = [0, 1, 2, 3] +BASE_LOCATION_RECORDS = [] -def initiateTerrain(root, tag, wallRings): +def initiate_terrain(root, tag, wallRings): terrain = ET.SubElement(root, tag) eText = "" - global unit_location_records + global UNIT_LOCATION_RECORDS - def getObstacle(): + def get_obstacle(): chance = 0.2 * random.random() if random.random() < chance: return "1" @@ -22,35 +24,35 @@ def getObstacle(): for x in range(width): if y in range(0, wallRings) or y in range(height - wallRings, height): eText += "1" - unit_location_records.append((x, y)) + UNIT_LOCATION_RECORDS.append((x, y)) elif x in range(0, wallRings) or x in range(height - wallRings, height): eText += "1" - unit_location_records.append((x, y)) + UNIT_LOCATION_RECORDS.append((x, y)) else: - obstacle = getObstacle() + obstacle = get_obstacle() eText += obstacle if obstacle == "1": - unit_location_records.append((x, y)) + UNIT_LOCATION_RECORDS.append((x, y)) terrain.text = eText -def initiatePlayers(root, tag): +def initiate_players(root, tag): players = ET.SubElement(root, tag) ET.SubElement(players, "rts.Player", ID="0", resources="5") ET.SubElement(players, "rts.Player", ID="1", resources="5") -def initiateUnits(root, tag, wallRings): +def initiate_units(root, tag, wallRings): units = ET.SubElement(root, tag) - height = int(root.attrib.get("height")) - width = int(root.attrib.get("width")) - initiateResources(units, "rts.units.Unit", wallRings, height, width) - initiateBases(units, "rts.units.Unit", wallRings, height, width) - initiateWorkers(units, "rts.units.Unit", wallRings, height, width) + int(root.attrib.get("height")) + int(root.attrib.get("width")) + initiate_resources(units, "rts.units.Unit") + initiate_bases(units, "rts.units.Unit") + initiate_workers(units, "rts.units.Unit") -def initiateResources(root, tag, wallRings, height, width): +def initiate_resources(root, tag): num_resource = 4 for i in range(num_resource): @@ -60,41 +62,47 @@ def initiateResources(root, tag, wallRings, height, width): ) -def initiateBases(root, tag, wallRings, height, width): +def initiate_bases(root, tag): num_bases = 2 + index_list = SECTIONS_CHOICES.copy() + global BASE_LOCATION_RECORDS + for i in range(num_bases): - x, y = get_xy(random.randint(0, 3)) + index = random.choice(index_list) + BASE_LOCATION_RECORDS.append(index) + index_list.remove(index) + x, y = get_xy(index) ET.SubElement( root, tag, type="Base", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="10" ) -def initiateWorkers(root, tag, wallRings, height, width): +def initiate_workers(root, tag): num_worker = 2 for i in range(num_worker): - x, y = get_xy(random.randint(0, 3)) + x, y = get_xy(BASE_LOCATION_RECORDS[i]) ET.SubElement( root, tag, type="Worker", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="1" ) def get_unique_key(): - global key - key = key + 1 - return str(key) + global KEY + KEY = KEY + 1 + return str(KEY) def get_xy(index): - global unit_location_records + global UNIT_LOCATION_RECORDS - x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( - sections[index][1][0], sections[index][1][1] + x, y = random.randint(SECTIONS[index][0][0], SECTIONS[index][0][1]), random.randint( + SECTIONS[index][1][0], SECTIONS[index][1][1] ) - while (x, y) in unit_location_records: - x, y = random.randint(sections[index][0][0], sections[index][0][1]), random.randint( - sections[index][1][0], sections[index][1][1] + while (x, y) in UNIT_LOCATION_RECORDS: + x, y = random.randint(SECTIONS[index][0][0], SECTIONS[index][0][1]), random.randint( + SECTIONS[index][1][0], SECTIONS[index][1][1] ) - unit_location_records.append((x, y)) + UNIT_LOCATION_RECORDS.append((x, y)) return x, y @@ -107,19 +115,16 @@ def get_xy(index): if wallRingsLimit < 0: wallRingsLimit = 0 wallRings = random.randint(0, wallRingsLimit) - sections = [ + SECTIONS = [ ((wallRings, (width - 1) // 2), (wallRings, (height - 1) // 2)), ((width // 2, (width - 1) - wallRings), (wallRings, (height - 1) // 2)), ((wallRings, (width - 1) // 2), (height // 2, (height - 1) - wallRings)), - ((width // 2, (width - 1) - wallRings), - (height // 2, (height - 1) - wallRings)), + ((width // 2, (width - 1) - wallRings), (height // 2, (height - 1) - wallRings)), ] - initiateTerrain(root, "terrain", wallRings) - initiatePlayers(root, "players") - initiateUnits(root, "units", wallRings) - - print(unit_location_records) + initiate_terrain(root, "terrain", wallRings) + initiate_players(root, "players") + initiate_units(root, "units", wallRings) tree = ET.ElementTree(root) tree.write("PCG/maps/filename.xml") From 7587c5e2dcc73596931ccb1adee9e5691e49dbb2 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Thu, 24 Mar 2022 21:03:18 -0400 Subject: [PATCH 05/17] Update microrts --- gym_microrts/microrts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gym_microrts/microrts b/gym_microrts/microrts index e3dd5bda..2c8a6264 160000 --- a/gym_microrts/microrts +++ b/gym_microrts/microrts @@ -1 +1 @@ -Subproject commit e3dd5bda771896f10b3c8dcc3b85a7b0d391056c +Subproject commit 2c8a626498b71e44beaaac9c311cd0a25b74a275 From 5340bc41172b9b2a088d1ca5eace3bcc731ba7b4 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Thu, 24 Mar 2022 21:56:45 -0400 Subject: [PATCH 06/17] Update PCG into class --- PCG/maps/filename.xml | 2 +- PCG/pcg.py | 261 ++++++++++++++++++++++-------------------- 2 files changed, 140 insertions(+), 123 deletions(-) diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml index 1e1fed26..28d70dcd 100644 --- a/PCG/maps/filename.xml +++ b/PCG/maps/filename.xml @@ -1 +1 @@ -1111111111111111111111111111111111111111111111111111111111111111111111111111111111111000100111111111100000011111111110000001111111111000000111111111100000011111111110000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111 \ No newline at end of file +1111111111111111111111111111111111000011000000111100000000000011110000001000001111000000001000111100000000000011110000100001001111100000000000111100000000010011110000001000001111000000000000111100100000000011111000000000001111111111111111111111111111111111 \ No newline at end of file diff --git a/PCG/pcg.py b/PCG/pcg.py index 8ad2e16f..e26a8d2f 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,130 +1,147 @@ import random import xml.etree.cElementTree as ET -KEY = 15 -SECTIONS = [] -UNIT_LOCATION_RECORDS = [] -SECTIONS_CHOICES = [0, 1, 2, 3] -BASE_LOCATION_RECORDS = [] - - -def initiate_terrain(root, tag, wallRings): - terrain = ET.SubElement(root, tag) - eText = "" - global UNIT_LOCATION_RECORDS - - def get_obstacle(): - chance = 0.2 * random.random() - if random.random() < chance: - return "1" - else: - return "0" - - for y in range(height): - for x in range(width): - if y in range(0, wallRings) or y in range(height - wallRings, height): - eText += "1" - UNIT_LOCATION_RECORDS.append((x, y)) - elif x in range(0, wallRings) or x in range(height - wallRings, height): - eText += "1" - UNIT_LOCATION_RECORDS.append((x, y)) - else: - obstacle = get_obstacle() - eText += obstacle - if obstacle == "1": - UNIT_LOCATION_RECORDS.append((x, y)) - - terrain.text = eText - - -def initiate_players(root, tag): - players = ET.SubElement(root, tag) - ET.SubElement(players, "rts.Player", ID="0", resources="5") - ET.SubElement(players, "rts.Player", ID="1", resources="5") - - -def initiate_units(root, tag, wallRings): - units = ET.SubElement(root, tag) - int(root.attrib.get("height")) - int(root.attrib.get("width")) - initiate_resources(units, "rts.units.Unit") - initiate_bases(units, "rts.units.Unit") - initiate_workers(units, "rts.units.Unit") - - -def initiate_resources(root, tag): - num_resource = 4 - - for i in range(num_resource): - x, y = get_xy(i) - ET.SubElement( - root, tag, type="Resource", ID=get_unique_key(), player="-1", x=str(x), y=str(y), resources="25", hitpoints="1" - ) - - -def initiate_bases(root, tag): - num_bases = 2 - index_list = SECTIONS_CHOICES.copy() - global BASE_LOCATION_RECORDS - for i in range(num_bases): - index = random.choice(index_list) - BASE_LOCATION_RECORDS.append(index) - index_list.remove(index) - x, y = get_xy(index) - ET.SubElement( - root, tag, type="Base", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="10" - ) - - -def initiate_workers(root, tag): - num_worker = 2 - for i in range(num_worker): - x, y = get_xy(BASE_LOCATION_RECORDS[i]) - ET.SubElement( - root, tag, type="Worker", ID=get_unique_key(), player=str(i % 2), x=str(x), y=str(y), resources="0", hitpoints="1" - ) - - -def get_unique_key(): - global KEY - KEY = KEY + 1 - return str(KEY) - - -def get_xy(index): - global UNIT_LOCATION_RECORDS - - x, y = random.randint(SECTIONS[index][0][0], SECTIONS[index][0][1]), random.randint( - SECTIONS[index][1][0], SECTIONS[index][1][1] - ) - while (x, y) in UNIT_LOCATION_RECORDS: - x, y = random.randint(SECTIONS[index][0][0], SECTIONS[index][0][1]), random.randint( - SECTIONS[index][1][0], SECTIONS[index][1][1] +class PCG: + def __init__( + self, width=16, height=16, key=15, unit_location_records=[], sections_choices=[0, 1, 2, 3], base_location_records=[] + ): + self.height = height + self.width = width + self.wallRingsLimit = min(height, width) // 2 - 3 + if self.wallRingsLimit < 0: + self.wallRingsLimit = 0 + self.wallRings = random.randint(0, self.wallRingsLimit) + self.key = key + self.sections = [ + ((self.wallRings, (width - 1) // 2), (self.wallRings, (height - 1) // 2)), + ((width // 2, (width - 1) - self.wallRings), (self.wallRings, (height - 1) // 2)), + ((self.wallRings, (width - 1) // 2), (height // 2, (height - 1) - self.wallRings)), + ((width // 2, (width - 1) - self.wallRings), (height // 2, (height - 1) - self.wallRings)), + ] + self.unit_location_records = unit_location_records + self.sections_choices = sections_choices + self.base_location_records = base_location_records + + def initiate_terrain(self, root, tag, wallRings): + terrain = ET.SubElement(root, tag) + eText = "" + + def get_obstacle(): + chance = 0.2 * random.random() + if random.random() < chance: + return "1" + else: + return "0" + + for y in range(self.height): + for x in range(self.width): + if y in range(0, wallRings) or y in range(self.height - wallRings, self.height): + eText += "1" + self.unit_location_records.append((x, y)) + elif x in range(0, wallRings) or x in range(self.height - wallRings, self.height): + eText += "1" + self.unit_location_records.append((x, y)) + else: + obstacle = get_obstacle() + eText += obstacle + if obstacle == "1": + self.unit_location_records.append((x, y)) + + terrain.text = eText + + def initiate_players(self, root, tag): + players = ET.SubElement(root, tag) + ET.SubElement(players, "rts.Player", ID="0", resources="5") + ET.SubElement(players, "rts.Player", ID="1", resources="5") + + def initiate_units(self, root, tag): + units = ET.SubElement(root, tag) + int(root.attrib.get("height")) + int(root.attrib.get("width")) + self.initiate_resources(units, "rts.units.Unit") + self.initiate_bases(units, "rts.units.Unit") + self.initiate_workers(units, "rts.units.Unit") + + def initiate_resources(self, root, tag): + num_resource = 4 + + for i in range(num_resource): + x, y = self.get_xy(i) + ET.SubElement( + root, + tag, + type="Resource", + ID=self.get_unique_key(), + player="-1", + x=str(x), + y=str(y), + resources="25", + hitpoints="1", + ) + + def initiate_bases(self, root, tag): + num_bases = 2 + index_list = self.sections_choices.copy() + + for i in range(num_bases): + index = random.choice(index_list) + self.base_location_records.append(index) + index_list.remove(index) + x, y = self.get_xy(index) + ET.SubElement( + root, + tag, + type="Base", + ID=self.get_unique_key(), + player=str(i % 2), + x=str(x), + y=str(y), + resources="0", + hitpoints="10", + ) + + def initiate_workers(self, root, tag): + num_worker = 2 + for i in range(num_worker): + x, y = self.get_xy(self.base_location_records[i]) + ET.SubElement( + root, + tag, + type="Worker", + ID=self.get_unique_key(), + player=str(i % 2), + x=str(x), + y=str(y), + resources="0", + hitpoints="1", + ) + + def get_unique_key(self): + self.key = self.key + 1 + return str(self.key) + + def get_xy(self, index): + x, y = random.randint(self.sections[index][0][0], self.sections[index][0][1]), random.randint( + self.sections[index][1][0], self.sections[index][1][1] ) - UNIT_LOCATION_RECORDS.append((x, y)) - return x, y + while (x, y) in self.unit_location_records: + x, y = random.randint(self.sections[index][0][0], self.sections[index][0][1]), random.randint( + self.sections[index][1][0], self.sections[index][1][1] + ) + self.unit_location_records.append((x, y)) + return x, y + + def get_map(self): + root = ET.Element("rts.PhysicalGameState", width="16", height="16") + self.initiate_terrain(root, "terrain", self.wallRings) + self.initiate_players(root, "players") + self.initiate_units(root, "units") + tree = ET.ElementTree(root) + tree.write("PCG/maps/filename.xml") + return tree if __name__ == "__main__": - - root = ET.Element("rts.PhysicalGameState", width="16", height="16") - height = int(root.attrib.get("height")) - width = int(root.attrib.get("width")) - wallRingsLimit = min(height, width) // 2 - 3 - if wallRingsLimit < 0: - wallRingsLimit = 0 - wallRings = random.randint(0, wallRingsLimit) - SECTIONS = [ - ((wallRings, (width - 1) // 2), (wallRings, (height - 1) // 2)), - ((width // 2, (width - 1) - wallRings), (wallRings, (height - 1) // 2)), - ((wallRings, (width - 1) // 2), (height // 2, (height - 1) - wallRings)), - ((width // 2, (width - 1) - wallRings), (height // 2, (height - 1) - wallRings)), - ] - - initiate_terrain(root, "terrain", wallRings) - initiate_players(root, "players") - initiate_units(root, "units", wallRings) - - tree = ET.ElementTree(root) - tree.write("PCG/maps/filename.xml") + pcg = PCG() + pcg.get_map() From 50d85fe76112eb134dc930845b709ad7c202b550 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Wed, 30 Mar 2022 21:27:58 -0400 Subject: [PATCH 07/17] Add readme and argparse --- PCG/README.md | 3 +++ PCG/maps/filename.xml | 2 +- PCG/pcg.py | 17 ++++++++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 PCG/README.md diff --git a/PCG/README.md b/PCG/README.md new file mode 100644 index 00000000..5fa5813b --- /dev/null +++ b/PCG/README.md @@ -0,0 +1,3 @@ +Run this command to get a PCG generated map: +cd PCG +python pcg.py --width 16 --height 16 \ No newline at end of file diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml index 28d70dcd..dffe29ee 100644 --- a/PCG/maps/filename.xml +++ b/PCG/maps/filename.xml @@ -1 +1 @@ -1111111111111111111111111111111111000011000000111100000000000011110000001000001111000000001000111100000000000011110000100001001111100000000000111100000000010011110000001000001111000000000000111100100000000011111000000000001111111111111111111111111111111111 \ No newline at end of file +111111111111100010001011101110000001100010000011100100000001100000000001100000001001100000001101101000000001100010000101101000000001111111111111 \ No newline at end of file diff --git a/PCG/pcg.py b/PCG/pcg.py index e26a8d2f..e9a71ca1 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,6 +1,16 @@ +import argparse import random import xml.etree.cElementTree as ET +def parse_args(): + # fmt: off + parser = argparse.ArgumentParser() + parser.add_argument('--width', type=int, default=16,help='the width of the map') + parser.add_argument('--height', type=int, default=16,help='the height of the map') + + args = parser.parse_args() + # fmt: on + return args class PCG: def __init__( @@ -133,15 +143,16 @@ def get_xy(self, index): return x, y def get_map(self): - root = ET.Element("rts.PhysicalGameState", width="16", height="16") + root = ET.Element("rts.PhysicalGameState", width=str(self.width), height=str(self.height)) self.initiate_terrain(root, "terrain", self.wallRings) self.initiate_players(root, "players") self.initiate_units(root, "units") tree = ET.ElementTree(root) - tree.write("PCG/maps/filename.xml") + tree.write("./maps/filename.xml") return tree if __name__ == "__main__": - pcg = PCG() + args = parse_args() + pcg = PCG(width=args.width, height=args.height) pcg.get_map() From be9d8edca63738f9f99ba9516799845bee5994ef Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Wed, 30 Mar 2022 21:30:12 -0400 Subject: [PATCH 08/17] Update README.md --- PCG/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PCG/README.md b/PCG/README.md index 5fa5813b..f8d595a2 100644 --- a/PCG/README.md +++ b/PCG/README.md @@ -1,3 +1,5 @@ Run this command to get a PCG generated map: +```bash cd PCG -python pcg.py --width 16 --height 16 \ No newline at end of file +python pcg.py --width 16 --height 16 +``` From 566d3473bbdddbbd19c2462fe514669b291ca3d1 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Wed, 30 Mar 2022 21:31:35 -0400 Subject: [PATCH 09/17] Update pcg.py --- PCG/pcg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PCG/pcg.py b/PCG/pcg.py index e9a71ca1..a7788741 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -2,6 +2,7 @@ import random import xml.etree.cElementTree as ET + def parse_args(): # fmt: off parser = argparse.ArgumentParser() @@ -12,6 +13,7 @@ def parse_args(): # fmt: on return args + class PCG: def __init__( self, width=16, height=16, key=15, unit_location_records=[], sections_choices=[0, 1, 2, 3], base_location_records=[] From e3dece61f005bf450920fb00841639ba0aa517fb Mon Sep 17 00:00:00 2001 From: Costa Huang Date: Thu, 31 Mar 2022 21:54:06 -0400 Subject: [PATCH 10/17] Add more documentation --- .gitignore | 1 + PCG/README.md | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9e6bcf3a..a1e064a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +filename.xml *.temp.csv debug.sh.docker.sh .DS_Store diff --git a/PCG/README.md b/PCG/README.md index f8d595a2..1b237434 100644 --- a/PCG/README.md +++ b/PCG/README.md @@ -1,5 +1,15 @@ -Run this command to get a PCG generated map: +# Procedural Content Generation for Maps + +Run this command to get a PCG (Procedural Content Generation) generated map: + ```bash cd PCG python pcg.py --width 16 --height 16 ``` + +Such a command would generate a map at `maps/filename.xml`. You may use microrts's GUI editor at `gym_microrts/microrts/src/gui/frontend/FrontEnd.java` to visualize the map. + +``` +bash build.sh +java -cp gym_microrts/microrts/microrts.jar gui.frontend.FrontEnd +``` From a50aff7164f623ab38df15380a08cd27500ba05b Mon Sep 17 00:00:00 2001 From: Costa Huang Date: Thu, 31 Mar 2022 21:54:28 -0400 Subject: [PATCH 11/17] remove filename.xml --- PCG/maps/filename.xml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 PCG/maps/filename.xml diff --git a/PCG/maps/filename.xml b/PCG/maps/filename.xml deleted file mode 100644 index dffe29ee..00000000 --- a/PCG/maps/filename.xml +++ /dev/null @@ -1 +0,0 @@ -111111111111100010001011101110000001100010000011100100000001100000000001100000001001100000001101101000000001100010000101101000000001111111111111 \ No newline at end of file From 23cc2340410d26af0ac10b3e8b9dfb707b28ac45 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Thu, 14 Apr 2022 23:38:07 -0400 Subject: [PATCH 12/17] Allow generating multiple maps --- PCG/maps/wall-1 | 15 --------------- PCG/pcg.py | 24 +++++++++++++++++++----- 2 files changed, 19 insertions(+), 20 deletions(-) delete mode 100644 PCG/maps/wall-1 diff --git a/PCG/maps/wall-1 b/PCG/maps/wall-1 deleted file mode 100644 index 5903a1cd..00000000 --- a/PCG/maps/wall-1 +++ /dev/null @@ -1,15 +0,0 @@ - - 1111111110000001100000011000000110000001100000011000000111111111 - - - - - - - - - - - - - diff --git a/PCG/pcg.py b/PCG/pcg.py index a7788741..41d6ed11 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,5 +1,6 @@ import argparse import random +import os import xml.etree.cElementTree as ET @@ -8,6 +9,7 @@ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--width', type=int, default=16,help='the width of the map') parser.add_argument('--height', type=int, default=16,help='the height of the map') + parser.add_argument('--num-maps', type=int, default=200, help='the number of the maps to generate') args = parser.parse_args() # fmt: on @@ -16,7 +18,7 @@ def parse_args(): class PCG: def __init__( - self, width=16, height=16, key=15, unit_location_records=[], sections_choices=[0, 1, 2, 3], base_location_records=[] + self, width=16, height=16, key=15, unit_location_records=[], sections_choices=[0, 1, 2, 3], base_location_records=[], num_maps=200 ): self.height = height self.width = width @@ -34,6 +36,7 @@ def __init__( self.unit_location_records = unit_location_records self.sections_choices = sections_choices self.base_location_records = base_location_records + self.num_maps = num_maps def initiate_terrain(self, root, tag, wallRings): terrain = ET.SubElement(root, tag) @@ -144,17 +147,28 @@ def get_xy(self, index): self.unit_location_records.append((x, y)) return x, y - def get_map(self): + def get_map(self, mapKey): root = ET.Element("rts.PhysicalGameState", width=str(self.width), height=str(self.height)) self.initiate_terrain(root, "terrain", self.wallRings) self.initiate_players(root, "players") self.initiate_units(root, "units") tree = ET.ElementTree(root) - tree.write("./maps/filename.xml") + tree.write(os.path.join("PCG/maps/", "pcgMap" + "_" + str(mapKey) + ".xml")) + self.reset() + return tree + def reset(self): + self.unit_location_records = [] + self.base_location_records = [] + + def get_maps(self): + for i in range(self.num_maps): + self.get_map(i) if __name__ == "__main__": + if not os.path.exists("PCG/maps"): + os.makedirs("PCG/maps") args = parse_args() - pcg = PCG(width=args.width, height=args.height) - pcg.get_map() + pcg = PCG(width=args.width, height=args.height, num_maps=args.num_maps) + pcg.get_maps() From 3fe0424065afdd677bcf86bd317832cae0dbb840 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:00:10 -0400 Subject: [PATCH 13/17] Clean up --- PCG/pcg.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/PCG/pcg.py b/PCG/pcg.py index 41d6ed11..b208a196 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,6 +1,6 @@ import argparse -import random import os +import random import xml.etree.cElementTree as ET @@ -18,7 +18,14 @@ def parse_args(): class PCG: def __init__( - self, width=16, height=16, key=15, unit_location_records=[], sections_choices=[0, 1, 2, 3], base_location_records=[], num_maps=200 + self, + width=16, + height=16, + key=15, + unit_location_records=[], + sections_choices=[0, 1, 2, 3], + base_location_records=[], + num_maps=200, ): self.height = height self.width = width @@ -155,7 +162,7 @@ def get_map(self, mapKey): tree = ET.ElementTree(root) tree.write(os.path.join("PCG/maps/", "pcgMap" + "_" + str(mapKey) + ".xml")) self.reset() - + return tree def reset(self): @@ -166,6 +173,7 @@ def get_maps(self): for i in range(self.num_maps): self.get_map(i) + if __name__ == "__main__": if not os.path.exists("PCG/maps"): os.makedirs("PCG/maps") From 865682ac545eadc8730bf5227484224af5f34353 Mon Sep 17 00:00:00 2001 From: xluox <37052306+xluox@users.noreply.github.com> Date: Thu, 28 Apr 2022 21:26:17 -0400 Subject: [PATCH 14/17] Add seed and update vec_env to read in PCG maps folder --- PCG/pcg.py | 12 +++++++++--- gym_microrts/envs/vec_env.py | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/PCG/pcg.py b/PCG/pcg.py index b208a196..7f45c325 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -1,6 +1,7 @@ import argparse import os import random +import time import xml.etree.cElementTree as ET @@ -9,10 +10,14 @@ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--width', type=int, default=16,help='the width of the map') parser.add_argument('--height', type=int, default=16,help='the height of the map') - parser.add_argument('--num-maps', type=int, default=200, help='the number of the maps to generate') - + parser.add_argument('--num-maps', type=int, default=199, help='the number of the maps to generate') + parser.add_argument('--seed', type=int, default=1, + help='seed of the experiment') args = parser.parse_args() # fmt: on + + if not args.seed: + args.seed = int(time.time()) return args @@ -160,7 +165,7 @@ def get_map(self, mapKey): self.initiate_players(root, "players") self.initiate_units(root, "units") tree = ET.ElementTree(root) - tree.write(os.path.join("PCG/maps/", "pcgMap" + "_" + str(mapKey) + ".xml")) + tree.write(os.path.join("PCG/maps/", "pcg_map" + "_" + str(mapKey) + ".xml")) self.reset() return tree @@ -178,5 +183,6 @@ def get_maps(self): if not os.path.exists("PCG/maps"): os.makedirs("PCG/maps") args = parse_args() + random.seed(args.seed) pcg = PCG(width=args.width, height=args.height, num_maps=args.num_maps) pcg.get_maps() diff --git a/gym_microrts/envs/vec_env.py b/gym_microrts/envs/vec_env.py index cb4b9a79..9fb3109c 100644 --- a/gym_microrts/envs/vec_env.py +++ b/gym_microrts/envs/vec_env.py @@ -12,6 +12,7 @@ from PIL import Image import gym_microrts +import PCG class MicroRTSGridModeVecEnv: @@ -59,7 +60,8 @@ def __init__( self.microrts_path = os.path.join(gym_microrts.__path__[0], "microrts") # prepare training maps - self.cycle_maps = list(map(lambda i: os.path.join(self.microrts_path, i), cycle_maps)) + self.pcg_map_path = os.path.join(PCG.__path__[0], "maps") + self.cycle_maps = list(map(lambda i: os.path.join(self.pcg_map_path, i), cycle_maps)) self.next_map = cycle(self.cycle_maps) # read map From 432abecfe8d208f1c6e2259cadc23cdfd242777e Mon Sep 17 00:00:00 2001 From: xluox Date: Tue, 10 May 2022 22:04:34 -0400 Subject: [PATCH 15/17] update readme --- PCG/README.md | 2 +- PCG/pcg.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PCG/README.md b/PCG/README.md index 1b237434..9bd3bd44 100644 --- a/PCG/README.md +++ b/PCG/README.md @@ -4,7 +4,7 @@ Run this command to get a PCG (Procedural Content Generation) generated map: ```bash cd PCG -python pcg.py --width 16 --height 16 +python pcg.py --width 16 --height 16 --num-maps 200 ``` Such a command would generate a map at `maps/filename.xml`. You may use microrts's GUI editor at `gym_microrts/microrts/src/gui/frontend/FrontEnd.java` to visualize the map. diff --git a/PCG/pcg.py b/PCG/pcg.py index 7f45c325..a40f2ebe 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -10,7 +10,7 @@ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--width', type=int, default=16,help='the width of the map') parser.add_argument('--height', type=int, default=16,help='the height of the map') - parser.add_argument('--num-maps', type=int, default=199, help='the number of the maps to generate') + parser.add_argument('--num-maps', type=int, default=200, help='the number of the maps to generate') parser.add_argument('--seed', type=int, default=1, help='seed of the experiment') args = parser.parse_args() From a0ad79d7e1e5cd2041f34761a6d9f08ba8d472c7 Mon Sep 17 00:00:00 2001 From: xluox Date: Wed, 8 Jun 2022 19:51:36 -0400 Subject: [PATCH 16/17] Fix the logic of resetting wall rings Add flag to turn on varying wall rings and non varying wall rings --- PCG/pcg.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/PCG/pcg.py b/PCG/pcg.py index a40f2ebe..5a294e00 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -13,6 +13,7 @@ def parse_args(): parser.add_argument('--num-maps', type=int, default=200, help='the number of the maps to generate') parser.add_argument('--seed', type=int, default=1, help='seed of the experiment') + parser.add_argument('--wall-rings-vary', type=bool, default=False, help='the switch to turn on varying wall rings') args = parser.parse_args() # fmt: on @@ -31,26 +32,31 @@ def __init__( sections_choices=[0, 1, 2, 3], base_location_records=[], num_maps=200, + wall_rings_vary = False ): self.height = height self.width = width + self.wall_rings_vary = wall_rings_vary self.wallRingsLimit = min(height, width) // 2 - 3 if self.wallRingsLimit < 0: self.wallRingsLimit = 0 - self.wallRings = random.randint(0, self.wallRingsLimit) + if self.wall_rings_vary: + self.wall_rings = random.randint(0, self.wallRingsLimit) + else: + self.wall_rings = 0 self.key = key self.sections = [ - ((self.wallRings, (width - 1) // 2), (self.wallRings, (height - 1) // 2)), - ((width // 2, (width - 1) - self.wallRings), (self.wallRings, (height - 1) // 2)), - ((self.wallRings, (width - 1) // 2), (height // 2, (height - 1) - self.wallRings)), - ((width // 2, (width - 1) - self.wallRings), (height // 2, (height - 1) - self.wallRings)), + ((self.wall_rings, (width - 1) // 2), (self.wall_rings, (height - 1) // 2)), + ((width // 2, (width - 1) - self.wall_rings), (self.wall_rings, (height - 1) // 2)), + ((self.wall_rings, (width - 1) // 2), (height // 2, (height - 1) - self.wall_rings)), + ((width // 2, (width - 1) - self.wall_rings), (height // 2, (height - 1) - self.wall_rings)), ] self.unit_location_records = unit_location_records self.sections_choices = sections_choices self.base_location_records = base_location_records self.num_maps = num_maps - def initiate_terrain(self, root, tag, wallRings): + def initiate_terrain(self, root, tag, wall_rings): terrain = ET.SubElement(root, tag) eText = "" @@ -63,10 +69,10 @@ def get_obstacle(): for y in range(self.height): for x in range(self.width): - if y in range(0, wallRings) or y in range(self.height - wallRings, self.height): + if y in range(0, wall_rings) or y in range(self.height - wall_rings, self.height): eText += "1" self.unit_location_records.append((x, y)) - elif x in range(0, wallRings) or x in range(self.height - wallRings, self.height): + elif x in range(0, wall_rings) or x in range(self.height - wall_rings, self.height): eText += "1" self.unit_location_records.append((x, y)) else: @@ -161,7 +167,7 @@ def get_xy(self, index): def get_map(self, mapKey): root = ET.Element("rts.PhysicalGameState", width=str(self.width), height=str(self.height)) - self.initiate_terrain(root, "terrain", self.wallRings) + self.initiate_terrain(root, "terrain", self.wall_rings) self.initiate_players(root, "players") self.initiate_units(root, "units") tree = ET.ElementTree(root) @@ -173,6 +179,17 @@ def get_map(self, mapKey): def reset(self): self.unit_location_records = [] self.base_location_records = [] + self.reset_wall_rings() + + def reset_wall_rings(self): + if not self.wall_rings_vary: return + self.wall_rings = random.randint(0, self.wallRingsLimit) + self.sections = [ + ((self.wall_rings, (self.width - 1) // 2), (self.wall_rings, (self.height - 1) // 2)), + ((self.width // 2, (self.width - 1) - self.wall_rings), (self.wall_rings, (self.height - 1) // 2)), + ((self.wall_rings, (self.width - 1) // 2), (self.height // 2, (self.height - 1) - self.wall_rings)), + ((self.width // 2, (self.width - 1) - self.wall_rings), (self.height // 2, (self.height - 1) - self.wall_rings)), + ] def get_maps(self): for i in range(self.num_maps): @@ -184,5 +201,5 @@ def get_maps(self): os.makedirs("PCG/maps") args = parse_args() random.seed(args.seed) - pcg = PCG(width=args.width, height=args.height, num_maps=args.num_maps) + pcg = PCG(width=args.width, height=args.height, num_maps=args.num_maps, wall_rings_vary=args.wall_rings_vary) pcg.get_maps() From 9935c4f783405bf035b8ce332ca3f41884fb0ec9 Mon Sep 17 00:00:00 2001 From: xluox Date: Wed, 8 Jun 2022 19:59:21 -0400 Subject: [PATCH 17/17] Clean up --- PCG/pcg.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PCG/pcg.py b/PCG/pcg.py index 5a294e00..f8e88ecb 100644 --- a/PCG/pcg.py +++ b/PCG/pcg.py @@ -32,7 +32,7 @@ def __init__( sections_choices=[0, 1, 2, 3], base_location_records=[], num_maps=200, - wall_rings_vary = False + wall_rings_vary=False, ): self.height = height self.width = width @@ -182,7 +182,8 @@ def reset(self): self.reset_wall_rings() def reset_wall_rings(self): - if not self.wall_rings_vary: return + if not self.wall_rings_vary: + return self.wall_rings = random.randint(0, self.wallRingsLimit) self.sections = [ ((self.wall_rings, (self.width - 1) // 2), (self.wall_rings, (self.height - 1) // 2)),