Skip to content

Commit 29a5000

Browse files
committed
Part 12: Increasing Difficulty
1 parent beba38e commit 29a5000

File tree

3 files changed

+75
-44
lines changed

3 files changed

+75
-44
lines changed

game/game_map.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ def __init__(
111111
max_rooms: int,
112112
room_min_size: int,
113113
room_max_size: int,
114-
max_monsters_per_room: int,
115-
max_items_per_room: int,
116114
current_floor: int = 0,
117115
):
118116
self.engine = engine
@@ -125,9 +123,6 @@ def __init__(
125123
self.room_min_size = room_min_size
126124
self.room_max_size = room_max_size
127125

128-
self.max_monsters_per_room = max_monsters_per_room
129-
self.max_items_per_room = max_items_per_room
130-
131126
self.current_floor = current_floor
132127

133128
def generate_floor(self) -> None:
@@ -141,7 +136,6 @@ def generate_floor(self) -> None:
141136
room_max_size=self.room_max_size,
142137
map_width=self.map_width,
143138
map_height=self.map_height,
144-
max_monsters_per_room=self.max_monsters_per_room,
145-
max_items_per_room=self.max_items_per_room,
139+
current_floor=self.current_floor,
146140
engine=self.engine,
147141
)

game/procgen.py

Lines changed: 74 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Iterator, List, Tuple
3+
from typing import TYPE_CHECKING, Dict, Iterator, List, Tuple
44
import copy
55
import random
66

@@ -15,6 +15,69 @@
1515
import game.game_map
1616

1717

