Skip to content

Commit d7f84d9

Browse files
committed
Part 12: Increasing Difficulty
1 parent e5d5385 commit d7f84d9

File tree

3 files changed

+89
-45
lines changed

3 files changed

+89
-45
lines changed

game/game_map.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ def __init__(
121121
max_rooms: int,
122122
room_min_size: int,
123123
room_max_size: int,
124-
max_monsters_per_room: int,
125-
max_items_per_room: int,
126124
current_floor: int = 0,
127125
):
128126
self.engine = engine
@@ -135,9 +133,6 @@ def __init__(
135133
self.room_min_size = room_min_size
136134
self.room_max_size = room_max_size
137135

138-
self.max_monsters_per_room = max_monsters_per_room
139-
self.max_items_per_room = max_items_per_room
140-
141136
self.current_floor = current_floor
142137

143138
def generate_floor(self) -> None:
@@ -151,7 +146,6 @@ def generate_floor(self) -> None:
151146
room_max_size=self.room_max_size,
152147
map_width=self.map_width,
153148
map_height=self.map_height,
154-
max_monsters_per_room=self.max_monsters_per_room,
155-
max_items_per_room=self.max_items_per_room,
149+
current_floor=self.current_floor,
156150
engine=self.engine,
157151
)

game/procgen.py

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import copy
44
import random
5-
from typing import Iterator, List, Tuple, TYPE_CHECKING
5+
from typing import Dict, Iterator, List, Tuple, TYPE_CHECKING
66

77
import tcod
88

@@ -15,6 +15,73 @@
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(
45+
weighted_chances_by_floor: List[Tuple[int, int]], floor: int
46+
) -> int:
47+
current_value = 0
48+
49+
for floor_minimum, value in weighted_chances_by_floor:
50+
if floor_minimum > floor:
51+
break
52+
else:
53+
current_value = value
54+
55+
return current_value
56+
57+
58+
def get_entities_at_random(
59+
weighted_chances_by_floor: Dict[int, List[Tuple[game.entity.Entity, int]]],
60+
number_of_entities: int,
61+
floor: int,
62+
) -> List[game.entity.Entity]:
63+
entity_weighted_chances = {}
64+
65+
for key, values in weighted_chances_by_floor.items():
66+
if key > floor:
67+
break
68+
else:
69+
for value in values:
70+
entity = value[0]
71+
weighted_chance = value[1]
72+
73+
entity_weighted_chances[entity] = weighted_chance
74+
75+
entities = list(entity_weighted_chances.keys())
76+
entity_weighted_chance_values = list(entity_weighted_chances.values())
77+
78+
chosen_entities = random.choices(
79+
entities, weights=entity_weighted_chance_values, k=number_of_entities
80+
)
81+
82+
return chosen_entities
83+
84+
1885
class RectangularRoom:
1986
def __init__(self, x: int, y: int, width: int, height: int):
2087
self.x1 = x
@@ -60,40 +127,29 @@ def tunnel_between(
60127

61128

62129
def place_entities(
63-
room: RectangularRoom, dungeon: game.game_map.GameMap, maximum_monsters: int, maximum_items: int,
130+
room: RectangularRoom, dungeon: game.game_map.GameMap, floor_number: int,
64131
) -> None:
65-
number_of_monsters = random.randint(0, maximum_monsters)
66-
number_of_items = random.randint(0, maximum_items)
67-
68-
for _ in range(number_of_monsters):
69-
x = random.randint(room.x1 + 1, room.x2 - 1)
70-
y = random.randint(room.y1 + 1, room.y2 - 1)
71-
72-
if not any(entity.x == x and entity.y == y for entity in dungeon.entities):
73-
if random.random() < 0.8:
74-
monster = copy.deepcopy(game.entity_factories.orc)
75-
else:
76-
monster = copy.deepcopy(game.entity_factories.troll)
77-
78-
monster.place(x, y, dungeon)
79-
80-
for _ in range(number_of_items):
132+
number_of_monsters = random.randint(
133+
0, get_max_value_for_floor(max_monsters_by_floor, floor_number)
134+
)
135+
number_of_items = random.randint(
136+
0, get_max_value_for_floor(max_items_by_floor, floor_number)
137+
)
138+
139+
monsters: List[game.entity.Entity] = get_entities_at_random(
140+
enemy_chances, number_of_monsters, floor_number
141+
)
142+
items: List[game.entity.Entity] = get_entities_at_random(
143+
item_chances, number_of_items, floor_number
144+
)
145+
146+
for entity in monsters + items:
81147
x = random.randint(room.x1 + 1, room.x2 - 1)
82148
y = random.randint(room.y1 + 1, room.y2 - 1)
83149

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

98154

99155
def generate_dungeon(
@@ -102,8 +158,7 @@ def generate_dungeon(
102158
room_max_size: int,
103159
map_width: int,
104160
map_height: int,
105-
max_monsters_per_room: int,
106-
max_items_per_room: int,
161+
current_floor: int,
107162
engine: game.engine.Engine,
108163
) -> game.game_map.GameMap:
109164
"""Generate a new dungeon map."""
@@ -138,7 +193,7 @@ def generate_dungeon(
138193
for x, y in tunnel_between(rooms[-1].center, new_room.center):
139194
dungeon.tiles[x, y] = game.tiles.floor
140195

141-
place_entities(new_room, dungeon, max_monsters_per_room, max_items_per_room)
196+
place_entities(new_room, dungeon, current_floor)
142197

143198
# Finally, append the new room to the list.
144199
rooms.append(new_room)

game/setup_game.py

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

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

4441
engine = game.engine.Engine(player=player)
@@ -50,8 +47,6 @@ def new_game() -> game.engine.Engine:
5047
room_max_size=room_max_size,
5148
map_width=map_width,
5249
map_height=map_height,
53-
max_monsters_per_room=max_monsters_per_room,
54-
max_items_per_room=max_items_per_room,
5550
)
5651
engine.game_world.generate_floor()
5752
engine.update_fov()

0 commit comments

Comments
 (0)