X Tutup
"""Langton's Ant, by Al Sweigart al@inventwithpython.com A cellular automata animation. Press Ctrl-C to stop. More info: https://en.wikipedia.org/wiki/Langton%27s_ant This code is available at https://nostarch.com/big-book-small-python-programming Tags: large, artistic, bext, simulation""" import copy, random, sys, time try: import bext except ImportError: print('This program requires the bext module, which you') print('can install by following the instructions at') print('https://pypi.org/project/Bext/') sys.exit() # Set up the constants: WIDTH, HEIGHT = bext.size() # We can't print to the last column on Windows without it adding a # newline automatically, so reduce the width by one: WIDTH -= 1 HEIGHT -= 1 # Adjustment for the quit message at the bottom. NUMBER_OF_ANTS = 10 # (!) Try changing this to 1 or 50. PAUSE_AMOUNT = 0.1 # (!) Try changing this to 1.0 or 0.0. # (!) Try changing these to make the ants look different: ANT_UP = '^' ANT_DOWN = 'v' ANT_LEFT = '<' ANT_RIGHT = '>' # (!) Try changing these colors to one of 'black', 'red', 'green', # 'yellow', 'blue', 'purple', 'cyan', or 'white'. (These are the only # colors that the bext module supports.) ANT_COLOR = 'red' BLACK_TILE = 'black' WHITE_TILE = 'white' NORTH = 'north' SOUTH = 'south' EAST = 'east' WEST = 'west' def main(): bext.fg(ANT_COLOR) # The ants' color is the foreground color. bext.bg(WHITE_TILE) # Set the background to white to start. bext.clear() # Create a new board data structure: board = {'width': WIDTH, 'height': HEIGHT} # Create ant data structures: ants = [] for i in range(NUMBER_OF_ANTS): ant = { 'x': random.randint(0, WIDTH - 1), 'y': random.randint(0, HEIGHT - 1), 'direction': random.choice([NORTH, SOUTH, EAST, WEST]), } ants.append(ant) # Keep track of which tiles have changed and need to be redrawn on # the screen: changedTiles = [] while True: # Main program loop. displayBoard(board, ants, changedTiles) changedTiles = [] # nextBoard is what the board will look like on the next step in # the simulation. Start with a copy of the current step's board: nextBoard = copy.copy(board) # Run a single simulation step for each ant: for ant in ants: if board.get((ant['x'], ant['y']), False) == True: nextBoard[(ant['x'], ant['y'])] = False # Turn clockwise: if ant['direction'] == NORTH: ant['direction'] = EAST elif ant['direction'] == EAST: ant['direction'] = SOUTH elif ant['direction'] == SOUTH: ant['direction'] = WEST elif ant['direction'] == WEST: ant['direction'] = NORTH else: nextBoard[(ant['x'], ant['y'])] = True # Turn counter clockwise: if ant['direction'] == NORTH: ant['direction'] = WEST elif ant['direction'] == WEST: ant['direction'] = SOUTH elif ant['direction'] == SOUTH: ant['direction'] = EAST elif ant['direction'] == EAST: ant['direction'] = NORTH changedTiles.append((ant['x'], ant['y'])) # Move the ant forward in whatever direction it's facing: if ant['direction'] == NORTH: ant['y'] -= 1 if ant['direction'] == SOUTH: ant['y'] += 1 if ant['direction'] == WEST: ant['x'] -= 1 if ant['direction'] == EAST: ant['x'] += 1 # If the ant goes past the edge of the screen, # it should wrap around to other side. ant['x'] = ant['x'] % WIDTH ant['y'] = ant['y'] % HEIGHT changedTiles.append((ant['x'], ant['y'])) board = nextBoard def displayBoard(board, ants, changedTiles): """Displays the board and ants on the screen. The changedTiles argument is a list of (x, y) tuples for tiles on the screen that have changed and need to be redrawn.""" # Draw the board data structure: for x, y in changedTiles: bext.goto(x, y) if board.get((x, y), False): bext.bg(BLACK_TILE) else: bext.bg(WHITE_TILE) antIsHere = False for ant in ants: if (x, y) == (ant['x'], ant['y']): antIsHere = True if ant['direction'] == NORTH: print(ANT_UP, end='') elif ant['direction'] == SOUTH: print(ANT_DOWN, end='') elif ant['direction'] == EAST: print(ANT_LEFT, end='') elif ant['direction'] == WEST: print(ANT_RIGHT, end='') break if not antIsHere: print(' ', end='') # Display the quit message at the bottom of the screen: bext.goto(0, HEIGHT) bext.bg(WHITE_TILE) print('Press Ctrl-C to quit.', end='') sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_AMOUNT) # If this program was run (instead of imported), run the game: if __name__ == '__main__': try: main() except KeyboardInterrupt: print("Langton's Ant, by Al Sweigart al@inventwithpython.com") sys.exit() # When Ctrl-C is pressed, end the program.
X Tutup