class Game(object): def __init__(self, inputMap=None): if inputMap is not None: self.inputMap = inputMap.rstrip() self.field = None self.lives = 3 self.score = 0 self.pacman = None self.ghosts = [] self.pills = [] self.walls = [] self.gameOver = False self.controller = None self.gate = None self.level = 1 self.lastLevel = 1 self.levelMaps = None self.animation = False def play(self, debug): self.parse() while (self.gameOver is False): self.tick() self.render() self.refresh() sleep(0.1) if (self.pacman.alive is False): self.pacman.restart() if (debug is True): self.gameOver = True def parse(self): if self.levelMaps: self.inputMap = self.levelMaps.getLevel(self.level) else: if "SEPARATOR" in self.inputMap: self.levelMaps = LevelMaps(self.inputMap) self.lastLevel = self.levelMaps.maxLevel() self.inputMap = self.levelMaps.getLevel(self.level) columns = self.inputMap.index("\n") self.parseStatus(self.inputMap[:columns]) screenRows = self.inputMap[columns + 1:].split('\n') rows = len(screenRows) self.field = GameField(columns, rows) self.parseField(screenRows) def parseStatus(self, statusLine): elements = statusLine.split() try: self.lives = int(elements[0]) self.score = int(elements[1]) except ValueError: pass def parseField(self, screenRows): for y in range(self.field.height()): for x in range(self.field.width()): if Pacman.isPacman(screenRows[y][x]): self.pacman = Pacman(self, (x, y), screenRows[y][x]) self.pacman.useAnimation(self.animation) self.field.add((x, y), self.pacman) if Wall.isWall(screenRows[y][x]): wall = Wall((x, y), screenRows[y][x]) self.walls.append(wall) self.field.add((x, y), wall) if Wall.isGate(screenRows[y][x]): self.gate = wall if Pill.isPill(screenRows[y][x]): pill = Pill((x, y), screenRows[y][x]) self.pills.append(pill) self.field.add((x, y), pill) if Ghost.isGhost(screenRows[y][x]): ghost = Ghost(self, (x, y), screenRows[y][x]) self.ghosts.append(ghost) self.field.add((x, y), ghost) def setGameField(self, width, height): self.field = GameField(width, height) def setPacman(self, coordinates, direction): self.pacman = Pacman(self, coordinates) self.pacman.setDirection(direction) self.field.add(coordinates, self.pacman) def addWall(self, coordinates, icon): wall = Wall(coordinates, icon) self.walls.append(wall) self.field.add(coordinates, wall) def tick(self): if not self.gameOver: for ghost in self.ghosts: ghost.tick() if self.pacman: self.pacman.tick() self.updateField() def render(self): self.output = "{lives:1d}".format(lives=self.lives) self.output += "{score:>{width}d}\n".format(score=self.score, width=self.field.width() - len(self.output)) self.output += self.field.render() def refresh(self): print("\u001B[H" + "\u001B[2J" + "\u001B[1m") print(self.output) def updateField(self): newField = GameField(self.field.width(), self.field.height()) for wall in self.walls: newField.add(wall.coordinates, wall) for pill in self.pills: newField.add(pill.coordinates, pill) for ghost in self.ghosts: newField.add(ghost.coordinates, ghost) if self.pacman: newField.add(self.pacman.coordinates, self.pacman) if self.gameOver: Game.printGameOver(newField) self.field = newField def getElement(self, coords): return self.field.get(coords) def isGhost(self, coordinates): return Ghost.isGhost(self.field.get(coordinates)) def isWall(self, coordinates): return Wall.isWall(self.field.get(coordinates)) def isGate(self, coordinates): return Wall.isGate(self.field.get(coordinates)) def isField(self, coordinates): return Wall.isField(self.field.get(coordinates)) def isPill(self, coordinates): return Pill.isPill(self.field.get(coordinates)) def isPacman(self, coordinates): return isinstance(self.field.get(coordinates), Pacman) def eatPill(self, coordinates): pill = self.field.get(coordinates) self.pills.remove(pill) self.score += pill.score() for ghost in self.ghosts: ghost.triggerEffect(pill) if len(self.pills) == 0: self.nextLevel() def killGhost(self, ghost): self.score += ghost.score() ghost.kill() def killPacman(self): self.pacman.kill() self.lives -= 1 if (self.lives == 0): self.gameOver = True def getPacman(self): return self.pacman def setController(self, controller): self.controller = controller def move(self, direction): self.pacman.move(direction) def setLevel(self, level): self.level = level def setMaxLevel(self, level): self.lastLevel = level def nextLevel(self): if self.level < self.lastLevel: self.level += 1 self.pills = [] self.walls = [] self.ghosts = [] self.parse() else: self.gameOver = True self.pacman.restart() def useAnimation(self): self.animation = True def getLives(self): return self.lives def getScore(self): return self.score def printGameOver(field): cols = field.width() rows = field.height() GAME = "GAME" OVER = "OVER" y = floor(rows / 2) - 2 padding = floor(((cols - 2) - len(GAME)) / 2) for i in range(len(GAME)): x = padding + i + 1 field.add((x, y), GAME[i]) field.add((x, y + 1), OVER[i])
class Game(object): def __init__(self, input_map=None): if input_map is not None: self.input_map = input_map.rstrip() self.field = None self.lives = 3 self.score = 0 self.pacman = None self.ghosts = [] self.pills = [] self.walls = [] self.game_over = False self.controller = None self.display = None self.gate = None self.level = 1 self.last_level = 1 self.level_maps = None self.animation = False self.using_pills = False self.player = None self.scoreboard = None def init(self): self.parse() self.display.init(self) def play(self, debug): while True: self.tick() self.render() self.refresh() sleep(FRAME_RATE_IN_SECS) if (not self.pacman.alive): self.display.flash() self.pacman.restart() if self.game_over or debug: break self.post_score() def parse(self): self.set_game_input() columns = self.input_map.index("\n") self.parse_status(self.input_map[:columns]) screen_rows = self.input_map[columns+1:].split('\n') rows = len(screen_rows) self.field = GameField(columns, rows) self.parse_field(screen_rows) def set_game_input(self): if self.level_maps: self.input_map = self.level_maps.get_level(self.level) else: if "SEPARATOR" in self.input_map: self.level_maps = LevelMaps(self.input_map) self.last_level = self.level_maps.max_level() self.input_map = self.level_maps.get_level(self.level) def parse_status(self, status_line): elements = status_line.split() try: self.lives = int(elements[0]) self.score = int(elements[1]) except ValueError: pass def parse_field(self, screen_rows): for y in range(self.field.height()): for x in range(self.field.width()): element = tokenizer.get_element((x, y), screen_rows[y][x]) if (element): element.add_to_game(self) def add_pill(self, pill): self.using_pills = True self.pills.append(pill) self.field.add(pill.coordinates, pill) def add_ghost(self, ghost): self.ghosts.append(ghost) self.field.add(ghost.coordinates, ghost) def set_field(self, width, height): self.field = GameField(width, height) def set_pacman(self, coordinates, direction): pacman = Pacman(coordinates) pacman.set_direction(direction) pacman.add_to_game(self) def add_pacman(self, pacman): self.pacman = pacman self.field.add(pacman.coordinates, pacman) def add_wall(self, coordinates, icon): wall = Wall(coordinates, icon) self.walls.append(wall) self.field.add(coordinates, wall) if Wall.is_gate(wall): self.gate = wall def tick(self): for ghost in self.ghosts: ghost.tick() if self.pacman: self.pacman.tick() if self.is_level_clear(): self.next_level() self.update_field() def render(self): composite = Game.render_status(self.lives, self.score, self.field.width()) self.output = composite["video"] self.colour = composite["colour"] self.output += "\n" self.colour.append(0) composite = self.field.render() self.output += composite["video"] self.colour.extend(composite["colour"]) def render_status(lives, score, columns): colour = [] video = "{lives:1d}".format(lives=lives) video += "{score:>{width}d}".format(score=score, width=columns - len(video)) for i in range(len(video)): colour.append(0) return {"video": video, "colour": colour} def refresh(self): self.display.refresh(self.output, self.colour) def update_field(self): new_field = GameField(self.field.width(), self.field.height()) for wall in self.walls: new_field.add(wall.coordinates, wall) for pill in self.pills: new_field.add(pill.coordinates, pill) for ghost in self.ghosts: new_field.add(ghost.coordinates, ghost) if self.pacman: new_field.add(self.pacman.coordinates, self.pacman) if self.game_over: Game.print_game_over(new_field) self.field = new_field def get_element(self, coords): return self.field.get(coords) def is_ghost(self, coordinates): return Ghost.is_ghost(self.field.get(coordinates)) def is_wall(self, coordinates): return Wall.is_wall(self.field.get(coordinates)) def is_gate(self, coordinates): return Wall.is_gate(self.field.get(coordinates)) def is_field(self, coordinates): return Wall.is_field(self.field.get(coordinates)) def is_pill(self, coordinates): return Pill.is_pill(self.field.get(coordinates)) def is_pacman(self, coordinates): return isinstance(self.field.get(coordinates), Pacman) def eat_pill(self, coordinates): pill = self.field.get(coordinates) self.pills.remove(pill) self.score += pill.score() for ghost in self.ghosts: ghost.trigger_effect(pill) def kill_ghost(self, coordinates): ghost = self.field.get(coordinates) self.score += ghost.score() ghost.kill() def kill_pacman(self): self.pacman.kill() self.lives -= 1 if (self.lives == 0): self.game_over = True def get_pacman(self): return self.pacman def set_controller(self, controller): self.controller = controller def set_display(self, display): self.display = display def move(self, direction): self.pacman.move(direction) def set_level(self, level): self.level = level def set_max_level(self, level): self.last_level = level def is_level_clear(self): return (len(self.pills) == 0) and self.using_pills def next_level(self): if self.level < self.last_level: self.level += 1 self.pills[:] = [] self.walls = [] self.ghosts = [] self.parse() else: self.game_over = True self.pacman.restart() def use_animation(self): self.animation = True def get_lives(self): return self.lives def get_score(self): return self.score def print_game_over(field): cols = field.width() rows = field.height() GAME = "GAME" OVER = "OVER" y = floor(rows / 2) - 2 padding = floor(((cols - 2) - len(GAME)) / 2) for i in range(len(GAME)): x = padding + i + 1 field.add((x, y), GAME[i]) field.add((x, y+1), OVER[i]) def set_player(self, player): self.player = player def post_score(self): if self.scoreboard is None: scoreboard_url = os.getenv("SCOREBOARD_URL") self.scoreboard = Scoreboard(scoreboard_url, self.player) self.scoreboard.post_score(self.score) def get_scores(self): response = self.scoreboard.scores() scores = [] for score in response: name = score.player points = str(score.score) scores.append(name + ":" + points) return scores