Advertisement
BilakshanP

Conway's Game of Life (3D)

Dec 21st, 2024
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.71 KB | Gaming | 0 0
  1. import numpy as np
  2. import pyvista as pv
  3. from matplotlib import cm
  4. from matplotlib.colors import LinearSegmentedColormap, to_rgb
  5.  
  6. def initialize_grid(size, prob=0.2):
  7.     """Initialize a 2D grid with random live cells."""
  8.     return np.random.choice([0, 1], size=size, p=[1-prob, prob])
  9.  
  10. def count_neighbors(grid, x, y):
  11.     """Count neighbors for the cell at (x, y) in the grid."""
  12.     offsets = [-1, 0, 1]
  13.     neighbors = 0
  14.     for dx in offsets:
  15.         for dy in offsets:
  16.             if dx == 0 and dy == 0:
  17.                 continue
  18.             nx, ny = x + dx, y + dy
  19.             if 0 <= nx < grid.shape[0] and 0 <= ny < grid.shape[1]:
  20.                 neighbors += grid[nx, ny]
  21.     return neighbors
  22.  
  23. def evolve(grid):
  24.     """Evolve the 2D grid to the next generation."""
  25.     new_grid = grid.copy()
  26.     for x in range(grid.shape[0]):
  27.         for y in range(grid.shape[1]):
  28.             neighbors = count_neighbors(grid, x, y)
  29.             if grid[x, y] == 1 and (neighbors < 2 or neighbors > 3):
  30.                 new_grid[x, y] = 0
  31.             elif grid[x, y] == 0 and neighbors == 3:
  32.                 new_grid[x, y] = 1
  33.     return new_grid
  34.  
  35. def create_3d_grid(history):
  36.     """Combine all generations into a single 3D grid."""
  37.     max_generations = len(history)
  38.     size_x, size_y = history[0].shape
  39.     grid_3d = np.zeros((max_generations, size_x, size_y), dtype=int)
  40.     for z, layer in enumerate(history):
  41.         grid_3d[z, :, :] = layer
  42.     return grid_3d
  43.  
  44. def get_colors(history, color_mode, start_color=None, end_color=None):
  45.     """Generate colors for the cubes based on the chosen mode."""
  46.     num_generations = len(history)
  47.  
  48.     if color_mode == "gradient":
  49.         # Use a predefined colormap
  50.         cmap = cm.get_cmap("viridis", num_generations)
  51.         return [cmap(i / (num_generations - 1))[:3] for i in range(num_generations)]
  52.    
  53.     elif color_mode == "custom_gradient":
  54.         # Create a custom gradient using start and end colors
  55.         if not start_color or not end_color:
  56.             raise ValueError("Start and end colors must be specified for custom gradient.")
  57.         cmap = LinearSegmentedColormap.from_list("custom", [start_color, end_color], num_generations)
  58.         return [cmap(i / (num_generations - 1))[:3] for i in range(num_generations)]
  59.    
  60.     elif color_mode == "fixed":
  61.         # Use a set of fixed contrasting colors
  62.         fixed_colors = [
  63.             (1, 0, 0),  # Red
  64.             (0, 1, 0),  # Green
  65.             (0, 0, 1),  # Blue
  66.             (1, 1, 0),  # Yellow
  67.             (1, 0, 1),  # Magenta
  68.             (0, 1, 1),  # Cyan
  69.         ]
  70.         return [fixed_colors[i % len(fixed_colors)] for i in range(num_generations)]
  71.    
  72.     else:
  73.         raise ValueError("Invalid color mode. Choose 'gradient', 'custom_gradient', or 'fixed'.")
  74.  
  75. def visualize_pyvista_with_colors(history, color_mode="gradient", start_color=None, end_color=None):
  76.     """Visualize the 3D grid with PyVista using cubes and flexible colors."""
  77.     grid_3d = create_3d_grid(history)
  78.     points = []
  79.     colors = get_colors(history, color_mode, start_color, end_color)
  80.  
  81.     for z, layer in enumerate(grid_3d):
  82.         for x in range(layer.shape[0]):
  83.             for y in range(layer.shape[1]):
  84.                 if grid_3d[z, x, y] == 1:
  85.                     points.append((x, y, z))
  86.    
  87.     points = np.array(points)
  88.  
  89.     # Create PyVista mesh with cubes and dynamic colors
  90.     plotter = pv.Plotter()
  91.     for i, point in enumerate(points):
  92.         gen = int(point[2])  # The generation determines the color
  93.         cube = pv.Cube(center=point, x_length=1, y_length=1, z_length=1)
  94.         plotter.add_mesh(cube, color=colors[gen], show_edges=True)
  95.     plotter.show()
  96.  
  97. def main():
  98.     size = (20, 20)  # Define the grid size
  99.     generations = 10
  100.  
  101.     # Set this to "random", "custom", or "list"
  102.     initial_input_mode = "list"
  103.  
  104.     if initial_input_mode == "random":
  105.         # Generate a random initial grid
  106.         initial_grid = initialize_grid(size)
  107.     elif initial_input_mode == "custom":
  108.         # Define a custom initial grid (modify as needed)
  109.         initial_grid = np.zeros(size, dtype=int)
  110.         initial_grid[10, 9:12] = 1  # Example: Horizontal line at the center
  111.     elif initial_input_mode == "list":
  112.         # User provides a Python list for the initial grid
  113.         user_input_list = [
  114.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  115.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  116.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  117.             [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
  118.             [0, 0, 0, 1, 0, 1, 1, 1, 0, 0],
  119.             [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
  120.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  121.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  122.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  123.             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  124.         ]
  125.         # Convert list to numpy array
  126.         initial_grid = np.array(user_input_list, dtype=int)
  127.         size = initial_grid.shape  # Update size based on user input
  128.     else:
  129.         raise ValueError("Invalid input mode. Choose 'random', 'custom', or 'list'.")
  130.  
  131.     print("Initial 2D grid (0 = dead, 1 = alive):")
  132.     print(initial_grid)
  133.  
  134.     history = [initial_grid]
  135.     current_grid = initial_grid
  136.  
  137.     for _ in range(generations):
  138.         next_grid = evolve(current_grid)
  139.         history.append(next_grid)
  140.         current_grid = next_grid
  141.  
  142.     # Choose the desired color mode
  143.     color_mode = "custom_gradient"  # "gradient", "custom_gradient", or "fixed"
  144.     start_color = (1, 0, 0)  # RGB (for custom_gradient)
  145.     end_color = (0, 0, 1)    # RGB (for custom_gradient)
  146.  
  147.     visualize_pyvista_with_colors(history, color_mode=color_mode, start_color=start_color, end_color=end_color)
  148.  
  149. if __name__ == "__main__":
  150.     main()
  151.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement