|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +from Core.CMazeEnviroment import CMazeEnviroment, MazeActions |
| 4 | +import numpy as np |
| 5 | +import pygame |
| 6 | +import pygame.locals as G |
| 7 | +import random |
| 8 | + |
| 9 | +def createMaze(): |
| 10 | + sz = 64 |
| 11 | + maze = (0.8 < np.random.rand(sz, sz)).astype(np.float32) |
| 12 | + res = CMazeEnviroment( |
| 13 | + maze=maze, |
| 14 | + pos=(0, 0), |
| 15 | + FOV=3 |
| 16 | + ) |
| 17 | + res.respawn() |
| 18 | + return res |
| 19 | + |
| 20 | +class Colors: |
| 21 | + BLACK = (0, 0, 0) |
| 22 | + SILVER = (192, 192, 192) |
| 23 | + WHITE = (255, 255, 255) |
| 24 | + BLUE = (0, 0, 255) |
| 25 | + GREEN = (0, 255, 0) |
| 26 | + RED = (255, 0, 0) |
| 27 | + PURPLE = (255, 0, 255) |
| 28 | + |
| 29 | +class App: |
| 30 | + MODES = ['manual', 'random'] |
| 31 | + def __init__(self): |
| 32 | + self._running = True |
| 33 | + self._display_surf = None |
| 34 | + self._createMaze() |
| 35 | + self._mode = 'manual' |
| 36 | + self._paused = True |
| 37 | + self._speed = 20 |
| 38 | + |
| 39 | + def _createMaze(self): |
| 40 | + self._maze = createMaze() |
| 41 | + self._initMaze = self._maze.copy() |
| 42 | + return |
| 43 | + |
| 44 | + def on_init(self): |
| 45 | + pygame.init() |
| 46 | + |
| 47 | + self._display_surf = pygame.display.set_mode((800, 650), pygame.HWSURFACE) |
| 48 | + pygame.display.set_caption('Deep maze') |
| 49 | + self._font = pygame.font.Font(pygame.font.get_default_font(), 16) |
| 50 | + self._running = True |
| 51 | + |
| 52 | + def on_event(self, event): |
| 53 | + if event.type == G.QUIT: |
| 54 | + self._running = False |
| 55 | + |
| 56 | + if event.type == G.KEYDOWN: |
| 57 | + if G.K_m == event.key: |
| 58 | + mode = next((i for i, x in enumerate(self.MODES) if x == self._mode)) |
| 59 | + self._mode = self.MODES[(mode + 1) % len(self.MODES)] |
| 60 | + self._paused = True |
| 61 | + |
| 62 | + if G.K_SPACE == event.key: |
| 63 | + self._paused = not self._paused |
| 64 | + |
| 65 | + if G.K_ESCAPE == event.key: |
| 66 | + self._running = False |
| 67 | + |
| 68 | + if 'manual' == self._mode: |
| 69 | + if G.K_r == event.key: |
| 70 | + self._createMaze() |
| 71 | + |
| 72 | + if G.K_i == event.key: |
| 73 | + self._maze = self._initMaze.copy() |
| 74 | + |
| 75 | + if G.K_y == event.key: |
| 76 | + self._maze.respawn() |
| 77 | + |
| 78 | + actMapping = { |
| 79 | + G.K_LEFT: MazeActions.LEFT, |
| 80 | + G.K_RIGHT: MazeActions.RIGHT, |
| 81 | + G.K_UP: MazeActions.UP, |
| 82 | + G.K_DOWN: MazeActions.DOWN |
| 83 | + } |
| 84 | + |
| 85 | + act = actMapping.get(event.key, False) |
| 86 | + if act and self._maze.isPossible(act): |
| 87 | + self._maze.apply(act) |
| 88 | + ##### |
| 89 | + return |
| 90 | + |
| 91 | + def on_loop(self): |
| 92 | + if ('random' == self._mode) and not self._paused: |
| 93 | + for _ in range(self._speed): |
| 94 | + actions = self._maze.validActions() |
| 95 | + if actions: |
| 96 | + self._maze.apply(random.choice(actions)) |
| 97 | + pass |
| 98 | + |
| 99 | + def _renderMaze(self): |
| 100 | + fog = self._maze.fog |
| 101 | + maze = self._maze.maze |
| 102 | + h, w = maze.shape |
| 103 | + dx, dy = delta = np.array([640, 640]) / np.array([w, h]) |
| 104 | + for ix in range(w): |
| 105 | + for iy in range(h): |
| 106 | + isDiscovered = 0 < fog[ix, iy] |
| 107 | + isWall = 0 < maze[ix, iy] |
| 108 | + y, x = delta * np.array([ix, iy]) |
| 109 | + |
| 110 | + clr = Colors.PURPLE if isWall else Colors.WHITE |
| 111 | + if not isDiscovered: |
| 112 | + clr = np.array(clr) * .3 |
| 113 | + pygame.draw.rect(self._display_surf, clr, [x, y, dx - 1, dy - 1], 0) |
| 114 | + # current pos |
| 115 | + x, y = delta * self._maze.pos |
| 116 | + pygame.draw.rect(self._display_surf, Colors.RED, [x, y, dx - 1, dy - 1], 0) |
| 117 | + return |
| 118 | + |
| 119 | + def _renderInfo(self): |
| 120 | + self._display_surf.blit( |
| 121 | + self._font.render( |
| 122 | + 'Score: %.2f' % (self._maze.score), |
| 123 | + False, Colors.BLUE |
| 124 | + ), (655, 15) |
| 125 | + ) |
| 126 | + |
| 127 | + self._display_surf.blit( |
| 128 | + self._font.render( |
| 129 | + 'Mode: %s' % (self._mode), |
| 130 | + False, Colors.BLUE |
| 131 | + ), (655, 35) |
| 132 | + ) |
| 133 | + return |
| 134 | + |
| 135 | + def on_render(self): |
| 136 | + self._display_surf.fill(Colors.SILVER) |
| 137 | + self._renderMaze() |
| 138 | + self._renderInfo() |
| 139 | + pygame.display.flip() |
| 140 | + |
| 141 | + def run(self): |
| 142 | + if self.on_init() == False: |
| 143 | + self._running = False |
| 144 | + |
| 145 | + while self._running: |
| 146 | + for event in pygame.event.get(): |
| 147 | + self.on_event(event) |
| 148 | + |
| 149 | + self.on_loop() |
| 150 | + self.on_render() |
| 151 | + |
| 152 | + pygame.quit() |
| 153 | + |
| 154 | +def main(): |
| 155 | + app = App() |
| 156 | + app.run() |
| 157 | + pass |
| 158 | + |
| 159 | +if __name__ == '__main__': |
| 160 | + main() |
0 commit comments