Skip to content

Commit

Permalink
basic UI
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenWizard2015 committed Aug 24, 2020
1 parent 00fd8ad commit 4389744
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 12 deletions.
56 changes: 44 additions & 12 deletions Core/CMazeEnviroment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from enum import Enum
import numpy as np
import random

class MazeActions(Enum):
LEFT = (-1, 0)
Expand All @@ -9,44 +10,75 @@ class MazeActions(Enum):

class CMazeEnviroment:
def __init__(self, maze, pos, FOV):
self._maze = np.pad(np.array(maze), FOV, constant_values=(1,))
self._pos = np.array(pos) + FOV
self.maze = np.pad(np.array(maze), FOV, constant_values=(1,))
self._fov = FOV

self._fog = np.zeros_like(self._maze)
x, y = np.array(pos) + FOV
self.spawnAt(x, y)
return

def spawnAt(self, x, y):
self.pos = np.array([y, x])
self.fog = np.zeros_like(self.maze)
self._updateFog()
return

def respawn(self):
w, h = self.maze.shape
while True:
x = random.randint(0, w - 1)
y = random.randint(0, h - 1)
if self.maze[x, y] <= 0:
self.spawnAt(x, y)
break
return

def _updateFog(self):
y, x = self._pos
self._fog[
y, x = self.pos
self.fog[
x - self._fov:x + self._fov + 1,
y - self._fov:y + self._fov + 1
] = 1
return

def apply(self, action):
self._pos += action.value
self.pos += action.value
self._updateFog()
return

def vision(self):
y, x = self._pos
return self._maze[
y, x = self.pos
return self.maze[
x - self._fov:x + self._fov + 1,
y - self._fov:y + self._fov + 1
]

@property
def state(self):
return ((self.vision(), self._fog, ), self.score, self.done)
return ((self.vision(), self.fog, ), self.score, self.done)

@property
def done(self):
y, x = self._pos
return 1 < self._maze[x, y]
return 1 < self.maze[x, y]

@property
def score(self):
h, w = self._fog.shape
h, w = self.fog.shape
total = h * w
return np.count_nonzero(self._fog) / total
return np.count_nonzero(self.fog) / total

def copy(self):
# dirty copy
res = CMazeEnviroment(self.maze, self.pos, self._fov)
res.maze = self.maze.copy()
res.fog = self.fog.copy()
res.pos = self.pos.copy()
return res

def isPossible(self, action):
y, x = self.pos + action.value
return self.maze[x, y] <= 0

def validActions(self):
return [ act for act in MazeActions if self.isPossible(act) ]
160 changes: 160 additions & 0 deletions view_maze.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Core.CMazeEnviroment import CMazeEnviroment, MazeActions
import numpy as np
import pygame
import pygame.locals as G
import random

def createMaze():
sz = 64
maze = (0.8 < np.random.rand(sz, sz)).astype(np.float32)
res = CMazeEnviroment(
maze=maze,
pos=(0, 0),
FOV=3
)
res.respawn()
return res

class Colors:
BLACK = (0, 0, 0)
SILVER = (192, 192, 192)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)

class App:
MODES = ['manual', 'random']
def __init__(self):
self._running = True
self._display_surf = None
self._createMaze()
self._mode = 'manual'
self._paused = True
self._speed = 20

def _createMaze(self):
self._maze = createMaze()
self._initMaze = self._maze.copy()
return

def on_init(self):
pygame.init()

self._display_surf = pygame.display.set_mode((800, 650), pygame.HWSURFACE)
pygame.display.set_caption('Deep maze')
self._font = pygame.font.Font(pygame.font.get_default_font(), 16)
self._running = True

def on_event(self, event):
if event.type == G.QUIT:
self._running = False

if event.type == G.KEYDOWN:
if G.K_m == event.key:
mode = next((i for i, x in enumerate(self.MODES) if x == self._mode))
self._mode = self.MODES[(mode + 1) % len(self.MODES)]
self._paused = True

if G.K_SPACE == event.key:
self._paused = not self._paused

if G.K_ESCAPE == event.key:
self._running = False

if 'manual' == self._mode:
if G.K_r == event.key:
self._createMaze()

if G.K_i == event.key:
self._maze = self._initMaze.copy()

if G.K_y == event.key:
self._maze.respawn()

actMapping = {
G.K_LEFT: MazeActions.LEFT,
G.K_RIGHT: MazeActions.RIGHT,
G.K_UP: MazeActions.UP,
G.K_DOWN: MazeActions.DOWN
}

act = actMapping.get(event.key, False)
if act and self._maze.isPossible(act):
self._maze.apply(act)
#####
return

def on_loop(self):
if ('random' == self._mode) and not self._paused:
for _ in range(self._speed):
actions = self._maze.validActions()
if actions:
self._maze.apply(random.choice(actions))
pass

def _renderMaze(self):
fog = self._maze.fog
maze = self._maze.maze
h, w = maze.shape
dx, dy = delta = np.array([640, 640]) / np.array([w, h])
for ix in range(w):
for iy in range(h):
isDiscovered = 0 < fog[ix, iy]
isWall = 0 < maze[ix, iy]
y, x = delta * np.array([ix, iy])

clr = Colors.PURPLE if isWall else Colors.WHITE
if not isDiscovered:
clr = np.array(clr) * .3
pygame.draw.rect(self._display_surf, clr, [x, y, dx - 1, dy - 1], 0)
# current pos
x, y = delta * self._maze.pos
pygame.draw.rect(self._display_surf, Colors.RED, [x, y, dx - 1, dy - 1], 0)
return

def _renderInfo(self):
self._display_surf.blit(
self._font.render(
'Score: %.2f' % (self._maze.score),
False, Colors.BLUE
), (655, 15)
)

self._display_surf.blit(
self._font.render(
'Mode: %s' % (self._mode),
False, Colors.BLUE
), (655, 35)
)
return

def on_render(self):
self._display_surf.fill(Colors.SILVER)
self._renderMaze()
self._renderInfo()
pygame.display.flip()

def run(self):
if self.on_init() == False:
self._running = False

while self._running:
for event in pygame.event.get():
self.on_event(event)

self.on_loop()
self.on_render()

pygame.quit()

def main():
app = App()
app.run()
pass

if __name__ == '__main__':
main()

0 comments on commit 4389744

Please sign in to comment.