Spaces:
Sleeping
Sleeping
File size: 7,483 Bytes
390ca88 bd2a7ad 390ca88 a70ed2f 390ca88 bd2a7ad 390ca88 312acdf 390ca88 bd2a7ad 390ca88 a70ed2f bd2a7ad 390ca88 312acdf 390ca88 312acdf 390ca88 312acdf 390ca88 bd2a7ad 390ca88 312acdf 390ca88 bd2a7ad 390ca88 bd2a7ad 312acdf bd2a7ad 390ca88 a70ed2f 390ca88 bd2a7ad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
import random
from flask_socketio import emit
class Game:
def __init__(self):
self.map_size = 50 # Much larger dungeon
self.visible_size = 10 # 10x10 visible area on screen
self.door_pos = [48, 48] # Door to next level at far end - set before generating maze
self.terrain = self.generate_maze()
self.player_pos = [1, 1] # Start near top-left
self.player_health = 10
self.player_attack = 2
self.inventory = []
self.monsters = self.generate_monsters()
self.items = self.generate_items()
self.level = 1
def generate_maze(self):
# Simple recursive backtracking maze generation
terrain = [['w' for _ in range(self.map_size)] for _ in range(self.map_size)]
def carve(x, y):
terrain[y][x] = 'f'
directions = [(0, 2), (2, 0), (-2, 0), (0, -2)] # Right, Down, Left, Up (2 steps for corridors)
random.shuffle(directions)
for dx, dy in directions:
nx, ny = x + dx, y + dy
if (0 <= nx < self.map_size and 0 <= ny < self.map_size and
terrain[ny][nx] == 'w'):
mid_x, mid_y = x + dx // 2, y + dy // 2
terrain[mid_y][mid_x] = 'f' # Carve path
carve(nx, ny)
# Start carving from (1,1) to avoid edges
carve(1, 1)
# Ensure player start and door positions are accessible
terrain[1][1] = 'f'
if hasattr(self, 'door_pos'): # Safety check
terrain[self.door_pos[1]][self.door_pos[0]] = 'd' # 'd' for door
else:
print("Warning: door_pos not set, using default [48, 48]")
terrain[48][48] = 'd' # Fallback if door_pos is not set
return terrain
def generate_monsters(self):
monsters = {}
for _ in range(10): # 10 enemies (e.g., 5 goblins, 5 skeletons)
while True:
x, y = random.randint(2, self.map_size - 3), random.randint(2, self.map_size - 3)
if self.terrain[y][x] == 'f' and (x, y) not in monsters and (x, y) != tuple(self.player_pos):
monster_type = random.choice(['goblin', 'skeleton'])
health = 5 if monster_type == 'goblin' else 6
attack = 1 if monster_type == 'goblin' else 2
monsters[(x, y)] = {'type': monster_type, 'health': health, 'attack': attack}
break
return monsters
def generate_items(self):
items = {}
item_types = ['potion', 'sword']
for _ in range(5): # 5 items (e.g., 3 potions, 2 swords)
while True:
x, y = random.randint(2, self.map_size - 3), random.randint(2, self.map_size - 3)
if self.terrain[y][x] == 'f' and (x, y) not in items and (x, y) not in self.monsters:
items[(x, y)] = random.choice(item_types)
break
return items
def get_visible_area(self):
print("Generating visible area for player at:", self.player_pos) # Debug log
px, py = self.player_pos
half_size = self.visible_size // 2
start_x = max(0, px - half_size)
start_y = max(0, py - half_size)
end_x = min(self.map_size, px + half_size + 1)
end_y = min(self.map_size, py + half_size + 1)
visible_terrain = [['' for _ in range(self.visible_size)] for _ in range(self.visible_size)]
visible_entities = [['' for _ in range(self.visible_size)] for _ in range(self.visible_size)]
for y in range(start_y, end_y):
for x in range(start_x, end_x):
grid_y = y - (py - half_size)
grid_x = x - (px - half_size)
if 0 <= grid_y < self.visible_size and 0 <= grid_x < self.visible_size:
visible_terrain[grid_y][grid_x] = self.terrain[y][x] if self.terrain[y][x] else 'f' # Default to 'f'
if (x, y) == tuple(self.player_pos):
visible_entities[grid_y][grid_x] = 'player'
elif (x, y) in self.monsters:
visible_entities[grid_y][grid_x] = self.monsters[(x, y)]['type']
elif (x, y) in self.items:
visible_entities[grid_y][grid_x] = self.items[(x, y)]
elif (x, y) == tuple(self.door_pos):
visible_entities[grid_y][grid_x] = 'door'
print("Visible terrain:", visible_terrain) # Debug log
print("Visible entities:", visible_entities) # Debug log
return {'terrain': visible_terrain, 'entities': visible_entities}
def get_game_state(self):
visible = self.get_visible_area()
state = {
'terrain': visible['terrain'],
'entities': visible['entities'],
'health': self.player_health,
'inventory': self.inventory,
'attack': self.player_attack,
'level': self.level
}
print("Game state:", state) # Debug log
return state
def is_valid_position(self, x, y):
return (0 <= x < self.map_size and 0 <= y < self.map_size and
self.terrain[y][x] != 'w')
def move_player(self, direction):
dx, dy = {'up': (0, -1), 'down': (0, 1), 'left': (-1, 0), 'right': (1, 0)}[direction]
new_x, new_y = self.player_pos[0] + dx, self.player_pos[1] + dy
if self.is_valid_position(new_x, new_y):
self.player_pos = [new_x, new_y]
pos_tuple = tuple(self.player_pos)
# Check for monster
if pos_tuple in self.monsters:
self.handle_combat(pos_tuple)
# Check for item
elif pos_tuple in self.items:
item = self.items.pop(pos_tuple)
self.inventory.append(item)
if item == 'sword':
self.player_attack += 1
emit('message', 'Picked up a sword! Attack increased.')
else:
emit('message', f'Picked up a {item}!')
# Check for door
elif pos_tuple == tuple(self.door_pos):
self.level += 1
self.reset_level()
emit('message', f'Entered Level {self.level}! New dungeon awaits.')
def reset_level(self):
self.door_pos = [48, 48] # Reset door position
self.terrain = self.generate_maze()
self.player_pos = [1, 1]
self.player_health = 10
self.monsters = self.generate_monsters()
self.items = self.generate_items()
def handle_combat(self, pos):
from flask_socketio import emit
monster = self.monsters[pos]
monster_health = monster['health']
while monster_health > 0 and self.player_health > 0:
monster_health -= self.player_attack
emit('message', f"You attack the {monster['type']} for {self.player_attack} damage.")
if monster_health <= 0:
emit('message', f"You defeated the {monster['type']}!")
del self.monsters[pos]
break
self.player_health -= monster['attack']
emit('message', f"The {monster['type']} attacks you for {monster['attack']} damage.")
if self.player_health <= 0:
emit('message', 'Game over! You were defeated.')
break |