Spaces:
Sleeping
Sleeping
Update game.py
Browse files
game.py
CHANGED
@@ -1,38 +1,107 @@
|
|
|
|
|
|
|
|
1 |
class Game:
|
2 |
def __init__(self):
|
3 |
-
self.map_size =
|
4 |
-
self.
|
5 |
-
self.
|
|
|
6 |
self.player_health = 10
|
7 |
self.player_attack = 2
|
8 |
self.inventory = []
|
9 |
-
self.monsters =
|
10 |
-
self.items =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
terrain[
|
18 |
return terrain
|
19 |
|
20 |
-
def
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def get_game_state(self):
|
|
|
30 |
return {
|
31 |
-
'terrain':
|
32 |
-
'entities':
|
33 |
'health': self.player_health,
|
34 |
'inventory': self.inventory,
|
35 |
-
'attack': self.player_attack
|
|
|
36 |
}
|
37 |
|
38 |
def is_valid_position(self, x, y):
|
@@ -54,10 +123,22 @@ class Game:
|
|
54 |
self.inventory.append(item)
|
55 |
if item == 'sword':
|
56 |
self.player_attack += 1
|
57 |
-
from flask_socketio import emit
|
58 |
emit('message', 'Picked up a sword! Attack increased.')
|
59 |
else:
|
60 |
emit('message', f'Picked up a {item}!')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
def handle_combat(self, pos):
|
63 |
from flask_socketio import emit
|
|
|
1 |
+
import random
|
2 |
+
from flask_socketio import emit
|
3 |
+
|
4 |
class Game:
|
5 |
def __init__(self):
|
6 |
+
self.map_size = 50 # Much larger dungeon
|
7 |
+
self.visible_size = 10 # 10x10 visible area on screen
|
8 |
+
self.terrain = self.generate_maze()
|
9 |
+
self.player_pos = [1, 1] # Start near top-left
|
10 |
self.player_health = 10
|
11 |
self.player_attack = 2
|
12 |
self.inventory = []
|
13 |
+
self.monsters = self.generate_monsters()
|
14 |
+
self.items = self.generate_items()
|
15 |
+
self.door_pos = [48, 48] # Door to next level at far end
|
16 |
+
self.level = 1
|
17 |
+
|
18 |
+
def generate_maze(self):
|
19 |
+
# Simple recursive backtracking maze generation
|
20 |
+
terrain = [['w' for _ in range(self.map_size)] for _ in range(self.map_size)]
|
21 |
+
|
22 |
+
def carve(x, y):
|
23 |
+
terrain[y][x] = 'f'
|
24 |
+
directions = [(0, 2), (2, 0), (-2, 0), (0, -2)] # Right, Down, Left, Up (2 steps for corridors)
|
25 |
+
random.shuffle(directions)
|
26 |
+
for dx, dy in directions:
|
27 |
+
nx, ny = x + dx, y + dy
|
28 |
+
if (0 <= nx < self.map_size and 0 <= ny < self.map_size and
|
29 |
+
terrain[ny][nx] == 'w'):
|
30 |
+
mid_x, mid_y = x + dx // 2, y + dy // 2
|
31 |
+
terrain[mid_y][mid_y] = 'f' # Carve path
|
32 |
+
carve(nx, ny)
|
33 |
|
34 |
+
# Start carving from (1,1) to avoid edges
|
35 |
+
carve(1, 1)
|
36 |
+
|
37 |
+
# Ensure player start and door positions are accessible
|
38 |
+
terrain[1][1] = 'f'
|
39 |
+
terrain[self.door_pos[1]][self.door_pos[0]] = 'd' # 'd' for door
|
40 |
return terrain
|
41 |
|
42 |
+
def generate_monsters(self):
|
43 |
+
monsters = {}
|
44 |
+
for _ in range(10): # 10 enemies (e.g., 5 goblins, 5 skeletons)
|
45 |
+
while True:
|
46 |
+
x, y = random.randint(2, self.map_size - 3), random.randint(2, self.map_size - 3)
|
47 |
+
if self.terrain[y][x] == 'f' and (x, y) not in monsters and (x, y) != tuple(self.player_pos):
|
48 |
+
monster_type = random.choice(['goblin', 'skeleton'])
|
49 |
+
health = 5 if monster_type == 'goblin' else 6
|
50 |
+
attack = 1 if monster_type == 'goblin' else 2
|
51 |
+
monsters[(x, y)] = {'type': monster_type, 'health': health, 'attack': attack}
|
52 |
+
break
|
53 |
+
return monsters
|
54 |
+
|
55 |
+
def generate_items(self):
|
56 |
+
items = {}
|
57 |
+
item_types = ['potion', 'sword']
|
58 |
+
for _ in range(5): # 5 items (e.g., 3 potions, 2 swords)
|
59 |
+
while True:
|
60 |
+
x, y = random.randint(2, self.map_size - 3), random.randint(2, self.map_size - 3)
|
61 |
+
if self.terrain[y][x] == 'f' and (x, y) not in items and (x, y) not in self.monsters:
|
62 |
+
items[(x, y)] = random.choice(item_types)
|
63 |
+
break
|
64 |
+
return items
|
65 |
+
|
66 |
+
def get_visible_area(self):
|
67 |
+
# Center the visible 10x10 area around the player
|
68 |
+
px, py = self.player_pos
|
69 |
+
half_size = self.visible_size // 2
|
70 |
+
start_x = max(0, px - half_size)
|
71 |
+
start_y = max(0, py - half_size)
|
72 |
+
end_x = min(self.map_size, px + half_size + 1)
|
73 |
+
end_y = min(self.map_size, py + half_size + 1)
|
74 |
+
|
75 |
+
# Pad with empty space if near edges
|
76 |
+
visible_terrain = [['' for _ in range(self.visible_size)] for _ in range(self.visible_size)]
|
77 |
+
visible_entities = [['' for _ in range(self.visible_size)] for _ in range(self.visible_size)]
|
78 |
+
|
79 |
+
for y in range(start_y, end_y):
|
80 |
+
for x in range(start_x, end_x):
|
81 |
+
grid_y = y - (py - half_size)
|
82 |
+
grid_x = x - (px - half_size)
|
83 |
+
if 0 <= grid_y < self.visible_size and 0 <= grid_x < self.visible_size:
|
84 |
+
visible_terrain[grid_y][grid_x] = self.terrain[y][x]
|
85 |
+
if (x, y) == tuple(self.player_pos):
|
86 |
+
visible_entities[grid_y][grid_x] = 'player'
|
87 |
+
elif (x, y) in self.monsters:
|
88 |
+
visible_entities[grid_y][grid_x] = self.monsters[(x, y)]['type']
|
89 |
+
elif (x, y) in self.items:
|
90 |
+
visible_entities[grid_y][grid_x] = self.items[(x, y)]
|
91 |
+
elif (x, y) == tuple(self.door_pos):
|
92 |
+
visible_entities[grid_y][grid_x] = 'door'
|
93 |
+
|
94 |
+
return {'terrain': visible_terrain, 'entities': visible_entities}
|
95 |
|
96 |
def get_game_state(self):
|
97 |
+
visible = self.get_visible_area()
|
98 |
return {
|
99 |
+
'terrain': visible['terrain'],
|
100 |
+
'entities': visible['entities'],
|
101 |
'health': self.player_health,
|
102 |
'inventory': self.inventory,
|
103 |
+
'attack': self.player_attack,
|
104 |
+
'level': self.level
|
105 |
}
|
106 |
|
107 |
def is_valid_position(self, x, y):
|
|
|
123 |
self.inventory.append(item)
|
124 |
if item == 'sword':
|
125 |
self.player_attack += 1
|
|
|
126 |
emit('message', 'Picked up a sword! Attack increased.')
|
127 |
else:
|
128 |
emit('message', f'Picked up a {item}!')
|
129 |
+
# Check for door
|
130 |
+
elif pos_tuple == tuple(self.door_pos):
|
131 |
+
self.level += 1
|
132 |
+
self.reset_level()
|
133 |
+
emit('message', f'Entered Level {self.level}! New dungeon awaits.')
|
134 |
+
|
135 |
+
def reset_level(self):
|
136 |
+
self.terrain = self.generate_maze()
|
137 |
+
self.player_pos = [1, 1]
|
138 |
+
self.player_health = 10
|
139 |
+
self.monsters = self.generate_monsters()
|
140 |
+
self.items = self.generate_items()
|
141 |
+
self.door_pos = [48, 48]
|
142 |
|
143 |
def handle_combat(self, pos):
|
144 |
from flask_socketio import emit
|