Toggle Navigation
Hatchery
Eggs
maze
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
# 1.00 - Initial version # 1.01 - Fixed maze start cell # 1.02 - Added 'dust' to show difference between visited and unvisited trails. # 1.03 - Added settings support # 1.04 - Added animation # 1.05 - Small fix to active cell selection # # Description: # Find your way to the exit of the maze. # Longer lingering lowers your score, but eating fruits on your path # adds to score. Wander carefully. Success! # # Usage: # Use buttons at the side of to move from cell to cell until you find # the exit. Orange cells are fruits. Red cell your starting point and # a green cell the exit. # # Button: # Mid top buttons - move north # Mid left buttons - move west # Mid right buttons - move east # Mid bottom buttons - move south # # Touch pad: # Left / Right - select maze # import display, keypad, touchpads, appconfig, virtualtimers KEY_MOVE_NORTH_0 = 1 KEY_MOVE_NORTH_1 = 2 KEY_MOVE_SOUTH_0 = 13 KEY_MOVE_SOUTH_1 = 14 KEY_MOVE_EAST_0 = 7 KEY_MOVE_EAST_1 = 11 KEY_MOVE_WEST_0 = 4 KEY_MOVE_WEST_1 = 8 DEF_MAZE = [[0x4A, 0x4C, 0x1C, 0x4C, 0x49, 0x86, 0x4C, 0x48, 0x49, 0x47, 0x4A, 0x49, 0x43, 0x46, 0x89, 0x43, 0x46, 0x44, 0x4D, 0x43, 0x46, 0x4D, 0x2E, 0x4C, 0x45], [0x4E, 0x4C, 0x48, 0x49, 0x4B, 0x4A, 0x48, 0xCC, 0x4C, 0x4C, 0x49, 0x4A, 0x4C, 0x49, 0x4A, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0xCA, 0xCC, 0x48, 0x4C, 0x4C, 0x49, 0x4E, 0x40, 0x69, 0x4A, 0x4C, 0x45, 0x43, 0x46, 0x45, 0x46, 0x4C, 0x4C, 0x49, 0x43, 0x46, 0x49, 0x43, 0x43, 0x4A, 0x4C, 0x4C, 0xCC, 0xCC, 0xCC, 0x45, 0x4B, 0x43, 0x4C, 0x4C, 0x44, 0x49, 0x47, 0x43, 0x43, 0xCB, 0xCA, 0x45, 0x4A, 0x4C, 0x4C, 0x4C, 0x49, 0x43, 0x46, 0x4C, 0x45, 0x43, 0x43, 0x46, 0x4C, 0x48, 0x4C, 0x4C, 0x4C, 0x49, 0x43, 0x46, 0x4C, 0x49, 0x4B, 0x46, 0xCC, 0x41, 0x43, 0x46, 0x41, 0x4A, 0x45, 0x4A, 0x4C, 0x49, 0x46, 0x45, 0x4A, 0x49, 0x4A, 0x45, 0x46, 0x4C, 0x4C, 0x45, 0x4A, 0x49, 0x4A, 0x45, 0x42, 0x49, 0x4A, 0x45, 0x42, 0x4C, 0xC9, 0x43, 0x42, 0x49, 0x43, 0x43, 0x4E, 0x41, 0x4A, 0x44, 0x4C, 0x49, 0x43, 0x46, 0x45, 0xCE, 0x48, 0x4C, 0x4C, 0x4C, 0x45, 0x43, 0x46, 0x48, 0x45, 0x47, 0x46, 0x49, 0x43, 0x4E, 0x41, 0x43, 0x47, 0x43, 0x43, 0x46, 0x49, 0x43, 0x46, 0x4C, 0x49, 0x47, 0xC3, 0x4E, 0x48, 0x4C, 0x45, 0x4B, 0x4A, 0x49, 0x4A, 0x45, 0x4A, 0x45, 0x4A, 0x4C, 0x49, 0x43, 0x46, 0x49, 0x43, 0x43, 0x4A, 0x45, 0x46, 0x4C, 0x45, 0x43, 0x4E, 0x49, 0x46, 0x4C, 0x44, 0x4C, 0x45, 0x4A, 0x49, 0x42, 0x45, 0x46, 0x45, 0x4A, 0x45, 0x4A, 0x45, 0x4E, 0x44, 0x45, 0x4A, 0x45, 0x47, 0x43, 0x43, 0x4A, 0x4C, 0x4C, 0x49, 0x46, 0x4C, 0x41, 0x4E, 0x49, 0x4A, 0x4C, 0x49, 0x47, 0x42, 0x45, 0x4A, 0x4C, 0x49, 0x43, 0x4B, 0x46, 0x4C, 0xCC, 0xC8, 0x49, 0xC6, 0x48, 0x49, 0x43, 0x42, 0x45, 0x4A, 0x49, 0x46, 0x4E, 0x49, 0x42, 0x4C, 0x45, 0x46, 0x49, 0x46, 0x49, 0x43, 0x4E, 0x44, 0x49, 0x47, 0x43, 0x42, 0x49, 0x4A, 0x49, 0x47, 0x46, 0x49, 0x43, 0x43, 0x43, 0x46, 0x49, 0x47, 0x43, 0x46, 0x49, 0x46, 0x45, 0x4A, 0x4C, 0x4C, 0x44, 0x4D, 0x43, 0x46, 0x49, 0x4A, 0x45, 0x4A, 0x44, 0x45, 0x47, 0x43, 0x46, 0x4C, 0x4C, 0x45, 0x47, 0x42, 0x45, 0x4B, 0x46, 0x49, 0x42, 0xC6, 0x46, 0x4C, 0xCC, 0x45, 0x4B, 0xCA, 0x4C, 0x4C, 0x45, 0x4E, 0x41, 0x46, 0x4C, 0x44, 0x49, 0x4A, 0x4C, 0x41, 0x4A, 0x4C, 0x49, 0x4A, 0x49, 0x46, 0x4D, 0x46, 0x48, 0x45, 0x47, 0x4C, 0x4C, 0x4C, 0x4C, 0x48, 0x41, 0x43, 0x4A, 0x4C, 0x4C, 0x49, 0x43, 0x4A, 0x4C, 0x49, 0x43, 0x43, 0x4E, 0x45, 0x43, 0xCB, 0x46, 0x45, 0x43, 0x4A, 0x49, 0x4B, 0x43, 0x4A, 0x4C, 0x4C, 0x4C, 0x49, 0x4A, 0x41, 0x47, 0x46, 0x45, 0x4A, 0x4C, 0x45, 0x43, 0x46, 0x49, 0x43, 0x47, 0x46, 0x4C, 0x49, 0x46, 0x40, 0x4C, 0xCD, 0x46, 0xC5, 0x43, 0x43, 0x46, 0x45, 0x4A, 0x49, 0x49, 0x46, 0x45, 0x43, 0x4A, 0x4C, 0x4C, 0x45, 0x4B, 0x4A, 0x45, 0x4A, 0x45, 0x46, 0x49, 0x4A, 0x49, 0x42, 0x4D, 0x43, 0x4A, 0x49, 0x4A, 0x49, 0x43, 0x43, 0x4B, 0x4A, 0x44, 0x46, 0x47, 0x4A, 0x4C, 0x45, 0x46, 0x4C, 0x4C, 0x49, 0x46, 0x44, 0xCC, 0x45, 0x4A, 0x49, 0x43, 0x43, 0x46, 0x45, 0x4A, 0x45, 0x43, 0x46, 0x45, 0x46, 0x41, 0x43, 0x43, 0x42, 0x4D, 0x46, 0x48, 0x45, 0x4E, 0x49, 0x4A, 0x48, 0x4D, 0x46, 0x4C, 0x49, 0xCB, 0x4A, 0x45, 0x43, 0x43, 0x42, 0x4C, 0x49, 0x46, 0xC9, 0x43, 0x4B, 0x4A, 0x4C, 0x45, 0x43, 0x43, 0x43, 0x4A, 0x49, 0x46, 0x4C, 0x49, 0x46, 0x45, 0x46, 0x48, 0x4C, 0x49, 0x43, 0x46, 0x41, 0x4B, 0x43, 0x43, 0x42, 0x4D, 0x46, 0x4C, 0x41, 0x43, 0x43, 0x46, 0x49, 0x4B, 0x43, 0x46, 0x41, 0x43, 0x46, 0x4C, 0x49, 0x43, 0x4A, 0x4C, 0x49, 0x43, 0x4E, 0x45, 0x42, 0x49, 0x46, 0x45, 0x42, 0x45, 0x43, 0x4A, 0x4C, 0x49, 0x47, 0x43, 0x42, 0x49, 0x43, 0x43, 0x46, 0x49, 0x47, 0x46, 0x49, 0x4B, 0x43, 0x46, 0x45, 0x4E, 0x44, 0x45, 0x4A, 0x49, 0x47, 0x46, 0x4C, 0x49, 0x43, 0x4E, 0x45, 0x43, 0x4B, 0x46, 0x49, 0x43, 0x43, 0x47, 0x43, 0x43, 0x5E, 0x44, 0x4C, 0x4C, 0xC5, 0x46, 0x44, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x45, 0x46, 0x4C, 0x4C, 0x4C, 0x45, 0x46, 0x4C, 0x4C, 0x45, 0x46, 0x4C, 0x44, 0x45, 0x46, 0x4C, 0x44, 0x45], [0x4A, 0x4C, 0x1C, 0x4C, 0x49, 0x86, 0x4C, 0x48, 0x49, 0x47, 0x4A, 0x49, 0x43, 0x46, 0x89, 0x43, 0x46, 0x44, 0x4D, 0x43, 0x46, 0x4D, 0x2E, 0x4C, 0x45]] DEF_MAX_X = [ 5,30, 5] DEF_MAX_Y = [ 5,20, 5] DEF_INI_X = [ 2, 0, 2] DEF_INI_Y = [ 0,19, 0] settings = appconfig.get('maze', {'colours': {'empty' : '000000', 'wall' : '0000FF', 'entry' : 'FF0000', 'exit' : '00FF00', 'dust' : '138535', 'fruit' : 'FFC000'}, 'animationrate': 500}) g_colours = {} g_animation_even = False g_animation_rate = settings['animationrate'] g_maze = [] g_maze_cell = 0 g_maze_index = 0 g_maze_max_x = 5 g_maze_max_y = 5 g_player_pos_x = 2 g_player_pos_y = 0 g_player_score = 0 g_player_steps = 0 def init_app(): global g_colours print('Initializing App Maze') for key, colour in settings['colours'].items(): g_colours[key] = int(colour, 16) def init_maze(): global g_maze, g_maze_cell global g_maze_max_x, g_maze_max_y global g_player_pos_x, g_player_pos_y global g_player_score, g_player_steps print('Initializing Maze %s' % (g_maze_index + 1)) g_maze_max_x = DEF_MAX_X[g_maze_index] g_maze_max_y = DEF_MAX_Y[g_maze_index] g_player_pos_x = DEF_INI_X[g_maze_index] g_player_pos_y = DEF_INI_Y[g_maze_index] g_player_score = 0 g_player_steps = 0 g_maze = [] for idx in range(0,len(DEF_MAZE[g_maze_index])): g_maze.append(DEF_MAZE[g_maze_index][idx]) g_maze_cell = g_maze[g_maze_max_x * g_player_pos_y + g_player_pos_x] def update_maze(x, y): global g_maze, g_maze_cell, g_player_steps, g_player_score g_player_steps = g_player_steps + 1 g_maze_cell = g_maze[g_maze_max_x * y + x] if g_maze_cell & 0x40: #Dust g_maze[g_maze_max_x * y + x] = g_maze_cell & ~0x40 if g_maze_cell & 0x80: #Fruit! :P g_maze[g_maze_max_x * y + x] = g_maze_cell & ~0x80 g_player_score = g_player_score + 10 if g_maze_cell & 0x20: #Exit g_player_score = g_player_score + (100 - g_player_steps) print("(%s,%s) step: %s score: %s" % (g_player_pos_x, g_player_pos_y, g_player_steps, g_player_score)) def refresh_display(x, y): global g_maze_cell g_maze_cell = g_maze[g_maze_max_x * y + x] for idx in range(0,16): display.drawPixel(idx % 4, idx // 4, g_colours['empty']) if g_maze_cell & 0x40: #Dust for idx in [5,6,9,10]: display.drawPixel(idx % 4, idx // 4, g_colours['dust']) if g_maze_cell & 0x08: #North display.drawPixel(0, 0, g_colours['wall']) display.drawPixel(1, 0, g_colours['wall']) display.drawPixel(2, 0, g_colours['wall']) display.drawPixel(3, 0, g_colours['wall']) if g_maze_cell & 0x04: #South display.drawPixel(0, 3, g_colours['wall']) display.drawPixel(1, 3, g_colours['wall']) display.drawPixel(2, 3, g_colours['wall']) display.drawPixel(3, 3, g_colours['wall']) if g_maze_cell & 0x02: #West display.drawPixel(0, 0, g_colours['wall']) display.drawPixel(0, 1, g_colours['wall']) display.drawPixel(0, 2, g_colours['wall']) display.drawPixel(0, 3, g_colours['wall']) if g_maze_cell & 0x01: #East display.drawPixel(3, 0, g_colours['wall']) display.drawPixel(3, 1, g_colours['wall']) display.drawPixel(3, 2, g_colours['wall']) display.drawPixel(3, 3, g_colours['wall']) display.flush() def animate(): global g_animation_even g_animation_even = not g_animation_even animation = False colour = 0x000000 if g_maze_cell & 0x80: #Fruit! animation = True colour = g_colours['fruit'] elif g_maze_cell & 0x20: #Exit animation = True colour = g_colours['exit'] elif g_maze_cell & 0x10: #Entry animation = True colour = g_colours['entry'] if animation: if g_animation_even: for idx in [5,10]: display.drawPixel(idx % 4, idx // 4, colour) for idx in [6,9]: display.drawPixel(idx % 4, idx // 4, g_colours['empty']) else: for idx in [5,10]: display.drawPixel(idx % 4, idx // 4, g_colours['empty']) for idx in [6,9]: display.drawPixel(idx % 4, idx // 4, colour) display.flush() return g_animation_rate def on_key(index, pressed): global g_player_pos_x, g_player_pos_y if pressed: if (index == KEY_MOVE_NORTH_0 or index == KEY_MOVE_NORTH_1) and not (g_maze_cell & 0x08): if g_player_pos_y > 0: g_player_pos_y = g_player_pos_y - 1 elif (index == KEY_MOVE_SOUTH_0 or index == KEY_MOVE_SOUTH_1) and not (g_maze_cell & 0x04): if g_player_pos_y < g_maze_max_y: g_player_pos_y = g_player_pos_y + 1 elif (index == KEY_MOVE_WEST_0 or index == KEY_MOVE_WEST_1) and not (g_maze_cell & 0x02): if g_player_pos_x > 0: g_player_pos_x = g_player_pos_x - 1 elif (index == KEY_MOVE_EAST_0 or index == KEY_MOVE_EAST_1) and not (g_maze_cell & 0x01): if g_player_pos_x < g_maze_max_x: g_player_pos_x = g_player_pos_x + 1 refresh_display(g_player_pos_x, g_player_pos_y) update_maze(g_player_pos_x, g_player_pos_y) def on_touch_left(pressed): global g_maze_index if pressed and g_maze_index > 0: g_maze_index = g_maze_index - 1 init_maze() refresh_display(g_player_pos_x, g_player_pos_y) def on_touch_right(pressed): global g_maze_index if pressed and g_maze_index < 1: g_maze_index = g_maze_index + 1 init_maze() refresh_display(g_player_pos_x, g_player_pos_y) # Initialize application init_app() init_maze() refresh_display(g_player_pos_x, g_player_pos_y) # Start animation timers virtualtimers.begin(50) virtualtimers.new(0, animate, False) # Add key and touchpad handlers touchpads.on(touchpads.LEFT, on_touch_left) touchpads.on(touchpads.RIGHT, on_touch_right) keypad.add_handler(on_key)