tangledmind/utils.py

151 lines
4.5 KiB
Python
Raw Normal View History

2020-05-03 19:20:48 +02:00
# -*- coding: UTF-8 -*-
### Tangled Mind
### Author: Arthur 'Grizzly' Grisel-Davy
from glob import glob
import random
2020-05-04 04:08:10 +02:00
import pygame
2020-05-03 19:20:48 +02:00
def fetch_rooms(path):
"""Fetch all the basic tiles asset from the path.
Return a dictionary
"""
2020-05-05 01:29:22 +02:00
common_wildcard = '[A-Z]*-*.png'
unique_wildcard = '?-*.png'
common_filenames = glob(path+common_wildcard)
unique_filenames = glob(path+unique_wildcard)
#print(f"Found {len(common_filenames)} common rooms and {len(unique_filenames)} uniques rooms.")
2020-05-03 19:20:48 +02:00
assembly = {'T':[],
'R':[],
'D':[],
'L':[],}
2020-05-05 01:29:22 +02:00
for filename in common_filenames:
2020-05-03 19:20:48 +02:00
label = filename.split("/")[-1].split('-')[0]
if 'T' in label:
assembly['D'].append((label,filename))
if 'R' in label:
assembly['L'].append((label,filename))
if 'D' in label:
assembly['T'].append((label,filename))
if 'L' in label:
assembly['R'].append((label,filename))
background = glob(path+'*back*')[0]
2020-05-05 01:29:22 +02:00
return unique_filenames,assembly,background
2020-05-03 19:20:48 +02:00
def check_map(carte):
"""Function to check if a map is valid i.e. if no two rooms are at the same location
"""
positions = []
for room in carte:
if room[2] in positions:
return(False)
else:
positions.append(room[2])
return(True)
2020-05-03 19:20:48 +02:00
def map_generator(n):
"""Map generator generate a map with a main path of n rooms
"""
room_side = 1000
2020-05-05 04:58:16 +02:00
change_side = {'T':'D','R':'L','D':'T','L':'R'}
deplacements = {'T':[0,-1],'R':[1,0],'D':[0,1],'L':[-1,0]}
2020-05-03 19:20:48 +02:00
2020-05-05 01:29:22 +02:00
unique_filenames,assembly,back_path = fetch_rooms('./maps/rooms/')
2020-05-03 19:20:48 +02:00
#assembly = {'T/R/D/L':[(label1,path1),(label2,path2),...]}
2020-05-05 01:29:22 +02:00
unique_rooms = {filename.split("/")[-1][0].upper():pygame.image.load(filename).convert_alpha() for filename in unique_filenames}
current_label= random.choice(list(unique_rooms.keys()))
start_room = unique_rooms[current_label]
2020-05-03 19:20:48 +02:00
2020-05-04 04:08:10 +02:00
# Place the first room in the list
positions = []
2020-05-03 19:20:48 +02:00
position = [0,0]
2020-05-05 01:29:22 +02:00
mask = pygame.mask.from_surface(start_room)
carte = [(start_room,mask,position)]
2020-05-03 19:20:48 +02:00
2020-05-05 06:13:57 +02:00
open_paths = []
2020-05-03 19:20:48 +02:00
counter = 0
2020-05-05 04:58:16 +02:00
retry = 0
while counter <= n:
2020-05-03 19:20:48 +02:00
# select the next direction, can't be the direction of arrival
2020-05-05 01:29:22 +02:00
if len(current_label) > 1:
dir_next = random.choice(current_label.replace(dir_from,''))
else:
dir_next = current_label
2020-05-05 06:13:57 +02:00
dir_from = ''
2020-05-05 01:29:22 +02:00
2020-05-05 06:13:57 +02:00
# stor open paths for later closing
for other_direction in current_label.replace(dir_from,'').replace(dir_next,''):
other_dir_from = change_side[other_direction]
other_position = [a+room_side*b for a,b in zip(position,deplacements[other_direction])]
open_paths.append((other_dir_from,other_position))
2020-05-03 19:20:48 +02:00
# Select the next room
2020-05-05 04:58:16 +02:00
if counter < n: # The next room is not the final room.
next_label,next_room = random.choice(assembly[dir_next])
asset = pygame.image.load(next_room).convert_alpha()
2020-05-03 19:20:48 +02:00
2020-05-05 04:58:16 +02:00
else:
# The next room is the finale room.
asset = unique_rooms[change_side[dir_next]]
2020-05-03 19:20:48 +02:00
2020-05-05 04:58:16 +02:00
mask = pygame.mask.from_surface(asset)
next_position = [position[0]+room_side*deplacements[dir_next][0],position[1]+room_side*deplacements[dir_next][1]]
dir_from = change_side[dir_next]
2020-05-03 19:20:48 +02:00
# Check if we are not overwriting an existing room and store the current one.
if next_position not in positions:
counter += 1
# Build the map
carte.append((asset,mask,next_position))
positions.append(position)
2020-05-03 19:20:48 +02:00
# Update the variables for next turn
current_label = next_label
position = next_position
positions.append(position)
2020-05-05 04:58:16 +02:00
else:
retry +=1
if retry > 10:
raise ValueError("Too much retries")
2020-05-03 19:20:48 +02:00
2020-05-05 06:13:57 +02:00
if not check_map(carte):
raise ValueError("Invalid Map before closing paths.")
#Close all the open paths
for open_path in open_paths:
if open_path[1] not in positions:
room = unique_rooms[open_path[0]]
mask = pygame.mask.from_surface(room)
position = open_path[1]
carte.append((room,mask,position))
positions.append(position)
background = pygame.image.load(back_path).convert()
2020-05-05 06:13:57 +02:00
print("Open paths:")
print(open_paths)
if not check_map(carte):
2020-05-05 06:13:57 +02:00
raise ValueError("Invalid Map after closing paths.")
2020-05-05 01:29:22 +02:00
return(carte,(int(room_side/2),int(room_side/2)),background)
2020-05-03 19:20:48 +02:00