Grifter

Diamond Square Algorithm

Aug 19th, 2014
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.88 KB | None | 0 0
  1. __author__ = 'Grifter'
  2.  
  3. from random import gauss
  4. from math import sqrt
  5.  
  6.  
  7. class Square():
  8.     def __init__(self, a, b, c, d, order=0, chaos=0):
  9.         """
  10.        Data structure for squares in the Diamond Square Algorithm
  11.  
  12.        :param a: Top left corner height
  13.        :param b: Top right corner height
  14.        :param c: Bottom left corner height
  15.        :param d: Bottom right corner height
  16.        :param order: Order of recursion depth
  17.        :param chaos: Amount of chaos to induce
  18.        """
  19.         #Square data
  20.         self.order = order
  21.         self.chaos = chaos
  22.         self.heights = [float(a), float(b), float(c), float(d)]
  23.         self.sub_squares = []
  24.  
  25.         #Stochastic variables
  26.         self.random = gauss(0, 5)
  27.         self.random_scalar = self.chaos / (1 + self.order ** 2)
  28.  
  29.         #Recursion handler
  30.         if self.order < iterations:
  31.             self.sub_square_generation()
  32.         else:
  33.             final_squares.append(self.heights)
  34.  
  35.     def sub_square_generation(self):
  36.  
  37.         # Top left square generation
  38.         self.sub_squares.append(Square(
  39.             self.heights[0],
  40.             0.5 * (self.heights[0] + self.heights[1]),
  41.             0.5 * (self.heights[0] + self.heights[2]),
  42.             0.25 * sum(self.heights) + (self.random_scalar * self.random),
  43.             self.order + 1,
  44.             self.chaos
  45.         ))
  46.  
  47.         # Top right square generation
  48.         self.sub_squares.append(Square(
  49.             0.5 * (self.heights[0] + self.heights[1]),
  50.             self.heights[1],
  51.             0.25 * sum(self.heights) + (self.random_scalar * self.random),
  52.             0.5 * (self.heights[1] + self.heights[3]),
  53.             self.order + 1,
  54.             self.chaos
  55.         ))
  56.  
  57.         # Bottom left square generation
  58.         self.sub_squares.append(Square(
  59.             0.5 * (self.heights[0] + self.heights[2]),
  60.             0.25 * sum(self.heights) + + (self.random_scalar * self.random),
  61.             self.heights[2],
  62.             0.5 * (self.heights[2] + self.heights[3]),
  63.             self.order + 1,
  64.             self.chaos
  65.         ))
  66.  
  67.         # Bottom right square generation
  68.         self.sub_squares.append(Square(
  69.             0.25 * sum(self.heights) + self.random_scalar + (self.random_scalar * self.random),
  70.             0.5 * (self.heights[1] + self.heights[3]),
  71.             0.5 * (self.heights[2] + self.heights[3]),
  72.             self.heights[3],
  73.             self.order + 1,
  74.             self.chaos
  75.         ))
  76.  
  77.  
  78. class Generator():
  79.     def __init__(self, c):
  80.  
  81.         """
  82.        Generate fractal landscape using DSA
  83.  
  84.        :param c: Chaos factor of fractal
  85.        """
  86.         #Repository for final height map
  87.         self.map_array = []
  88.         #Generate Terrain
  89.         self.terrain = Square(0, 0, 0, 0, chaos=c)
  90.         #Collect final data from external variable
  91.         self.final_squares = final_squares
  92.         for i in range(iterations):
  93.             self.combine_list()
  94.         self.construct_map()
  95.  
  96.     def combine_squares(self, a, b, c, d):
  97.         temp = []
  98.         for row in range(0, int(sqrt(len(a)))):
  99.             for column in range(0, int(sqrt(len(a)))):
  100.                 temp.append(a[row * int(sqrt(len(a))) + column])
  101.             column = 0
  102.             while column < sqrt(len(b)):
  103.                 if column != 0:
  104.                     temp.append(b[row * int(sqrt(len(b))) + column])
  105.                 column += 1
  106.         for row in range(0, int(sqrt(len(c)))):
  107.             column = 0
  108.             while column < sqrt(len(c)):
  109.                 if row != 0:
  110.                     temp.append(c[row * int(sqrt(len(c))) + column])
  111.                 column += 1
  112.  
  113.             column = 0
  114.             while column < sqrt(len(d)):
  115.                 if column != 0 and row != 0:
  116.                     temp.append(d[row * int(sqrt(len(d))) + column])
  117.                 column += 1
  118.  
  119.         return temp
  120.  
  121.     def combine_list(self):
  122.         temp = []
  123.         i = 0
  124.         while i < len(self.final_squares) / 4:
  125.             temp.append(self.combine_squares(self.final_squares[i * 4],
  126.                                              self.final_squares[i * 4 + 1],
  127.                                              self.final_squares[i * 4 + 2],
  128.                                              self.final_squares[i * 4 + 3]))
  129.             i += 1
  130.         self.final_squares = temp
  131.  
  132.     def construct_map(self):
  133.         for i in range(int(sqrt(len(self.final_squares[0])))):
  134.             self.map_array.append([])
  135.         for i in range(len(self.final_squares[0])):
  136.             self.map_array[int(i / len(self.map_array))].append(self.final_squares[0][i])
  137.  
  138.     def __str__(self):
  139.         temp_str = ''
  140.         for i in self.map_array:
  141.             temp_str = temp_str + str(i) + '\n'
  142.         return temp_str
  143.  
  144.     def dump(self):
  145.         return self.map_array
  146.  
  147.  
  148. iterations = 5
  149. final_squares = []
  150. gen = Generator(1)
  151.  
  152. data = gen.dump()
Advertisement
Add Comment
Please, Sign In to add comment