18+
max_items_by_floor = [
19+
(1, 1),
20+
(4, 2),
21+
]
22+
23+
max_monsters_by_floor = [
24+
(1, 2),
25+
(4, 3),
26+
(6, 5),
27+
]
28+
29+
item_chances: Dict[int, List[Tuple[game.entity.Entity, int]]] = {
30+
0: [(game.entity_factories.health_potion, 35)],
31+
2: [(game.entity_factories.confusion_scroll, 10)],
32+
4: [(game.entity_factories.lightning_scroll, 25)],
33+
6: [(game.entity_factories.fireball_scroll, 25)],
34+
}
35+
36+
enemy_chances: Dict[int, List[Tuple[game.entity.Entity, int]]] = {
37+
0: [(game.entity_factories.orc, 80)],
38+
3: [(game.entity_factories.troll, 15)],
39+
5: [(game.entity_factories.troll, 30)],
40+
7: [(game.entity_factories.troll, 60)],
41+
}
42+
43+
44+
def get_max_value_for_floor(weighted_chances_by_floor: List[Tuple[int, int]], floor: int) -> int:
45+
current_value = 0
46+
47+
for floor_minimum, value in weighted_chances_by_floor:
48+
if floor_minimum > floor:
49+
break
50+
else:
51+
current_value = value
52+
53+
return current_value
54+
55+
56+
def get_entities_at_random(
57+
weighted_chances_by_floor: Dict[int, List[Tuple[game.entity.Entity, int]]],
58+
number_of_entities: int,
59+
floor: int,
60+
) -> List[game.entity.Entity]:
61+
entity_weighted_chances = {}
62+
63+
for key, values in weighted_chances_by_floor.items():
64+
if key > floor:
65+
break
66+
else:
67+
for value in values:
68+
entity = value[0]
69+
weighted_chance = value[1]
70+
71+
entity_weighted_chances[entity] = weighted_chance
72+
73+
entities = list(entity_weighted_chances.keys())
74+
entity_weighted_chance_values = list(entity_weighted_chances.values())
75+
76+
chosen_entities = random.choices(entities, weights=entity_weighted_chance_values, k=number_of_entities)
77+
78+
return chosen_entities
79+
80+
1881
class RectangularRoom:
1982
def __init__(self, x: int, y: int, width: int, height: int):
2083
self.x1 = x
@@ -60,41 +123,21 @@ def tunnel_between(start: Tuple[int, int], end: Tuple[int, int]) -> Iterator[Tup
60123
def place_entities(
61124
room: RectangularRoom,
62125
dungeon: game.game_map.GameMap,
63-
maximum_monsters: int,
64-
maximum_items: int,
126+
floor_number: int,
65127
) -> None:
66-
number_of_monsters = random.randint(0, maximum_monsters)
67-
number_of_items = random.randint(0, maximum_items)
128+
number_of_monsters = random.randint(0, get_max_value_for_floor(max_monsters_by_floor, floor_number))
129+
number_of_items = random.randint(0, get_max_value_for_floor(max_items_by_floor, floor_number))
68130

69-
for _ in range(number_of_monsters):
70-
x = random.randint(room.x1 + 1, room.x2 - 1)
71-
y = random.randint(room.y1 + 1, room.y2 - 1)
131+
monsters: List[game.entity.Entity] = get_entities_at_random(enemy_chances, number_of_monsters, floor_number)
132+
items: List[game.entity.Entity] = get_entities_at_random(item_chances, number_of_items, floor_number)
72133

73-
if not any(entity.x == x and entity.y == y for entity in dungeon.entities):
74-
if random.random() < 0.8:
75-
monster = copy.deepcopy(game.entity_factories.orc)
76-
else:
77-
monster = copy.deepcopy(game.entity_factories.troll)
78-
79-
monster.place(x, y, dungeon)
80-
81-
for _ in range(number_of_items):
134+
for entity in monsters + items:
82135
x = random.randint(room.x1 + 1, room.x2 - 1)
83136
y = random.randint(room.y1 + 1, room.y2 - 1)
84137

85138
if not any(entity.x == x and entity.y == y for entity in dungeon.entities):
86-
item_chance = random.random()
87-
88-
if item_chance < 0.7:
89-
item = copy.deepcopy(game.entity_factories.health_potion)
90-
elif item_chance < 0.8:
91-
item = copy.deepcopy(game.entity_factories.fireball_scroll)
92-
elif item_chance < 0.9:
93-
item = copy.deepcopy(game.entity_factories.confusion_scroll)
94-
else:
95-
item = copy.deepcopy(game.entity_factories.lightning_scroll)
96-
97-
item.place(x, y, dungeon)
139+
entity_copy = copy.deepcopy(entity)
140+
entity_copy.place(x, y, dungeon)
98141

99142

100143
def generate_dungeon(
@@ -103,8 +146,7 @@ def generate_dungeon(
103146
room_max_size: int,
104147
map_width: int,
105148
map_height: int,
106-
max_monsters_per_room: int,
107-
max_items_per_room: int,
149+
current_floor: int,
108150
engine: game.engine.Engine,
109151
) -> game.game_map.GameMap:
110152
"""Generate a new dungeon map."""
@@ -139,7 +181,7 @@ def generate_dungeon(
139181
for x, y in tunnel_between(rooms[-1].center, new_room.center):
140182
dungeon.tiles[x, y] = game.tiles.floor
141183

142-
place_entities(new_room, dungeon, max_monsters_per_room, max_items_per_room)
184+
place_entities(new_room, dungeon, current_floor)
143185

144186
# Finally, append the new room to the list.
145187
rooms.append(new_room)

game/setup_game.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ def new_game() -> game.engine.Engine:
3737
room_min_size = 6
3838
max_rooms = 30
3939

40-
max_monsters_per_room = 2
41-
max_items_per_room = 2
42-
4340
player = copy.deepcopy(game.entity_factories.player)
4441

4542
engine = game.engine.Engine(player=player)
@@ -51,8 +48,6 @@ def new_game() -> game.engine.Engine:
5148
room_max_size=room_max_size,
5249
map_width=map_width,
5350
map_height=map_height,
54-
max_monsters_per_room=max_monsters_per_room,
55-
max_items_per_room=max_items_per_room,
5651
)
5752
engine.game_world.generate_floor()
5853
engine.update_fov()

0 commit comments

Comments
 (0)