Last active
January 24, 2023 17:17
-
-
Save davepeck/c92696df8e7eeca6ef2099b114cd36eb to your computer and use it in GitHub Desktop.
Game of life, python CLI, entirely written by GitHub Copilot (I only wrote the comments!)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
from random import random | |
from typing import Set, Tuple | |
# Set the default BOARD_SIZE to 40 | |
BOARD_SIZE = 40 | |
def init_board_with_n_gliders(n: int) -> Set[Tuple[int, int]]: | |
"""Initialize a board with n gliders.""" | |
# Glider pattern. | |
glider = {(1, 0), (2, 1), (0, 2), (1, 2), (2, 2)} | |
# Initialize an empty board. | |
board = set() | |
# Add n gliders to random positions on the board. | |
for _ in range(n): | |
x = int(random() * (BOARD_SIZE - 3)) | |
y = int(random() * (BOARD_SIZE - 3)) | |
board.update((x + dx, y + dy) for dx, dy in glider) | |
return board | |
def game_of_life() -> None: | |
"""A compact python implementation of Conway's game of life.""" | |
# Initialize a board with BOARD_SIZE // 3 gliders. | |
board = init_board_with_n_gliders(BOARD_SIZE // 3) | |
# Run the game | |
while True: | |
print_board(board) | |
board = next_board(board) | |
time.sleep(0.25) | |
def print_board(board: Set[Tuple[int, int]]) -> None: | |
"""Print a board.""" | |
# Use ANSI escape codes to clear the screen. | |
print("\033[2J", end="") | |
# Draw the board with a border. | |
print("+" + "-" * BOARD_SIZE + "+") | |
for y in range(BOARD_SIZE): | |
print("|", end="") | |
for x in range(BOARD_SIZE): | |
# Use ANSI bright blue + unicode circle for live cells | |
print("\033[34;1m●\033[0m" if (x, y) in board else " ", end="") | |
print("|") | |
print("+" + "-" * BOARD_SIZE + "+") | |
print() | |
def next_board(board: Set[Tuple[int, int]]) -> Set[Tuple[int, int]]: | |
"""Calculate the next board.""" | |
return { | |
(x, y) | |
for x in range(BOARD_SIZE) | |
for y in range(BOARD_SIZE) | |
if is_alive((x, y), board) | |
} | |
def is_alive(cell: Tuple[int, int], board: Set[Tuple[int, int]]) -> bool: | |
"""Determine if a cell is alive.""" | |
x, y = cell | |
# Count the number of neighbors + the cell itself. | |
neighbors = sum((x + dx, y + dy) in board for dx in (-1, 0, 1) for dy in (-1, 0, 1)) | |
# If the cell is alive, it stays alive if it has 2 or 3 neighbors. | |
if cell in board: | |
return neighbors == 3 or neighbors == 4 | |
# If the cell is dead, it comes alive if it has exactly 3 neighbors. | |
return neighbors == 3 | |
if __name__ == "__main__": | |
game_of_life() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment