+import collections
+from dataclasses import dataclass
+import itertools
+from os import error
import random
+from itertools import product
+
import WorldTemplates
import World
import GameObject
import Debug
+
def generateWorld():
template = WorldTemplates.worldTemplate6
output = [[]]
output.insert(y, row)
return output
-def generateWorldGrowingRectangles():
+def generateWorldGrowingRectangles(minMaxRooms, iterations):
outputWorld = [[]]
- # generate default
- # TODO do this with a comprehension or something nice :)
for y in range(World.worldHeight):
row = []
for x in range(World.worldWidth):
row.append(cell)
outputWorld.insert(y, row)
-
-
class Room:
def __init__(self, point):
self.cells = [[]]
self.cells[0].append(point)
def growNorth(self):
- #newRow = [(tup[0], tup[1] - 1) for _, tup in enumerate(self.cells[0])]
- # I want to create a new row, that is equal to the first row, but the y coord of each cell is -1
newRow = []
for tup in self.cells[0]:
newRow.append((tup[0], tup[1] - 1))
self.minX -= 1
def growSouth(self):
- #newRow = [(tup[0], tup[1] + 1) for _, tup in enumerate(self.cells[-1])]
newRow = []
for tup in self.cells[-1]:
newRow.append((tup[0], tup[1] + 1))
# choose starting points
# TODO make this controllable
- points = random.randint(10, 12)
- #points = 1
-
+ points = random.randint(*minMaxRooms)
rooms = []
- for _ in range(points):
- #maybe limit how close these can be?
- y = random.randint(1, World.worldHeight - 2)
- x = random.randint(1, World.worldWidth - 2)
- #cell = GameObject.WorldCell()
- #cell.objects.append(GameObject.GameObject(x, y, "floor_tile", False))
- #outputWorld[y][x] = cell
- rooms.append(Room((x, y)))
- Debug.worldGenDebugRects.append((x, y, (0, 255, 0)))
+ excludeList = []
+ possible = True
+ count = 0
+
+ while count != points and possible:
+ possible = len([t for t in list(itertools.product(range(1, World.worldWidth - 2), range(1, World.worldWidth - 2))) if t not in excludeList]) > 0
+ coord = (random.randint(1, World.worldWidth - 2), random.randint(1, World.worldHeight - 2))
+ if coord not in excludeList:
+ excludeList.append(coord)
+ excludeList.append((coord[0] + 1, coord[1]))
+ excludeList.append((coord[0] - 1, coord[1]))
+ excludeList.append((coord[0], coord[1] + 1))
+ excludeList.append((coord[0], coord[1] - 1))
+ excludeList.append((coord[0] + 1, coord[1] - 1))
+ excludeList.append((coord[0] + 1, coord[1] + 1))
+ excludeList.append((coord[0] - 1, coord[1] - 1))
+ excludeList.append((coord[0] - 1, coord[1] + 1))
+ rooms.append(Room(coord))
+ Debug.worldGenDebugRects.append((coord[0], coord[1], (255, 155, 0)))
+ count += 1
+ else: continue
+ @dataclass
+ class Rect:
+ x1 : int = 0
+ y1 : int = 0
+ x2 : int = 0
+ y2 : int = 0
+
+ def testCollisions(rA, dir):
+ for rB in [item for item in rooms if not item == rA]:
+ if collide(Rect(rA.minX, rA.minY, rA.maxX, rA.maxY),
+ Rect(rB.minX, rB.minY, rB.maxX, rB.maxY),
+ dir):
+ return True
+ return False
+
+ def collide (a, b, dir):
+ #inflate b to account for 1 block border, idk why this needs to be 2 and not 1 /shrug
+ b = Rect(b.x1 - 2, b.y1 - 2, b.x2 + 2, b.y2 + 2)
+ if dir == (-1, 0):
+ a.x1 -= 1
+ elif dir == (1, 0):
+ a.x2 += 1
+ elif dir == (0, -1):
+ a.y1 -= 1
+ elif dir == (0, 1):
+ a.y2 += 1
+
+ return (a.x1 < b.x2 and
+ a.x2 > b.x1 and
+ a.y1 < b.y2 and
+ a.y2 > b.y1)
+
+
# Generate rooms
# TODO experiment with this
# TODO make controllable
- iterations = 12
for _ in range(iterations):
for r in rooms:
direction = random.randint(0, 3)
- # OPTIONAL EXTRA: CHECK IT WONT INTERESCT WITH OTHER ONE
if direction == 0:
if r.minY > 1:
- r.growNorth()
+ if not testCollisions(r, (0, -1)):
+ r.growNorth()
elif direction == 1:
if r.maxX < World.worldWidth - 2:
- r.growEast()
+ if not testCollisions(r, (1, 0)):
+ r.growEast()
elif direction == 2:
if r.maxY < World.worldHeight - 2:
- r.growSouth()
+ if not testCollisions(r, (0, 1)):
+ r.growSouth()
elif direction == 3:
if r.minX > 1:
- r.growWest()
+ if not testCollisions(r, (-1, 0)):
+ r.growWest()
# paint generated rooms to output
for r in rooms:
- #print ("\n====================================\n")
- #print(f'minX {r.minX} maxX {r.maxX} minY {r.minY} maxY {r.maxY}')
+ debugCol = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
for y in range(len(r.cells)):
- #print (r.cells[y])
for _, x in enumerate(r.cells[y]):
cell = GameObject.WorldCell()
cell.objects.append(GameObject.GameObject(x[0], x[1], "floor_tile", False))
outputWorld[x[1]][x[0]] = cell
- Debug.worldGenDebugRects.append((x[0], x[1], (0, 255, 255)))
+ Debug.worldGenDebugRects.append((x[0], x[1], debugCol))
return outputWorld
-
-# So to grow north we need to prepend a new list of the same "width"
-# the coords are the first lists coords -1
-# to grow east we need to append 1 to each list
-# to grow south we need to APPEND a new list of same width
-# to grow west we PREPEND one to each