def main(): # Setup the screen. bext.bg('black') bext.clear() global FISHES, BUBBLERS, BUBBLES, KELPS # Generate the global variables: FISHES = [] for i in range(NUM_FISH): FISHES.append(generateFish()) BUBBLERS = [] # NOTE: Bubbles are drawn, but not the bubblers themselves. for i in range(NUM_BUBBLERS): # Each bubbler starts at a random position. BUBBLERS.append(random.randint(0, WIDTH - 1)) BUBBLES = [] KELPS = [] for i in range(NUM_KELP): kelp = {'x': random.randint(0, WIDTH - 2), 'segments': []} # Generate each segment of the kelp. for i in range(random.randint(6, HEIGHT - 1)): kelp['segments'].append(random.choice(['(', ')'])) KELPS.append(kelp) # Run the simulation: step = 1 while True: drawAquarium(step) time.sleep(1 / FRAMES_PER_SECOND) clearAquarium() #bext.clear() step += 1
def main(): theFloor = getNewFloor() paintedAreas = set() # Generate painters: painters = [] for color in THE_PAINTERS: painters.append(Painter(color, theFloor)) bext.fg('black') bext.clear() while True: # Main simulation loop. for painter in painters: # Keep track of the painted floors: paintedAreas.add((painter.x, painter.y)) if len(paintedAreas) == WIDTH * HEIGHT: # Move the text cursor to the bottom right so that # new text doesn't overwrite our painting. bext.goto(bext.width() - 1, bext.height() - 1) print() # Print a newline. print('Seed: {} Width: {} Height: {}'.format( SEED, (WIDTH + 1) * 2, HEIGHT)) sys.exit() # The floor is completely painted, so quit. painter.move() sys.stdout.flush() time.sleep(PAUSE_LENGTH)
def main(): global FISHES, BUBBLERS, BUBBLES, KELPS, STEP bext.bg('black') bext.clear() # Generate the global variables: FISHES = [] for i in range(NUM_FISH): FISHES.append(generateFish()) # NOTE: Bubbles are drawn, but not the bubblers themselves. BUBBLERS = [] for i in range(NUM_BUBBLERS): # Each bubbler starts at a random position. BUBBLERS.append(random.randint(LEFT_EDGE, RIGHT_EDGE)) BUBBLES = [] KELPS = [] for i in range(NUM_KELP): kelpx = random.randint(LEFT_EDGE, RIGHT_EDGE) kelp = {'x': kelpx, 'segments': []} # Generate each segment of the kelp: for i in range(random.randint(6, HEIGHT - 1)): kelp['segments'].append(random.choice(['(', ')'])) KELPS.append(kelp) # Run the simulation: STEP = 1 while True: simulateAquarium() drawAquarium() time.sleep(1 / FRAMES_PER_SECOND) clearAquarium() STEP += 1
def main(): bext.bg('black') bext.fg('white') bext.clear() print('''Flood It, by Al Sweigart [email protected] Set the color of the upper left square, which fills in all the adjacent squares of that color. Try to make the entire board the same color.''') gameBoard = getNewBoard() movesLeft = 20 while True: # Main game loop. displayBoard(gameBoard) print('Moves left:', movesLeft) playerMove = askForPlayerMove() changeTile(playerMove, gameBoard, 0, 0) movesLeft -= 1 if hasWon(gameBoard): displayBoard(gameBoard) print('You have won!') break elif movesLeft == 0: displayBoard(gameBoard) print('You have run out of moves!') break
def main(): global FISHES, BUBBLERS, BUBBLES, KELPS # Generate the global variables: FISHES = [] for i in range(NUM_FISH): FISHES.append(generateFish()) BUBBLERS = [] # NOTE: Bubbles are drawn, but not the bubblers themselves. for i in range(NUM_BUBBLERS): # Each bubbler starts at a random position. BUBBLERS.append(random.randint(0, WIDTH - 1)) BUBBLES = [] KELPS = [] for i in range(NUM_KELP): kelp = {'x': random.randint(0, WIDTH - 2), 'segments': []} # Generate each segment of the kelp. for i in range(random.randint(6, HEIGHT - 1)): kelp['segments'].append(random.choice(['(', ')'])) KELPS.append(kelp) # Run the simulation: step = 1 while True: try: drawAquarium(step) time.sleep(PAUSE) bext.clear() step += 1 except KeyboardInterrupt: sys.exit()
def draw(): global DESIRED, generations most_fit = population[fittest_index] most_fit_score = fitness_pool[fittest_index] bext.clear() # bext.goto(0, 0) generations = generations + 1 print("most fit: " + "".join(most_fit)) print("generations: " + str(generations)) return most_fit_score == fitness(DESIRED)
def main(): global PAUSE step = 0 # bext.bg('white') while True: try: update() bext.clear() draw(step) time.sleep(PAUSE) step += 1 except KeyboardInterrupt: sys.exit()
def main(): """Run the Forest Fire simulation.""" forest = createNewForest() bext.clear() while True: # Main program loop. displayForest(forest) # Run a single simulation step: nextForest = {'width': forest['width'], 'height': forest['height']} for x in range(forest['width']): for y in range(forest['height']): if (x, y) in nextForest: # If we've already set nextForest[(x, y)] on a # previous iteration, just do nothing here: continue if (forest[(x, y)] == EMPTY) and ( random.randint(1, 10000) / 100 <= GROW_CHANCE): # Grow a tree in this empty space: nextForest[(x, y)] = TREE elif (forest[(x, y)] == TREE) and ( random.randint(1, 10000) / 100 <= LIGHTNING_CHANCE): # Lightning sets this tree on fire: nextForest[(x, y)] = FIRE elif forest[(x, y)] == FIRE: # Fire spreads to neighboring trees: for ix in range(-1, 2): for iy in range(-1, 2): if (x + ix, y + iy) in forest: if forest[(x + ix, y + iy)] == TREE: nextForest[(x + ix, y + iy)] = FIRE else: nextForest[(x + ix, y + iy)] = forest[(x + ix, y + iy)] # The tree has burned down now, so erase it: nextForest[(x, y)] = EMPTY else: # Just copy the existing object: nextForest[(x, y)] = forest[(x, y)] forest = nextForest time.sleep(PAUSE_LENGTH)
def main(): global PAUSE, MAX_POPULATION, population, next_population step = 0 for i in range(0, MAX_POPULATION): population.append(generate_random()) while True: try: update() bext.clear() if draw(): return population = next_population time.sleep(PAUSE) step += 1 except KeyboardInterrupt: sys.exit()
def main(): # Generate snake data structures: snakes = [] for i in range(NUMBER_OF_SNAKES): snakes.append(Snake()) bext.clear() while True: # Main simulation loop. # Draw quit message. bext.fg('white') bext.goto(0, 0) print('Ctrl-C to quit.', end='') for snake in snakes: snake.display() for snake in snakes: snake.moveRandom() sys.stdout.flush() time.sleep(PAUSE_LENGTH)
def main(): # Generate worm data structures: worms = [] for i in range(NUMBER_OF_WORMS): worms.append(Worm()) bext.clear() while True: # Main simulation loop. # Draw quit message. bext.fg('white') bext.goto(0, 0) print('Ctrl-C to quit.', end='') for worm in worms: worm.display() for worm in worms: worm.moveRandom() sys.stdout.flush() time.sleep(PAUSE_LENGTH)
def main(): theFloor = getNewFloor() # Generate painters: painters = [] for color in THE_PAINTERS: painters.append(Painter(color, theFloor)) bext.fg('black') bext.clear() while True: # Main simulation loop. # Draw quit message. bext.bg('white') bext.goto(0, 0) print('Ctrl-C to quit.', end='') for painter in painters: painter.move() sys.stdout.flush() time.sleep(PAUSE_LENGTH)
def main(): bext.fg('yellow') bext.clear() # Draw the quit message: bext.goto(0, 0) print('Ctrl-C to quit.', end='') # Display the walls of the hourglass: for wall in HOURGLASS: bext.goto(wall[X], wall[Y]) print(WALL, end='') while True: # Main program loop. allSand = list(INITIAL_SAND) # Draw the initial sand: for sand in allSand: bext.goto(sand[X], sand[Y]) print(SAND, end='') runHourglassSimulation(allSand)
def main(): bext.bg('black') bext.fg('white') bext.clear() print('''Floodplane, by Al Sweigart [email protected] Set the upper left color/shape, which fills in all the adjacent squares of that color/shape. Try to make the entire board the same color/shape.''') print('Do you want to play in colorblind mode? Y/N') response = input('> ') if response.upper().startswith('Y'): displayMode = SHAPE_MODE else: displayMode = COLOR_MODE gameBoard = getNewBoard() movesLeft = MOVES_PER_GAME while True: # Main game loop. displayBoard(gameBoard, displayMode) print('Moves left:', movesLeft) playerMove = askForPlayerMove(displayMode) changeTile(playerMove, gameBoard, 0, 0) movesLeft -= 1 if hasWon(gameBoard): displayBoard(gameBoard, displayMode) print('You have won!') break elif movesLeft == 0: displayBoard(gameBoard, displayMode) print('You have run out of moves!') break
def main(): bext.clear() # Generate some dots. dots = [] for i in range(NUMBER_OF_DOTS): dots.append({ COLOR: random.choice(COLORS), X: random.randint(1, WIDTH - 2), Y: random.randint(1, HEIGHT - 2), DIR: random.choice(DIRECTIONS) }) while True: # Main program loop. for dot in dots: # Handle each dot in the dots list. # Erase the dot's current location: bext.goto(dot[X], dot[Y]) print(' ', end='') # Move the dot: if dot[DIR] == UP_RIGHT: dot[X] += 1 dot[Y] -= 1 elif dot[DIR] == UP_LEFT: dot[X] -= 1 dot[Y] -= 1 elif dot[DIR] == DOWN_RIGHT: dot[X] += 1 dot[Y] += 1 elif dot[DIR] == DOWN_LEFT: dot[X] -= 1 dot[Y] += 1 # Draw the dots at their new location: bext.goto(dot[X], dot[Y]) bext.fg(dot[COLOR]) print(DOT_CHAR, end='') # See if the dot bounces off the corners: if dot[X] == 0 and dot[Y] == 0: dot[DIR] = DOWN_RIGHT elif dot[X] == 0 and dot[Y] == HEIGHT - 1: dot[DIR] = UP_RIGHT elif dot[X] == WIDTH - 1 and dot[Y] == 0: dot[DIR] = DOWN_LEFT elif dot[X] == WIDTH - 1 and dot[Y] == HEIGHT - 1: dot[DIR] = UP_LEFT # See if the dot bounces off the left edge: elif dot[X] == 0 and dot[DIR] == UP_LEFT: dot[DIR] = UP_RIGHT elif dot[X] == 0 and dot[DIR] == DOWN_LEFT: dot[DIR] = DOWN_RIGHT # See if the dot bounces off the right edge: elif dot[X] == WIDTH - 1 and dot[DIR] == UP_RIGHT: dot[DIR] = UP_LEFT elif dot[X] == WIDTH - 1 and dot[DIR] == DOWN_RIGHT: dot[DIR] = DOWN_LEFT # See if the dot bounces off the top edge: elif dot[Y] == 0 and dot[DIR] == UP_LEFT: dot[DIR] = DOWN_LEFT elif dot[Y] == 0 and dot[DIR] == UP_RIGHT: dot[DIR] = DOWN_RIGHT # See if the dot bounces off the bottom edge: elif dot[Y] == HEIGHT - 1 and dot[DIR] == DOWN_LEFT: dot[DIR] = UP_LEFT elif dot[Y] == HEIGHT - 1 and dot[DIR] == DOWN_RIGHT: dot[DIR] = UP_RIGHT sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_AMOUNT)
def main(): print('Conway\'s Game of Life') print('By Al Sweigart [email protected]') print('Press Ctrl-C to quit...') time.sleep(3) # Create random cells: currentCells = {} nextCells = {} previousCells = {} for x in range(WIDTH): for y in range(HEIGHT): if random.randint(0, 1) == 0: nextCells[x, y] = True bext.clear() while True: # Main program loop. previousCells = currentCells currentCells = nextCells # Print the cells: for y in range(0, HEIGHT, 2): # Skip every other row. for x in range(WIDTH): prevTopHalf = previousCells.get((x, y), False) curTopHalf = currentCells.get((x, y), False) topHalfHasChanged = prevTopHalf != curTopHalf prevBottomHalf = previousCells.get((x, y + 1), False) curBottomHalf = currentCells.get((x, y + 1), False) bottomHalfHasChanged = prevBottomHalf != curBottomHalf if topHalfHasChanged or bottomHalfHasChanged: bext.goto(x, y // 2) if curTopHalf and curBottomHalf: # Fill in both halves: print(FULL_BLOCK, end='') elif curTopHalf and not curBottomHalf: # Fill in top half: print(TOP_BLOCK, end='') elif not curTopHalf and curBottomHalf: # Fill in bottom half: print(BOTTOM_BLOCK, end='') elif not curTopHalf and not curBottomHalf: # Fill in nothing: print(' ', end='') print() # Print a newline at the end of the row. print('Press Ctrl-C to quit.', end='', flush=True) # Calculate next cells based on current cells: nextCells = {} for x in range(WIDTH): for y in range(HEIGHT): # Get neighboring coordinates: leftCoord = (x - 1) % WIDTH rightCoord = (x + 1) % WIDTH topCoord = (y - 1) % HEIGHT bottomCoord = (y + 1) % HEIGHT # Count number of living neighbors: numNeighbors = 0 if (leftCoord, topCoord) in currentCells: numNeighbors += 1 if (x, topCoord) in currentCells: numNeighbors += 1 if (rightCoord, topCoord) in currentCells: numNeighbors += 1 if (leftCoord, y) in currentCells: numNeighbors += 1 if (rightCoord, y) in currentCells: numNeighbors += 1 if (leftCoord, bottomCoord) in currentCells: numNeighbors += 1 if (x, bottomCoord) in currentCells: numNeighbors += 1 if (rightCoord, bottomCoord) in currentCells: numNeighbors += 1 # Set cell based on Conway's Game of Life rules: if currentCells.get((x, y), False): if numNeighbors in (2, 3): nextCells[x, y] = True else: if numNeighbors == 3: nextCells[x, y] = True time.sleep(PAUSE_LENGTH) # Pause to reduce flickering.
def main(): # Create a new board data structure. board = {'width': WIDTH, 'height': HEIGHT} for x in range(WIDTH): for y in range(HEIGHT): if (random.randint(1, 10000) / 100) <= INITIAL_TREE_DENSITY: board[(x, y)] = 'A' # Start as a tree. else: board[(x, y)] = ' ' # Start as an empty space. # Create firewalls for i in range(NUMBER_OF_FIREWALLS): if random.randint(0, 1) == 0: # Make a horizontal firewall: x = random.randint(0, max(WIDTH - FIREWALL_LENGTH - 1, 0)) y = random.randint(0, HEIGHT) for ix in range(FIREWALL_LENGTH): board[(x + ix, y)] = WALL_CHAR else: # Make a vertical firewall: x = random.randint(0, WIDTH) y = random.randint(0, max(HEIGHT - (FIREWALL_LENGTH // 2) - 1, 0)) for iy in range(FIREWALL_LENGTH // 2): board[(x, y + iy)] = WALL_CHAR bext.clear() while True: # Main program loop. # Draw the board data structure. bext.goto(0, 0) for y in range(board['height']): for x in range(board['width']): if board[(x, y)] == 'A': bext.fg('green') print('A', end='') elif board[(x, y)] == 'W': bext.fg('red') print('W', end='') else: bext.fg('reset') print(board[(x, y)], end='') print() bext.fg('reset') # Use the default font color. print('Grow chance: {}% Lightning chance: {}%'.format(GROW_CHANCE, LIGHTNING_CHANCE)) print('Press Ctrl-C to quit.') # Run a single simulation step: nextBoard = {'width': board['width'], 'height': board['height']} for x in range(board['width']): for y in range(board['height']): if (x, y) in nextBoard: # If we've already set nextBoard[(x, y)] on a previous iteration, just do nothing here. continue if board[(x, y)] == ' ' and (random.randint(1, 10000) / 100) <= GROW_CHANCE: # Grow a tree in this empty space: nextBoard[(x, y)] = 'A' # The letter 'A' sort of looks like a tree. elif board[(x, y)] == 'A' and (random.randint(1, 10000) / 100) <= LIGHTNING_CHANCE: # Lightning sets this tree on fire: nextBoard[(x, y)] = 'W' elif board[(x, y)] == 'W': # Fire spreads to neighboring trees. for ix in range(-1, 2): for iy in range(-1, 2): #if (0 <= x + ix < board['width']) and (0 <= y + iy < board['height']): if (x + ix, y + iy) in board: if board[(x + ix, y + iy)] == 'A': nextBoard[(x + ix, y + iy)] = 'W' else: nextBoard[(x + ix, y + iy)] = board[(x + ix, y + iy)] nextBoard[(x, y)] = ' ' # The original tree has burned down now. else: # Just copy the existing object. nextBoard[(x, y)] = board[(x, y)] board = nextBoard time.sleep(PAUSE_LENGTH)
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 main(): bext.clear() # Generate some dots. dots = [] for i in range(NUMBER_OF_DOTS): dots.append({ COLOR: random.choice(COLORS), X: random.randint(1, WIDTH - 2), Y: random.randint(1, HEIGHT - 2), DIR: random.choice(DIRECTIONS) }) while True: # Main program loop. oldDotPositions = [] for dot in dots: # Draw our dots: bext.goto(dot[X], dot[Y]) bext.fg(dot[COLOR]) print(DOT_CHAR, end='') oldDotPositions.append((dot[X], dot[Y])) sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_AMOUNT) for dot in dots: # Move our dots: if dot[DIR] == UP_RIGHT: dot[X] += 1 dot[Y] -= 1 elif dot[DIR] == UP_LEFT: dot[X] -= 1 dot[Y] -= 1 elif dot[DIR] == DOWN_RIGHT: dot[X] += 1 dot[Y] += 1 elif dot[DIR] == DOWN_LEFT: dot[X] -= 1 dot[Y] += 1 # See if our dots bounce off the corners: if dot[X] == 0 and dot[Y] == 0: dot[DIR] = DOWN_RIGHT elif dot[X] == 0 and dot[Y] == HEIGHT - 1: dot[DIR] = UP_RIGHT elif dot[X] == WIDTH - 1 and dot[Y] == 0: dot[DIR] = DOWN_LEFT elif dot[X] == WIDTH - 1 and dot[Y] == HEIGHT - 1: dot[DIR] = UP_LEFT # See if our dots bounce off the walls: elif dot[X] == 0 and dot[DIR] == UP_LEFT: dot[DIR] = UP_RIGHT elif dot[X] == 0 and dot[DIR] == DOWN_LEFT: dot[DIR] = DOWN_RIGHT elif dot[X] == WIDTH - 1 and dot[DIR] == UP_RIGHT: dot[DIR] = UP_LEFT elif dot[X] == WIDTH - 1 and dot[DIR] == DOWN_RIGHT: dot[DIR] = DOWN_LEFT elif dot[Y] == 0 and dot[DIR] == UP_LEFT: dot[DIR] = DOWN_LEFT elif dot[Y] == 0 and dot[DIR] == UP_RIGHT: dot[DIR] = DOWN_RIGHT elif dot[Y] == HEIGHT - 1 and dot[DIR] == DOWN_LEFT: dot[DIR] = UP_LEFT elif dot[Y] == HEIGHT - 1 and dot[DIR] == DOWN_RIGHT: dot[DIR] = UP_RIGHT for position in oldDotPositions: # Erase all of the dots. bext.goto(position[0], position[1]) print(' ', end='')
def main(): bext.clear() # Generate some points. points = [] for i in range(NUMBER_OF_POINTS): points.append({ X: random.randint(1, WIDTH - 2), Y: random.randint(1, HEIGHT - 2), DIR: random.choice(DIRECTIONS) }) while True: # Main program loop. oldpointPositions = [] if random.randint(1, 50) == 1: bext.fg('random') for i, point in enumerate(points): # Draw our lines: if i == len(points) - 1: # The last point connects to the first point. pointA = point pointB = points[0] else: pointA = point pointB = points[i + 1] for x, y in line(pointA[X], pointA[Y], pointB[X], pointB[Y]): bext.goto(x, y) print(LINE_CHAR, end='') oldpointPositions.append((x, y)) sys.stdout.flush() # (Required for bext-using programs.) time.sleep(0.1) for point in points: # Move our points: if point[DIR] == UP_RIGHT: point[X] += 1 point[Y] -= 1 elif point[DIR] == UP_LEFT: point[X] -= 1 point[Y] -= 1 elif point[DIR] == DOWN_RIGHT: point[X] += 1 point[Y] += 1 elif point[DIR] == DOWN_LEFT: point[X] -= 1 point[Y] += 1 # See if our points bounce off the corners: if point[X] == 0 and point[Y] == 0: point[DIR] = DOWN_RIGHT elif point[X] == 0 and point[Y] == HEIGHT - 1: point[DIR] = UP_RIGHT elif point[X] == WIDTH - 1 and point[Y] == 0: point[DIR] = DOWN_LEFT elif point[X] == WIDTH - 1 and point[Y] == HEIGHT - 1: point[DIR] = UP_LEFT # See if our points bounce off the walls: elif point[X] == 0 and point[DIR] == UP_LEFT: point[DIR] = UP_RIGHT elif point[X] == 0 and point[DIR] == DOWN_LEFT: point[DIR] = DOWN_RIGHT elif point[X] == WIDTH - 1 and point[DIR] == UP_RIGHT: point[DIR] = UP_LEFT elif point[X] == WIDTH - 1 and point[DIR] == DOWN_RIGHT: point[DIR] = DOWN_LEFT elif point[Y] == 0 and point[DIR] == UP_LEFT: point[DIR] = DOWN_LEFT elif point[Y] == 0 and point[DIR] == UP_RIGHT: point[DIR] = DOWN_RIGHT elif point[Y] == HEIGHT - 1 and point[DIR] == DOWN_LEFT: point[DIR] = UP_LEFT elif point[Y] == HEIGHT - 1 and point[DIR] == DOWN_RIGHT: point[DIR] = UP_RIGHT for position in oldpointPositions: # Erase all of the points. bext.goto(position[0], position[1]) print(' ', end='')
def main(): bext.clear() # Generate some points. points = [] for i in range(NUMBER_OF_POINTS): points.append({ X: random.randint(1, WIDTH - 2), Y: random.randint(1, HEIGHT - 2), DIR: random.choice(DIRECTIONS) }) while True: # Main program loop. # There's a 1 in 50 chance of changing the color. if random.randint(1, 50) == 1: bext.fg('random') # Erase the lines drawn previously at these points. drawLinesBetweenPoints(points, ' ') for point in points: # Move the points in the direction of point[DIR]: if point[DIR] == UP_RIGHT: point[X] += 1 point[Y] -= 1 elif point[DIR] == UP_LEFT: point[X] -= 1 point[Y] -= 1 elif point[DIR] == DOWN_RIGHT: point[X] += 1 point[Y] += 1 elif point[DIR] == DOWN_LEFT: point[X] -= 1 point[Y] += 1 # See if the point bounces off the corners: if point[X] == 0 and point[Y] == 0: point[DIR] = DOWN_RIGHT elif point[X] == 0 and point[Y] == HEIGHT - 1: point[DIR] = UP_RIGHT elif point[X] == WIDTH - 1 and point[Y] == 0: point[DIR] = DOWN_LEFT elif point[X] == WIDTH - 1 and point[Y] == HEIGHT - 1: point[DIR] = UP_LEFT # See if the dot bounces off the left edge: elif point[X] == 0 and point[DIR] == UP_LEFT: point[DIR] = UP_RIGHT elif point[X] == 0 and point[DIR] == DOWN_LEFT: point[DIR] = DOWN_RIGHT # See if the dot bounces off the right edge: elif point[X] == WIDTH - 1 and point[DIR] == UP_RIGHT: point[DIR] = UP_LEFT elif point[X] == WIDTH - 1 and point[DIR] == DOWN_RIGHT: point[DIR] = DOWN_LEFT # See if the dot bounces off the top edge: elif point[Y] == 0 and point[DIR] == UP_LEFT: point[DIR] = DOWN_LEFT elif point[Y] == 0 and point[DIR] == UP_RIGHT: point[DIR] = DOWN_RIGHT # See if the dot bounces off the bottom edge: elif point[Y] == HEIGHT - 1 and point[DIR] == DOWN_LEFT: point[DIR] = UP_LEFT elif point[Y] == HEIGHT - 1 and point[DIR] == DOWN_RIGHT: point[DIR] = UP_RIGHT # Draw the points in their new position: drawLinesBetweenPoints(points, LINE_CHAR) sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_AMOUNT)
def main(): # Draw the initially uncut grass field: bext.clear() if sys.platform == 'win32': bext.hide() # Currently, hiding the cursor only works on Windows. bext.fg('green') for i in range(HEIGHT): print(';' * WIDTH) print('Press Ctrl-C to quit.') # mowerx and mowery refer to the left edge of the lower, despite direction. mowerx = -MOWER_LEN mowery = 0 mowerDirection = 'right' growMode = False while True: # Main program loop. # Draw the mower: drawMower(mowerx, mowery, mowerDirection) # Draw the cut grass: if (mowerDirection == 'right') and (mowerx - 1 >= 0): bext.goto(mowerx - 1, mowery) bext.fg('green') print(',', end='') elif (mowerDirection == 'left') and (mowerx < WIDTH - MOWER_LEN): bext.goto(mowerx + MOWER_LEN, mowery) bext.fg('green') print(',', end='') # Move the mower: if mowerDirection == 'right': mowerx += 1 # Move the mower right. if mowerx > WIDTH: # After going past the right edge, # change position and direction. mowerDirection = 'left' mowery += 1 if mowery == HEIGHT: # Done mowing, let the grass grow back: growMode = True elif mowerDirection == 'left': mowerx -= 1 # Move the mower left. if mowerx < -MOWER_LEN: # After going past the left edge, # change position and direction. mowerDirection = 'right' mowery += 1 if mowery == HEIGHT: # Done mowing, let the grass grow back. growMode = True sys.stdout.flush() # (Required for bext-using programs.) time.sleep(MOWING_PAUSE) # Pause after mowing. if growMode: # Let the grass grow back one at a time: mowerx = -MOWER_LEN # Reset mower position. mowery = 0 # Reset mower position. bext.fg('green') # Create a set of all the places the grass needs to grow: grassToGrow = set() for x in range(WIDTH): for y in range(HEIGHT): grassToGrow.add((x, y)) # Grow the grass: while len(grassToGrow) > 0: x, y = random.sample(grassToGrow, 1)[0] grassToGrow.remove((x, y)) bext.goto(x, y) print(';') try: time.sleep(GROWING_PAUSE) # Pause after growing. except KeyboardInterrupt: sys.exit() # When Ctrl-C is pressed, end the program. growMode = False # Done growing grass.
def main(): bext.clear() # Draw the circle of the clock: for y, row in enumerate(CLOCKFACE.splitlines()): for x, char in enumerate(row): if char != ' ': bext.goto(x, y) print(char) while True: # Main program loop. # Get the current time from the computer's clock: currentTime = time.localtime() h = currentTime.tm_hour % 12 # Use 12-hour clock, not 24. m = currentTime.tm_min s = currentTime.tm_sec # Draw the second hand: secHandDirection = COMPLETE_ARC * (s / 60) + OFFSET_90_DEGREES secHandXPos = math.cos(secHandDirection) secHandYPos = math.sin(secHandDirection) secHandX = int(secHandXPos * SECOND_HAND_LENGTH + CENTERX) secHandY = int(secHandYPos * SECOND_HAND_LENGTH + CENTERY) secHandPoints = line(CENTERX, CENTERY, secHandX, secHandY) for x, y in secHandPoints: bext.goto(x, y) print(SECOND_HAND_CHAR, end='') # Draw the minute hand: minHandDirection = COMPLETE_ARC * (m / 60) + OFFSET_90_DEGREES minHandXPos = math.cos(minHandDirection) minHandYPos = math.sin(minHandDirection) minHandX = int(minHandXPos * MINUTE_HAND_LENGTH + CENTERX) minHandY = int(minHandYPos * MINUTE_HAND_LENGTH + CENTERY) minHandPoints = line(CENTERX, CENTERY, minHandX, minHandY) for x, y in minHandPoints: bext.goto(x, y) print(MINUTE_HAND_CHAR, end='') # Draw the hour hand: hourHandDirection = COMPLETE_ARC * (h / 12) + OFFSET_90_DEGREES hourHandXPos = math.cos(hourHandDirection) hourHandYPos = math.sin(hourHandDirection) hourHandX = int(hourHandXPos * HOUR_HAND_LENGTH + CENTERX) hourHandY = int(hourHandYPos * HOUR_HAND_LENGTH + CENTERY) hourHandPoints = line(CENTERX, CENTERY, hourHandX, hourHandY) for x, y in hourHandPoints: bext.goto(x, y) print(HOUR_HAND_CHAR, end='') sys.stdout.flush() # (Required for bext-using programs.) # Keep looping until the second changes: while True: time.sleep(0.01) if time.localtime().tm_sec != currentTime.tm_sec: break # Erase the clock hands: for x, y in secHandPoints: bext.goto(x, y) print(' ', end='') for x, y in minHandPoints: bext.goto(x, y) print(' ', end='') for x, y in hourHandPoints: bext.goto(x, y) print(' ', end='')
def main(): baseX = random.randint(0, WIDTH - 1) baseY = random.randint(0, HEIGHT - 1) vbotX = baseX vbotY = baseY vbotBattery = MAX_BATTERY dirtPiles = {} # Keys are (x, y) tuples, value is dirt level. for x in range(WIDTH): for y in range(HEIGHT): dirtPiles[(x, y)] = 0 # Set it to no dirt to begin with. # Add some dirt to start with: bext.clear() # Clear the terminal window. for i in range(NUM_STARTING_DIRT): newDirtX = random.randint(0, WIDTH - 1) newDirtY = random.randint(0, HEIGHT - 1) dirtPiles[(newDirtX, newDirtY)] = 1 bext.goto(newDirtX, newDirtY) print(DIRT_CHARS[dirtPiles[(newDirtX, newDirtY)]], end='') moveTo = [] # A list of (x, y) tuples to move to in turn. while True: # Main simulation loop. vbotStatus = CLEANING # Add dirt to the room: if random.randint(0, 100) <= DIRT_ADD_FREQUENCY: for i in range(DIRT_ADD_AMOUNT): newDirtX = random.randint(0, WIDTH - 1) newDirtY = random.randint(0, HEIGHT - 1) # Dirt piles max out at 3, so only add dirt if the dirt # level is less than 3: if dirtPiles[(newDirtX, newDirtY)] < 3: # Add dirt to this (x, y) space: dirtPiles[(newDirtX, newDirtY)] += 1 bext.goto(newDirtX, newDirtY) dirtPileLevel = dirtPiles[(newDirtX, newDirtY)] print(DIRT_CHARS[dirtPileLevel], end='') # The vbot has reached its destination, so find the # closest dirt pile: if len(moveTo) == 0: closestDirtDistance = None closestDirts = [] for dirtX in range(WIDTH): for dirtY in range(HEIGHT): if dirtPiles[(dirtX, dirtY)] == 0: continue # Skip clean spots. distance = getDistance(vbotX, vbotY, dirtX, dirtY) if (closestDirtDistance == None or distance < closestDirtDistance): closestDirtDistance = distance closestDirts = [(dirtX, dirtY)] elif distance == closestDirtDistance: closestDirts.append((dirtX, dirtY)) if closestDirtDistance != None: closestDirtX, closestDirtY = random.choice(closestDirts) moveTo = line(vbotX, vbotY, closestDirtX, closestDirtY) # Remove the first (x, y) returned from line() because # that is the vbot's current position. moveTo = moveTo[1:] # Determine if the vbot should head back to base to recharge: distanceToDirt = len(moveTo) if len(moveTo) > 0: lineToBase = line(moveTo[-1][0], moveTo[-1][0], baseX, baseY) # Subtract 1 because the first (x, y) returned from line() # is the vbot's current position. distanceFromDirtToBase = len(lineToBase) - 1 else: # There is no dirt to go to, so use 0: distanceFromDirtToBase = 0 if distanceToDirt + distanceFromDirtToBase > vbotBattery: # Make the vbot go towards the base station: moveTo = line(vbotX, vbotY, baseX, baseY) # Remove the first (x, y) returned from line() because # that is the vbot's current position. moveTo = moveTo[1:] vbotStatus = RETURNING # If the vbot is charging at the base station, make it stay # there until it is fully charged: if ((vbotX, vbotY) == (baseX, baseY) and vbotBattery < MAX_BATTERY): # Make the vbot stay where it is at the base station: moveTo = [] if len(moveTo) > 0: # Move the vbot towards its destination: vbotBattery -= 1 # Reduce the vbot's battery. # Erase the vbot from the screen and draw the dirt that # is at that space: bext.goto(vbotX, vbotY) print(DIRT_CHARS[dirtPiles[(vbotX, vbotY)]], end='') # Set new vbot position: vbotX, vbotY = moveTo[0] del moveTo[0] # Make the vbot suck up the dirt at its current location: dirtPiles[(vbotX, vbotY)] = 0 # Recharge the vbot if it's at the base station: if vbotX == baseX and vbotY == baseY: vbotStatus = CHARGING vbotBattery += RECHARGE_RATE if vbotBattery > MAX_BATTERY: vbotBattery = MAX_BATTERY # Display the vbot: bext.goto(vbotX, vbotY) print(VBOT, end='') # Display the base station: bext.goto(baseX, baseY) print(BASE, end='') # Display the batter indicator on the bottom row: bext.goto(0, HEIGHT) print('Press Ctrl-C to quit. ', end='') print(vbotStatus, end='') batteryPercentage = round(vbotBattery / MAX_BATTERY * 100, 1) print(' Battery:', str(batteryPercentage) + '% ', end='') sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE)
def main(): bext.clear() #generate some logos logos = [] for i in range(NUMBER_OF_LOGOS): logos.append({COLOR: random.choice(COLORS), X: random.randint(1, (WIDTH - 4)), Y: random.randint(1, HEIGHT - 1), DIR: random.choice(DIRECTIONS)}) if logos[-1][X] % 2 == 1: #make sure X is even so it can hit the corner logos[-1][X] -= 1 cornerBounces = 0 while True: for logo in logos: #erase the logo's current position bext.goto(logo[X], logo[Y]) print(' ', end='') original_direction = logo[DIR] #see if the logo bounces off the corners if logo[X] == 0 and logo[Y] == 0: logo[DIR] = DOWN_RIGHT cornerBounces += 1 elif logo[X] == 0 and logo[Y] == HEIGHT - 1: logo[DIR] = UP_RIGHT cornerBounces += 1 elif logo[X] == WIDTH - 3 and logo[Y] == 0: logo[DIR] == DOWN_LEFT cornerBounces += 1 elif logo[X] == WIDTH - 3 and logo[Y] == HEIGHT - 1: logo[DIR] == UP_LEFT cornerBounces += 1 # See if the logo bounces off the left edge: elif logo[X] == 0 and logo[DIR] == UP_LEFT: logo[DIR] = UP_RIGHT elif logo[X] == 0 and logo[DIR] == DOWN_LEFT: logo[DIR] = DOWN_RIGHT # See if the logo bounces off the right edge: # (WIDTH - 3 because 'DVD' has 3 letters.) elif logo[X] == WIDTH - 3 and logo[DIR] == UP_RIGHT: logo[DIR] = UP_LEFT elif logo[X] == WIDTH - 3 and logo[DIR] == DOWN_RIGHT: logo[DIR] = DOWN_LEFT # See if the logo bounces off the top edge: elif logo[Y] == 0 and logo[DIR] == UP_LEFT: logo[DIR] = DOWN_LEFT elif logo[Y] == 0 and logo[DIR] == UP_RIGHT: logo[DIR] = DOWN_RIGHT # See if the logo bounces off the bottom edge: elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_LEFT: logo[DIR] = UP_LEFT elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_RIGHT: logo[DIR] = UP_RIGHT if logo[DIR] != original_direction: # Change color when the logo bounces: logo[COLOR] = random.choice(COLORS) #move the logo. (X moves by 2 because the terminal #vharacers are twice as tall as they are wide) if logo[DIR] == UP_RIGHT: logo[X] += 2 logo[Y] -= 1 elif logo[DIR] == UP_LEFT: logo[X] -= 2 logo[Y] -= 1 elif logo[DIR] == DOWN_RIGHT: logo[X] += 2 logo[Y] += 1 elif logo[DIR] == DOWN_LEFT: logo[X] -= 2 logo[Y] += 1 #display the number of corner bounces bext.goto(5,0) bext.fg('white') print('Corner bounces:', cornerBounces, end='') for logo in logos: #draw the logos at their new location bext.goto(logo[X], logo[Y]) bext.fg(logo[COLOR]) print('DVD', end='') bext.goto(0,0) sys.stdout.flush() time.sleep(PAUSE_AMOUNT)
def main(): bext.fg('yellow') bext.clear() # Draw the quit message: bext.goto(0, 0) print('Ctrl-C to quit.', end='') # Draw the walls: for wall in ALL_WALLS: bext.goto(wall[X], wall[Y]) print(WALL, end='') while True: # Main program loop. allSand = list(INITIAL_SAND) random.shuffle(allSand) # Mix up the order that the grains of sand are simulated. # Draw the initial sand: for sand in allSand: bext.goto(sand[X], sand[Y]) print(SAND, end='') while True: # Keep looping until sand has run out. # Simulate all sand in the sandspace: #allSand.sort(key=lambda v: v[Y], reverse=True) # Sort from bottom sand up. random.shuffle(allSand) # Random order of grain simulation. sandMovedOnThisStep = False for i, sand in enumerate(allSand): if sand[Y] == HEIGHT - 1: continue # Sand is on the very bottom, so it won't move at all. # If nothing is under this sand, move it down: noSandBelow = (sand[X], sand[Y] + 1) not in allSand noWallBelow = (sand[X], sand[Y] + 1) not in ALL_WALLS canFallDown = noSandBelow and noWallBelow if canFallDown: allSand[i] = (sand[X], sand[Y] + 1) sandMovedOnThisStep = True bext.goto(sand[X], sand[Y]) print(' ', end='') bext.goto(sand[X], sand[Y] + 1) print(SAND, end='') else: # Check if the sand can fall to the left: noSandBelowLeft = (sand[X] - 1, sand[Y] + 1) not in allSand noWallBelowLeft = (sand[X] - 1, sand[Y] + 1) not in ALL_WALLS noWallToTheLeft = (sand[X] - 1, sand[Y]) not in ALL_WALLS notOnLeftEdge = sand[X] > 0 canFallLeft = noSandBelowLeft and noWallBelowLeft and noWallToTheLeft and notOnLeftEdge # Check if the sand can fall to the right: noSandBelowRight = (sand[X] + 1, sand[Y] + 1) not in allSand noWallBelowRight = (sand[X] + 1, sand[Y] + 1) not in ALL_WALLS noWallToTheRight = (sand[X] + 1, sand[Y]) not in ALL_WALLS notOnRightEdge = sand[X] < WIDTH - 1 canFallRight = noSandBelowRight and noWallBelowRight and noWallToTheRight and notOnRightEdge fallingDirection = None if canFallLeft and not canFallRight: fallingDirection = -1 elif not canFallLeft and canFallRight: fallingDirection = 1 elif canFallLeft and canFallRight: fallingDirection = random.choice((-1, 1)) # Check if the sand can "wide" fall two spaces to the left or right: if random.random() <= WIDE_FALL_CHANCE: noSandBelowTwoLeft = (sand[X] - 2, sand[Y] + 1) not in allSand noWallBelowTwoLeft = (sand[X] - 2, sand[Y] + 1) not in ALL_WALLS notOnSecondToLeftEdge = sand[X] > 1 canFallTwoLeft = canFallLeft and noSandBelowTwoLeft and noWallBelowTwoLeft and notOnSecondToLeftEdge noSandBelowTwoRight = (sand[X] + 2, sand[Y] + 1) not in allSand noWallBelowTwoRight = (sand[X] + 2, sand[Y] + 1) not in ALL_WALLS notOnSecondToRightEdge = sand[X] < WIDTH - 2 canFallTwoRight = canFallRight and noSandBelowTwoRight and noWallBelowTwoRight and notOnSecondToRightEdge if canFallTwoLeft and canFallTwoRight: fallingDirection = random.choice((-2, 2)) elif canFallTwoLeft and not canFallTwoRight: fallingDirection = -2 elif not canFallTwoLeft and canFallTwoRight: fallingDirection = 2 if fallingDirection == None: continue # This sand can't fall, so move on to the next grain of sand. # Move the grain of sand: allSand[i] = (sand[X] + fallingDirection, sand[Y] + 1) sandMovedOnThisStep = True bext.goto(sand[X], sand[Y]) # Move cursor to old sand location. print(' ', end='') # Erase old sand. bext.goto(sand[X] + fallingDirection, sand[Y] + 1) # Move cursor to new sand location. print(SAND, end='') # Draw new sand. sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_LENGTH) # Pause after this # If no sand has moved on this simulation step, reset the hourglass: if not sandMovedOnThisStep: time.sleep(2) # Erase the sand: for sand in allSand: bext.goto(sand[X], sand[Y]) print(' ', end='') break # Break out of main simultion loop to reset the hour glass.
def main(): bext.clear() # Generate some logos. logos = [] for i in range(NUMBER_OF_LOGOS): logos.append({ COLOR: random.choice(COLORS), X: random.randint(1, WIDTH - 4), Y: random.randint(1, HEIGHT - 4), DIR: random.choice(DIRECTIONS) }) if logos[-1][X] % 2 == 1: # Make sure X is even so it can hit the corner. logos[-1][X] -= 1 cornerBounces = 0 # Count how many times a logo hits a corner. while True: # Main program loop. for logo in logos: # Handle each logo in the logos list. # Erase the logo's current location: bext.goto(logo[X], logo[Y]) print(' ', end='') # (!) Try commenting this line out. originalDirection = logo[DIR] # See if the logo bounces off the corners: if logo[X] == 0 and logo[Y] == 0: logo[DIR] = DOWN_RIGHT cornerBounces += 1 elif logo[X] == 0 and logo[Y] == HEIGHT - 1: logo[DIR] = UP_RIGHT cornerBounces += 1 elif logo[X] == WIDTH - 3 and logo[Y] == 0: logo[DIR] = DOWN_LEFT cornerBounces += 1 elif logo[X] == WIDTH - 3 and logo[Y] == HEIGHT - 1: logo[DIR] = UP_LEFT cornerBounces += 1 # See if the logo bounces off the left edge: elif logo[X] == 0 and logo[DIR] == UP_LEFT: logo[DIR] = UP_RIGHT elif logo[X] == 0 and logo[DIR] == DOWN_LEFT: logo[DIR] = DOWN_RIGHT # See if the logo bounces off the right edge: # (WIDTH - 3 because 'DVD' has 3 letters.) elif logo[X] == WIDTH - 3 and logo[DIR] == UP_RIGHT: logo[DIR] = UP_LEFT elif logo[X] == WIDTH - 3 and logo[DIR] == DOWN_RIGHT: logo[DIR] = DOWN_LEFT # See if the logo bounces off the top edge: elif logo[Y] == 0 and logo[DIR] == UP_LEFT: logo[DIR] = DOWN_LEFT elif logo[Y] == 0 and logo[DIR] == UP_RIGHT: logo[DIR] = DOWN_RIGHT # See if the logo bounces off the bottom edge: elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_LEFT: logo[DIR] = UP_LEFT elif logo[Y] == HEIGHT - 1 and logo[DIR] == DOWN_RIGHT: logo[DIR] = UP_RIGHT if logo[DIR] != originalDirection: # Change color when the logo bounces: logo[COLOR] = random.choice(COLORS) # Move the logo. (X moves by 2 because the terminal # characters are twice as tall as they are wide.) if logo[DIR] == UP_RIGHT: logo[X] += 2 logo[Y] -= 1 elif logo[DIR] == UP_LEFT: logo[X] -= 2 logo[Y] -= 1 elif logo[DIR] == DOWN_RIGHT: logo[X] += 2 logo[Y] += 1 elif logo[DIR] == DOWN_LEFT: logo[X] -= 2 logo[Y] += 1 # Display number of corner bounces: bext.goto(5, 0) bext.fg('white') print('Corner bounces:', cornerBounces, end='') for logo in logos: # Draw the logos at their new location: bext.goto(logo[X], logo[Y]) bext.fg(logo[COLOR]) print('DVD', end='') bext.goto(0, 0) sys.stdout.flush() # (Required for bext-using programs.) time.sleep(PAUSE_AMOUNT)
def main(): bext.clear() #Draw the circle on the clock for y, row in enumerate(CLOCKFACE.splitlines()): for x, char in enumerate(row): if char != ' ': bext.goto(x, y) print(char) while True: #get current time from computer clock current_time = time.localtime() h = current_time.tm_hour % 12 #use 12 hour instead of 24 hour clock m = current_time.tm_min s = current_time.tm_sec #draw the second hand sec_hand_dir = COMPLETE_ARC * (s / 60) + OFFSET_90_DEGREES sec_hand_xpos = math.cos(sec_hand_dir) sec_hand_ypos = math.sin(sec_hand_dir) sec_hand_X = int(sec_hand_xpos * SECOND_HAND_LENGTH + CENTERX) sec_hand_Y = int(sec_hand_ypos * SECOND_HAND_LENGTH + CENTERY) sec_hand_points = line(CENTERX, CENTERY, sec_hand_X, sec_hand_Y) for x.y in sec_hand_points: bext.goto(x, y) print(SECOND_HAND_CHAR, end='') min_hand_dir = COMPLETE_ARC * (s / 60) + OFFSET_90_DEGREES min_hand_xpos = math.cos(min_hand_dir) min_hand_ypos = math.sin(min_hand_dir) min_hand_X = int(min_hand_xpos * MINUTE_HAND_LENGTH + CENTERX) min_hand_Y = int(min_hand_ypos * MINUTE_HAND_LENGTH + CENTERY) min_hand_points = line(CENTERX, CENTERY, min_hand_X, min_hand_Y) for x.y in min_hand_points: bext.goto(x, y) print(MINUTE_HAND_CHAR, end='') hour_hand_dir = COMPLETE_ARC * (s / 60) + OFFSET_90_DEGREES hour_hand_xpos = math.cos(hour_hand_dir) hour_hand_ypos = math.sin(hour_hand_dir) hour_hand_X = int(hour_hand_xpos * HOUR_HAND_LENGTH + CENTERX) hour_hand_Y = int(hour_hand_ypos * HOUR_HAND_LENGTH + CENTERY) hour_hand_points = line(CENTERX, CENTERY, hour_hand_X, hour_hand_Y) for x.y in hour_hand_points: bext.goto(x, y) print(HOUR_HAND_CHAR, end='') sys.stdout.flush() #required for bext using #keep logging until the second changes while True: time.sleep(0.1) if time.localtime().tm_sec != current_time.tm_sec: break #erase the clock hands for x, y in sec_hand_points: bext.goto(x, y) print(' ', end='') for x, y in min_hand_points: bext.goto(x, y) print(' ', end='') for x, y in hour_hand_points: bext.goto(x, y) print(' ', end='')
import sys, random, time try: import bext except ImportError: print("""This program requires the bext module, which you can install by opening a Terminal window (on macOS & Linux) and running: python3 -m pip install --user bext or a Command Prompt window (on Windows) and running: python -m pip install --user bext""") sys.exit() bext.clear() WIDTH, HEIGHT = bext.size() WIDTH -= 1 # Reduce width by 1 because of a weird Windows behavior. NUMBER_OF_POINTS = 4 COLORS = ('red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white') DIRECTIONS = ('upright', 'upleft', 'downright', 'downleft') LINE_CHAR = '#' def main(): # Generate some points. points = [] for i in range(NUMBER_OF_POINTS): points.append({ 'x': random.randint(1, WIDTH - 2), 'y': random.randint(1, HEIGHT - 2),
def main(): # Setup the screen: bext.fg('yellow') # Set foreground color. bext.bg('blue') # Set background color. 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(['N', 'S', 'E', 'W']) } ants.append(ant) # Keep running the simulation as long as we have ants: while len(ants) > 0: # Main program loop. # Draw the board data structure: bext.goto(0, 0) for y in range(board['height']): for x in range(board['width']): if board.get((x, y), False): print(chr(9608), end='') # Print a solid block. else: print(' ', end='') # Print an empty space. print() print('Press Ctrl-C to quit.') # Run a single simulation step for each ant: nextBoard = copy.copy(board) for ant in ants: if board.get((ant['x'], ant['y']), False) == True: nextBoard[(ant['x'], ant['y'])] = False # Turn clockwise: if ant['direction'] == 'N': ant['direction'] = 'E' elif ant['direction'] == 'E': ant['direction'] = 'S' elif ant['direction'] == 'S': ant['direction'] = 'W' elif ant['direction'] == 'W': ant['direction'] = 'N' else: nextBoard[(ant['x'], ant['y'])] = True # Turn counter clockwise: if ant['direction'] == 'N': ant['direction'] = 'W' elif ant['direction'] == 'W': ant['direction'] = 'S' elif ant['direction'] == 'S': ant['direction'] = 'E' elif ant['direction'] == 'E': ant['direction'] = 'N' # Move the ant forward: if ant['direction'] == 'N': ant['y'] -= 1 if ant['direction'] == 'S': ant['y'] += 1 if ant['direction'] == 'W': ant['x'] -= 1 if ant['direction'] == 'E': 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 - 1 ant['y'] = ant['y'] % HEIGHT - 1 board = nextBoard