Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import PIL
- import random
- import array
- import itertools
- class PearsonHash:
- def __init__(self, seed=None):
- if seed != None:
- assert seed in range(256), "seed must be integer between 0 and 255"
- self.seed = seed
- else:
- self.seed = random.randint(0, 255)
- self.permut = list(range(256))
- random.shuffle(self.permut)
- def __call__(self, array):
- h = self.seed
- for value in array:
- h = self.permut[h ^ value]
- return h
- def ZCurve(x, y, n):
- i = 0
- assert ((n & (n - 1)) == 0) and n != 0, "n must be power of 2"
- for j in range(n):
- i |= (x & 1) << (2 * j)
- x >>= 1
- i |= (y & 1) << (2 * j + 1)
- y >>= 1
- return i
- class Random2dNoise:
- def __init__(self, size):
- self.phash = PearsonHash()
- self.size = size
- def __call__(self, x, y):
- assert x < self.size and y < self.size, "x, y out of bounds"
- tmp = array.array('B', [0] * 4)
- z = ZCurve(x, y, self.size)
- for k in range(4):
- tmp[k] = (z >> (8 * k)) & 255
- return self.phash(tmp)
- class CellularAutomaton:
- def __init__(self, size, percent_filled=0.55, rng_seed=random.randint(0, 255)):
- random.seed(rng_seed)
- self.array = [[int(random.random() < percent_filled) for _ in range(size)] for _ in range(size)]
- self.size = size
- self.percent_filled = percent_filled
- self.rng_seed = rng_seed
- def iteration(self, rule1=4, rule2=5):
- res = [[0 for _ in range(self.size)] for _ in range(self.size)]
- for x, y in itertools.product(range(self.size), repeat=2):
- neighbours = []
- for dx, dy in itertools.product([-1, 0, 1], repeat=2):
- if dx == 0 and dy == 0: continue
- else:
- try: neighbours.append(self.array[y + dy][x+dx])
- except IndexError: pass
- if self.array[y][x] == 1:
- if sum(neighbours) < rule1:
- res[y][x] = 1
- else:
- res[y][x] = 0
- elif self.array[y][x] == 0:
- if sum(neighbours) < rule2:
- res[y][x] = 1
- else:
- res[y][x] = 0
- self.array = res
- class Map:
- def __init__(self, size=32, chunksize=16):
- """
- :int size: specifying map size for both axes
- :int chunksize: number of blocks in every chunk
- :call: map_chunk at (x_i, y_i)
- """
- self.size = size
- self.chunksize = chunksize
- self.seed_gen = Random2dNoise(size=size) # generator for random seeds at map indexes
- def __call__(self, x, y):
- seed = self.seed_gen(x, y)
- percent_filled = lambda: 0.51 # placeholder for a more random function
- ca = CellularAutomaton(size=self.chunksize, percent_filled=percent_filled(), rng_seed=seed)
- for i in range(7):
- ca.iteration()
- return ca
- s = 126
- map1 = Map(chunksize=s)
- maparray = map1(10, 10).array
- f = lambda x: ' ' if x == 0 else '#'
- def fill(data, pos):
- stack = [pos]
- xSize, ySize = len(data[0]), len(data)
- temp = [[0 for i in range(xSize)] for j in range(ySize)]
- while stack: # is not empty
- (x, y), *stack = stack
- if data[y][x] == 1:
- data[y][x] = 2
- if x > 0: stack.append((x - 1, y))
- if x < (xSize - 1): stack.append((x + 1, y))
- if y > 0: stack.append((x, y - 1))
- if y < (ySize - 1): stack.append((x, y + 1))
- print('\n'.join(''.join([f(maparray[y][x]) for x in range(len(maparray[0]))]) for y in range(len(maparray))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement