From 5aaef15b2ba269100e1ae0e42a25c2e1b1c18217 Mon Sep 17 00:00:00 2001 From: Charles Peyrat Date: Sun, 10 Jan 2021 23:38:29 +0100 Subject: [PATCH 1/5] Add new room type : chunk rooms --- squirrelbattle/mapgeneration/broguelike.py | 61 +++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/squirrelbattle/mapgeneration/broguelike.py b/squirrelbattle/mapgeneration/broguelike.py index 21408ae..a2d1532 100644 --- a/squirrelbattle/mapgeneration/broguelike.py +++ b/squirrelbattle/mapgeneration/broguelike.py @@ -13,7 +13,7 @@ DEFAULT_PARAMS = { "max_rooms": 20, "max_room_tries": 15, "cross_room": 1, - "corridor_chance": .6, + "corridor_chance": .2, "min_v_corr": 2, "max_v_corr": 6, "min_h_corr": 4, @@ -24,6 +24,10 @@ DEFAULT_PARAMS = { "loop_max": 5, "loop_threshold": 15, "spawn_per_region": [1, 2], + "room_chances" : { + "circular" : 5, + "chunks" : 1, + }, } def dist(level, y1, x1, y2, x2): @@ -253,6 +257,47 @@ class Generator: return y + length * dy, x + length * dx, dy, dx + def create_chunk_room(self, spawnable: bool = True) \ + -> Tuple[List[List[Tile]], int, int, int, int]: + """ + Create and return as a tile grid a room that is composed of multiple + overlapping circles of the same radius + Also return door info so we know how to place the room in the level + """ + height, width = 15, 15 + nb_chunks, r = 6, 3 + + h_sup, w_sup, h_off, w_off = self.corr_meta_info() + room = [[Tile.EMPTY] * (width + w_sup) \ + for _dummy in range(height + h_sup)] + + def draw_chunk(room, y, x): + for i in range(y - r, y + r + 1): + d = (y - i)**2 + for j in range(x - r, x + r + 1): + if d + (x - j)**2 < r**2: + room[i][j] = Tile.FLOOR + + draw_chunk(room, height//2 + 1, width//2 + 1) + + min_w, max_w = w_off + r + 1, width + w_off - r -1 + min_h, max_h = h_off + r + 1, height + h_off - r - 1 + for i in range(nb_chunks): + y, x = randint(min_h, max_h), randint(min_w, max_w) + while room[y][x] != Tile.FLOOR: + y, x = randint(min_h, max_h), randint(min_w, max_w) + draw_chunk(room, y, x) + + # log all placed tiles as spawn positions + if spawnable: + self.register_spawn_area(room) + + # attach exit + door_y, door_x, dy, dx = self.attach_door(room, h_sup, w_sup, + h_off, w_off) + + return room, door_y, door_x, dy, dx + def create_circular_room(self, spawnable: bool = True) \ -> Tuple[List[List[Tile]], int, int, int, int]: """ @@ -303,7 +348,19 @@ class Generator: door info. Set spawnable to False is the room should be marked as a potential spawning region on the map """ - return self.create_circular_room() + coef_dict = self.params["room_chances"] + sum_coefs = sum(coef_dict[key] for key in coef_dict) + target = randint(1, sum_coefs) + for key in coef_dict: + if target > coef_dict[key]: + target -= coef_dict[key] + else: + break + + if key == "circular": + return self.create_circular_room(spawnable = spawnable) + elif key == "chunks": + return self.create_chunk_room(spawnable = spawnable) def register_spawn_area(self, area: List[List[Tile]]) -> None: """ From c854d4157916a4abe0909b8de0eeff2954541711 Mon Sep 17 00:00:00 2001 From: Charles Peyrat Date: Mon, 11 Jan 2021 01:18:20 +0100 Subject: [PATCH 2/5] Fix merging mistakes and chunk rooms --- squirrelbattle/mapgeneration/broguelike.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/squirrelbattle/mapgeneration/broguelike.py b/squirrelbattle/mapgeneration/broguelike.py index a2d1532..6cdf3f8 100644 --- a/squirrelbattle/mapgeneration/broguelike.py +++ b/squirrelbattle/mapgeneration/broguelike.py @@ -278,7 +278,7 @@ class Generator: if d + (x - j)**2 < r**2: room[i][j] = Tile.FLOOR - draw_chunk(room, height//2 + 1, width//2 + 1) + draw_chunk(room, h_off + height//2 + 1, w_off + width//2 + 1) min_w, max_w = w_off + r + 1, width + w_off - r -1 min_h, max_h = h_off + r + 1, height + h_off - r - 1 @@ -381,8 +381,8 @@ class Generator: top left corner of the room on the level, then log them as a spawnable region """ - if self.queued_area != None: - translated_area = [[y+ry, x+rx] for ry, rx in self.queued_area] + if self.queued_area is not None: + translated_area = [[y + ry, x + rx] for ry, rx in self.queued_area] self.spawn_areas.append(translated_area) self.queued_area = None @@ -391,11 +391,6 @@ class Generator: Populate every spawnable area with some randomly chosen, randomly placed entity """ - if self.queued_area is not None: - translated_area = [[y + ry, x + rx] for ry, rx in self.queued_area] - self.spawn_areas.append(translated_area) - self.queued_area = None - min_c, max_c = self.params["spawn_per_region"] for region in self.spawn_areas: entity_count = randint(min_c, max_c) From 79d8ef3a442f8f0a61d7af31a43e64bb145256e1 Mon Sep 17 00:00:00 2001 From: Charles Peyrat Date: Sun, 10 Jan 2021 23:38:29 +0100 Subject: [PATCH 3/5] Add new room type : chunk rooms --- squirrelbattle/mapgeneration/broguelike.py | 61 +++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/squirrelbattle/mapgeneration/broguelike.py b/squirrelbattle/mapgeneration/broguelike.py index f746f37..550e90c 100644 --- a/squirrelbattle/mapgeneration/broguelike.py +++ b/squirrelbattle/mapgeneration/broguelike.py @@ -13,7 +13,7 @@ DEFAULT_PARAMS = { "max_rooms": 20, "max_room_tries": 15, "cross_room": 1, - "corridor_chance": .6, + "corridor_chance": .2, "min_v_corr": 2, "max_v_corr": 6, "min_h_corr": 4, @@ -24,6 +24,10 @@ DEFAULT_PARAMS = { "loop_max": 5, "loop_threshold": 15, "spawn_per_region": [1, 2], + "room_chances" : { + "circular" : 5, + "chunks" : 1, + }, } @@ -254,6 +258,47 @@ class Generator: return y + length * dy, x + length * dx, dy, dx + def create_chunk_room(self, spawnable: bool = True) \ + -> Tuple[List[List[Tile]], int, int, int, int]: + """ + Create and return as a tile grid a room that is composed of multiple + overlapping circles of the same radius + Also return door info so we know how to place the room in the level + """ + height, width = 15, 15 + nb_chunks, r = 6, 3 + + h_sup, w_sup, h_off, w_off = self.corr_meta_info() + room = [[Tile.EMPTY] * (width + w_sup) \ + for _dummy in range(height + h_sup)] + + def draw_chunk(room, y, x): + for i in range(y - r, y + r + 1): + d = (y - i)**2 + for j in range(x - r, x + r + 1): + if d + (x - j)**2 < r**2: + room[i][j] = Tile.FLOOR + + draw_chunk(room, height//2 + 1, width//2 + 1) + + min_w, max_w = w_off + r + 1, width + w_off - r -1 + min_h, max_h = h_off + r + 1, height + h_off - r - 1 + for i in range(nb_chunks): + y, x = randint(min_h, max_h), randint(min_w, max_w) + while room[y][x] != Tile.FLOOR: + y, x = randint(min_h, max_h), randint(min_w, max_w) + draw_chunk(room, y, x) + + # log all placed tiles as spawn positions + if spawnable: + self.register_spawn_area(room) + + # attach exit + door_y, door_x, dy, dx = self.attach_door(room, h_sup, w_sup, + h_off, w_off) + + return room, door_y, door_x, dy, dx + def create_circular_room(self, spawnable: bool = True) \ -> Tuple[List[List[Tile]], int, int, int, int]: """ @@ -304,7 +349,19 @@ class Generator: door info. Set spawnable to False is the room should be marked as a potential spawning region on the map """ - return self.create_circular_room() + coef_dict = self.params["room_chances"] + sum_coefs = sum(coef_dict[key] for key in coef_dict) + target = randint(1, sum_coefs) + for key in coef_dict: + if target > coef_dict[key]: + target -= coef_dict[key] + else: + break + + if key == "circular": + return self.create_circular_room(spawnable = spawnable) + elif key == "chunks": + return self.create_chunk_room(spawnable = spawnable) def register_spawn_area(self, area: List[List[Tile]]) -> None: """ From 03c45a970c1985e9bae3f4bd917a14ba0c22edf9 Mon Sep 17 00:00:00 2001 From: Charles Peyrat Date: Mon, 11 Jan 2021 01:18:20 +0100 Subject: [PATCH 4/5] Fix merging mistakes and chunk rooms --- squirrelbattle/mapgeneration/broguelike.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/squirrelbattle/mapgeneration/broguelike.py b/squirrelbattle/mapgeneration/broguelike.py index 550e90c..62c8b03 100644 --- a/squirrelbattle/mapgeneration/broguelike.py +++ b/squirrelbattle/mapgeneration/broguelike.py @@ -279,7 +279,7 @@ class Generator: if d + (x - j)**2 < r**2: room[i][j] = Tile.FLOOR - draw_chunk(room, height//2 + 1, width//2 + 1) + draw_chunk(room, h_off + height//2 + 1, w_off + width//2 + 1) min_w, max_w = w_off + r + 1, width + w_off - r -1 min_h, max_h = h_off + r + 1, height + h_off - r - 1 From 7b019ce1491635fa7a3646af3f88ed489b329a81 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Mon, 11 Jan 2021 01:21:52 +0100 Subject: [PATCH 5/5] Linting --- squirrelbattle/mapgeneration/broguelike.py | 22 +++++++++++----------- squirrelbattle/tests/game_test.py | 2 -- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/squirrelbattle/mapgeneration/broguelike.py b/squirrelbattle/mapgeneration/broguelike.py index 62c8b03..973485b 100644 --- a/squirrelbattle/mapgeneration/broguelike.py +++ b/squirrelbattle/mapgeneration/broguelike.py @@ -24,10 +24,10 @@ DEFAULT_PARAMS = { "loop_max": 5, "loop_threshold": 15, "spawn_per_region": [1, 2], - "room_chances" : { - "circular" : 5, - "chunks" : 1, - }, + "room_chances": { + "circular": 5, + "chunks": 1, + }, } @@ -269,19 +269,19 @@ class Generator: nb_chunks, r = 6, 3 h_sup, w_sup, h_off, w_off = self.corr_meta_info() - room = [[Tile.EMPTY] * (width + w_sup) \ + room = [[Tile.EMPTY] * (width + w_sup) for _dummy in range(height + h_sup)] - def draw_chunk(room, y, x): + def draw_chunk(room: List[List[Tile]], y: int, x: int) -> None: for i in range(y - r, y + r + 1): d = (y - i)**2 for j in range(x - r, x + r + 1): - if d + (x - j)**2 < r**2: + if d + (x - j) ** 2 < r ** 2: room[i][j] = Tile.FLOOR - draw_chunk(room, h_off + height//2 + 1, w_off + width//2 + 1) + draw_chunk(room, h_off + height // 2 + 1, w_off + width // 2 + 1) - min_w, max_w = w_off + r + 1, width + w_off - r -1 + min_w, max_w = w_off + r + 1, width + w_off - r - 1 min_h, max_h = h_off + r + 1, height + h_off - r - 1 for i in range(nb_chunks): y, x = randint(min_h, max_h), randint(min_w, max_w) @@ -359,9 +359,9 @@ class Generator: break if key == "circular": - return self.create_circular_room(spawnable = spawnable) + return self.create_circular_room(spawnable=spawnable) elif key == "chunks": - return self.create_chunk_room(spawnable = spawnable) + return self.create_chunk_room(spawnable=spawnable) def register_spawn_area(self, area: List[List[Tile]]) -> None: """ diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index 4f80977..e5573ec 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later import curses -import os import unittest from ..bootstrap import Bootstrap @@ -101,7 +100,6 @@ class TestGame(unittest.TestCase): Yeah, that's only for coverage. """ self.assertRaises(Exception, Bootstrap.run_game) - self.assertEqual(os.getenv("TERM", "unknown"), "unknown") def test_key_translation(self) -> None: """