Paste #53442: Untitled Paste

Date: 2019/03/25 14:08:58 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


from random import randint, sample, seed, choice, shuffle, uniform
from itertools import product
from time import time
from math import sqrt

seed(time())

def bound(a, l, h):
  if a < l:
    return l

  elif a > h:
    return h

  else:
    return a

def distance(a, b):
  f = 0
  for i, j in zip(a, b):
    f += (i - j)**2

  return sqrt(f)

class Grid:
  def __init__(self, width, height, roomsize):
    self.matrix = [[' ' for _ in range(width*roomsize+1)] for _ in range(height*roomsize+1)]
    self.width = width*roomsize
    self.height = height*roomsize
    self.rooms = []
    self.start = (randint(1, self.height//roomsize)*roomsize-(roomsize//2), randint(1, (self.width//roomsize)//2)*roomsize-(roomsize//2))
    self.end = (randint(1, self.height//roomsize)*roomsize-(roomsize//2), randint((self.width//roomsize)//2+1, self.width//roomsize)*roomsize-(roomsize//2))
    self.roomsize = roomsize

  def display_grid(self):
    for row in self.matrix:
      print(' '.join(row))

  def generate_path(self, randomization, grid_char):

    row = (self.start[0]+(self.roomsize//2))//self.roomsize
    column = (self.start[1]+(self.roomsize//2))//self.roomsize
    previous_opening = self.start

    total_openings = []

    done = False
    turn = 0
    i = 0

    while not done:
        i += 1
        openings = []

        if row < self.height//self.roomsize:
          openings.append((row*self.roomsize, column*self.roomsize-(self.roomsize//2), row+1, column))

        if column < self.width//self.roomsize:
          openings.append((row*self.roomsize-(self.roomsize//2), column*self.roomsize, row, column+1))

        if row > 1:
          openings.append((row*self.roomsize-self.roomsize, column*self.roomsize-(self.roomsize//2), row-1, column))

        if column > 1:
          openings.append((row*self.roomsize-(self.roomsize//2), column*self.roomsize-(self.roomsize//2), row, column-1))

        self.matrix[row*self.roomsize][column*self.roomsize] = grid_char
        self.matrix[row*self.roomsize-self.roomsize][column*self.roomsize-self.roomsize] = grid_char
        self.matrix[row*self.roomsize-self.roomsize][column*self.roomsize] = grid_char
        self.matrix[row*self.roomsize][column*self.roomsize-self.roomsize] = grid_char
        for x in range(1, self.roomsize):
          self.matrix[row*self.roomsize][column*self.roomsize-x] = grid_char
          self.matrix[row*self.roomsize-self.roomsize][column*self.roomsize-x] = grid_char
          self.matrix[row*self.roomsize-x][column*self.roomsize] = grid_char
          self.matrix[row*self.roomsize-x][column*self.roomsize-self.roomsize] = grid_char

        if not (row, column) in self.rooms:
          self.rooms.append((row, column))

        best_opening = ((0, 0), 10**9)

        for opening in openings:
          if distance(opening[:2], self.end) < best_opening[1]:
            best_opening = (opening, distance(opening[:2], self.end))

        if uniform(0, 1) < randomization:
          best_opening = (choice(openings), 0)

        bo_row, bo_column, row_, column_ = best_opening[0]
        if (distance((row*self.roomsize-(self.roomsize//2), column*self.roomsize-(self.roomsize//2)), self.end) == 0.0 or i >= ((self.height + self.width) * bound(randomization * 100, 1, 100))) and (len(total_openings) > (self.width*self.height)/(self.roomsize*4)):
          done = True

        else:
            total_openings.append((bo_row, bo_column))

        row = row_
        column = column_

    for bo_row, bo_column in total_openings:
      self.matrix[bo_row][bo_column] = '+'

    for row, column in self.rooms:
      self.matrix[row*self.roomsize-(self.roomsize//2)][column*self.roomsize-(self.roomsize//2)] = ' '

  def generate_keys(self, nkeys):
    KeyL = []
    for j in reversed(range(nkeys*2)):
      if j % 2 == 0:
        KeyL.append(str(j//2))

      if j % 2 == 1:
        KeyL.append(chr(j//2+97))

    p = (len(self.rooms)+1)//len(KeyL)

    for n, room in enumerate(self.rooms):
      if len(KeyL) == 1:
        row, column = room
        self.matrix[row*self.roomsize-(self.roomsize//2)][column*self.roomsize-(self.roomsize//2)] = 'B'
        KeyL.pop()

      elif n % p == (p-1) and not len(KeyL) == 0:
        row, column = room
        self.matrix[row*self.roomsize-(self.roomsize//2)][column*self.roomsize-(self.roomsize//2)] = KeyL.pop()

    self.matrix[self.start[0]][self.start[1]] = 'S'
    self.matrix[self.end[0]][self.end[1]] = 'E'

  def get_corners(self):
    for row, column in self.rooms:
      row, column = row*self.roomsize-self.roomsize, column*self.roomsize-self.roomsize
      self.matrix[row][column] = '%'


Maze = Grid(8, 8, 4)
Maze.generate_path(0.85, '.')
Maze.generate_keys(3)
Maze.get_corners()
Maze.display_grid()