Module pacai.ui.view
Expand source code
import abc
import os
from PIL import ImageFont
from pacai.ui import spritesheet
DEFAULT_GIF_FPS = 10
MIN_GIF_FPS = 1
DEFAULT_SKIP_FRAMES = 4
# By default, the sprite sheet is adjacent to this file.
DEFAULT_SPRITES = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pacman-sprites.png')
THIS_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)))
FONT_PATH = os.path.join(THIS_DIR, 'fonts', 'roboto', 'RobotoMono-Regular.ttf')
class AbstractView(abc.ABC):
"""
A abstarct view that represents all the necessary functionality a specific
view should implement.
The ability to produce a gif is inherent to all views,
even if they do not produce graphics at runtime.
"""
def __init__(self, spritesPath = DEFAULT_SPRITES,
gifPath = None, gifFPS = DEFAULT_GIF_FPS, skipFrames = DEFAULT_SKIP_FRAMES):
self._spritesPath = spritesPath
self._gifPath = gifPath
self._gifFPS = max(MIN_GIF_FPS, int(gifFPS))
self._saveFrames = (self._gifPath is not None)
self._skipFrames = max(1, int(skipFrames))
self._keyFrames = []
# The number of frames this view has produced.
self._frameCount = 0
# The number of turns this view has produced.
# (Tracked by the number of times agent 0 has been animated.)
self._turnCount = 0
self._sprites = spritesheet.loadSpriteSheet(spritesPath)
self._font = ImageFont.truetype(FONT_PATH, spritesheet.SQUARE_SIZE - 14)
def finish(self):
"""
Signal that the game is over and the UI should cleanup.
"""
# Save the gif.
if (self._saveFrames and len(self._keyFrames) > 0):
gifTimePerFrameMS = int(1.0 / self._gifFPS * 1000.0)
images = [frame.toImage(self._sprites, self._font) for frame in self._keyFrames]
images[0].save(self._gifPath, save_all = True, append_images = images,
duration = gifTimePerFrameMS, loop = 0, optimize = False)
def getKeyboard(self):
"""
For views that support keyboards, get an instance of a pacai.ui.keyboard.Keyboard.
"""
raise NotImplementedError("This view does not support keyboards.")
def initialize(self, state):
"""
Perform an initial drawing of the view.
"""
pass
def update(self, state, forceDraw = False):
"""
Materialize the view, given a state.
"""
if (state.isOver()):
forceDraw = True
frame = self._createFrame(state)
if (frame is not None and self._saveFrames
and (state.isOver() or (self._frameCount % self._skipFrames == 0))):
self._keyFrames.append(frame)
self._drawFrame(state, frame, forceDraw = forceDraw)
self._frameCount += 1
if (state.getLastAgentMoved() == 0):
self._turnCount += 1
@abc.abstractmethod
def _createFrame(self, state):
"""
Create the frame using the given state.
Children can decide on the correct concrete representation of a frame.
"""
pass
@abc.abstractmethod
def _drawFrame(self, state, frame, forceDraw = False):
"""
The real work for each view implementation.
From a frame, output to whatever medium this view utilizes.
"""
pass
Classes
class AbstractView (spritesPath='/home/eriq/code/pacman/pacai/ui/pacman-sprites.png', gifPath=None, gifFPS=10, skipFrames=4)
-
A abstarct view that represents all the necessary functionality a specific view should implement. The ability to produce a gif is inherent to all views, even if they do not produce graphics at runtime.
Expand source code
class AbstractView(abc.ABC): """ A abstarct view that represents all the necessary functionality a specific view should implement. The ability to produce a gif is inherent to all views, even if they do not produce graphics at runtime. """ def __init__(self, spritesPath = DEFAULT_SPRITES, gifPath = None, gifFPS = DEFAULT_GIF_FPS, skipFrames = DEFAULT_SKIP_FRAMES): self._spritesPath = spritesPath self._gifPath = gifPath self._gifFPS = max(MIN_GIF_FPS, int(gifFPS)) self._saveFrames = (self._gifPath is not None) self._skipFrames = max(1, int(skipFrames)) self._keyFrames = [] # The number of frames this view has produced. self._frameCount = 0 # The number of turns this view has produced. # (Tracked by the number of times agent 0 has been animated.) self._turnCount = 0 self._sprites = spritesheet.loadSpriteSheet(spritesPath) self._font = ImageFont.truetype(FONT_PATH, spritesheet.SQUARE_SIZE - 14) def finish(self): """ Signal that the game is over and the UI should cleanup. """ # Save the gif. if (self._saveFrames and len(self._keyFrames) > 0): gifTimePerFrameMS = int(1.0 / self._gifFPS * 1000.0) images = [frame.toImage(self._sprites, self._font) for frame in self._keyFrames] images[0].save(self._gifPath, save_all = True, append_images = images, duration = gifTimePerFrameMS, loop = 0, optimize = False) def getKeyboard(self): """ For views that support keyboards, get an instance of a pacai.ui.keyboard.Keyboard. """ raise NotImplementedError("This view does not support keyboards.") def initialize(self, state): """ Perform an initial drawing of the view. """ pass def update(self, state, forceDraw = False): """ Materialize the view, given a state. """ if (state.isOver()): forceDraw = True frame = self._createFrame(state) if (frame is not None and self._saveFrames and (state.isOver() or (self._frameCount % self._skipFrames == 0))): self._keyFrames.append(frame) self._drawFrame(state, frame, forceDraw = forceDraw) self._frameCount += 1 if (state.getLastAgentMoved() == 0): self._turnCount += 1 @abc.abstractmethod def _createFrame(self, state): """ Create the frame using the given state. Children can decide on the correct concrete representation of a frame. """ pass @abc.abstractmethod def _drawFrame(self, state, frame, forceDraw = False): """ The real work for each view implementation. From a frame, output to whatever medium this view utilizes. """ pass
Ancestors
- abc.ABC
Subclasses
Methods
def finish(self)
-
Signal that the game is over and the UI should cleanup.
Expand source code
def finish(self): """ Signal that the game is over and the UI should cleanup. """ # Save the gif. if (self._saveFrames and len(self._keyFrames) > 0): gifTimePerFrameMS = int(1.0 / self._gifFPS * 1000.0) images = [frame.toImage(self._sprites, self._font) for frame in self._keyFrames] images[0].save(self._gifPath, save_all = True, append_images = images, duration = gifTimePerFrameMS, loop = 0, optimize = False)
def getKeyboard(self)
-
For views that support keyboards, get an instance of a pacai.ui.keyboard.Keyboard.
Expand source code
def getKeyboard(self): """ For views that support keyboards, get an instance of a pacai.ui.keyboard.Keyboard. """ raise NotImplementedError("This view does not support keyboards.")
def initialize(self, state)
-
Perform an initial drawing of the view.
Expand source code
def initialize(self, state): """ Perform an initial drawing of the view. """ pass
def update(self, state, forceDraw=False)
-
Materialize the view, given a state.
Expand source code
def update(self, state, forceDraw = False): """ Materialize the view, given a state. """ if (state.isOver()): forceDraw = True frame = self._createFrame(state) if (frame is not None and self._saveFrames and (state.isOver() or (self._frameCount % self._skipFrames == 0))): self._keyFrames.append(frame) self._drawFrame(state, frame, forceDraw = forceDraw) self._frameCount += 1 if (state.getLastAgentMoved() == 0): self._turnCount += 1