Spaces:
Sleeping
Sleeping
File size: 6,986 Bytes
390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 390ca88 bd2a7ad 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 |
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.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.door_pos = [48, 48] # Door to next level at far end
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_y] = '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'
terrain[self.door_pos[1]][self.door_pos[0]] = 'd' # 'd' for door
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):
# Center the visible 10x10 area around the player
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)
# Pad with empty space if near edges
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 (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'
return {'terrain': visible_terrain, 'entities': visible_entities}
def get_game_state(self):
visible = self.get_visible_area()
return {
'terrain': visible['terrain'],
'entities': visible['entities'],
'health': self.player_health,
'inventory': self.inventory,
'attack': self.player_attack,
'level': self.level
}
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.terrain = self.generate_maze()
self.player_pos = [1, 1]
self.player_health = 10
self.monsters = self.generate_monsters()
self.items = self.generate_items()
self.door_pos = [48, 48]
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 |