summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Game.py128
-rw-r--r--GameView.py35
-rw-r--r--Snake.py6
-rwxr-xr-xmain.py27
4 files changed, 101 insertions, 95 deletions
diff --git a/Game.py b/Game.py
index 7e5cb1d..b5f70d1 100644
--- a/Game.py
+++ b/Game.py
@@ -15,32 +15,19 @@ from Walls import Walls
Static = Union[PressurePlate, Trail, Door]
-class Game:
- """Class responsible for the main logic of a game.
- For a game, this will probably be a singleton."""
-
- def __init__(self, levels: list[str]):
- self.snake: Optional[Snake] = None
+class Level:
+
+ def __init__(self, levelString: str):
self.boxes: list[Box] = []
self.statics: list[Static] = []
- self.walls: Walls = Walls.empty()
- self.levelIn: Optional['Vec2'] = None
- self.level = -1
- self.levels = []
- self.levels = levels
- self.nextLevel()
-
-
- def nextLevel(self) -> None:
- self.level += 1
- self.walls = Walls.fromString(self.levels[self.level])
- self.snake = None
+ self.walls = Walls.fromString(levelString)
self.statics = []
+ self.levelIn: Optional['Vec2'] = None
self.boxes = []
y = 0
- for line in self.levels[self.level].split('\n'):
+ for line in levelString.split('\n'):
x = 0
for char in line:
if char == "b":
@@ -49,7 +36,7 @@ class Game:
if self.doorAt(Vec.Vec2(x, y)) == None:
self.statics.append(Door(Vec.Vec2(x, y)))
elif char == "_":
- self.parseSwitchTrail(self.levels[self.level], Vec.Vec2(x, y))
+ self.parseSwitchTrail(levelString, Vec.Vec2(x, y))
elif char == "I":
self.levelIn = Vec.Vec2(x, y)
x += 1
@@ -63,6 +50,15 @@ class Game:
self.snake.heading = Vec.up
+ def doorAt(self, pos: Vec2) -> Optional[Door]:
+ for static in self.statics:
+ match static:
+ case Door():
+ if static.pos == pos:
+ return static
+ return None
+
+
def parseSwitchTrail(self, levelStr: str, platePos: Vec2) -> None:
level = levelStr.split('\n')
startSwitch = None
@@ -132,45 +128,6 @@ class Game:
return True
return pos in map(lambda box: box.pos, self.boxes)
- def tick(self) -> None:
- match self.snake:
- case Snake():
- self.snake.move()
-
- lastSnakeCell = self.snake.cells[0]#[len(self.snake.cells) - 1]
- if (lastSnakeCell.x < 0 or lastSnakeCell.x >= self.width()) or (lastSnakeCell.y < 0 or lastSnakeCell.y >= self.height()):
- self.nextLevel()
- return
-
- for static in self.statics:
- match static:
- case PressurePlate():
- if static.isActive() and not self._movableSolidAt(static.pos):
- static.deactivate()
- elif (not static.isActive()) and self._movableSolidAt(static.pos):
- static.activate()
- for static in self.statics:
- match static:
- case Door():
- if static.isOpen() and not static.isActive():
- if not self._movableSolidAt(static.pos):
- static.close()
-
-
- def isLost(self) -> bool:
- match self.snake:
- case Snake(): return self.snake.hasCollided
- case _: return False
-
-
- def doorAt(self, pos: Vec2) -> Optional[Door]:
- for static in self.statics:
- match static:
- case Door():
- if static.pos == pos:
- return static
- return None
-
def closedDoorAt(self, pos: Vec2) -> bool:
res = False
@@ -180,6 +137,7 @@ class Game:
res = res or (static.pos == pos and not static.isOpen())
return res
+
def switchAt(self, pos: Vec2) -> Optional[PressurePlate]:
for static in self.statics:
match static:
@@ -204,3 +162,55 @@ class Game:
return True
else:
return False
+
+ def isCompleted(self) -> bool:
+ snakeHead = self.snake.cells[0]
+ return (snakeHead.x < 0 or snakeHead.x >= self.width()) or (snakeHead.y < 0 or snakeHead.y >= self.height())
+
+
+
+class Game:
+ """Class responsible for the main logic of a game.
+ For a game, this will probably be a singleton."""
+
+ def __init__(self, levels: list[str]):
+ self.levelIndex = 0
+ self.levels = levels
+ self.level = Level(self.levels[self.levelIndex])
+
+
+ def nextLevel(self) -> None:
+ self.levelIndex += 1
+ self.level = Level(self.levels[self.levelIndex])
+
+ def restartLevel(self) -> None:
+ self.level = Level(self.levels[self.levelIndex])
+
+
+ def tick(self) -> None:
+
+ match self.level.snake:
+ case Snake():
+ self.level.snake.move()
+
+ for static in self.level.statics:
+ match static:
+ case PressurePlate():
+ if static.isActive() and not self.level._movableSolidAt(static.pos):
+ static.deactivate()
+ elif (not static.isActive()) and self.level._movableSolidAt(static.pos):
+ static.activate()
+ for static in self.level.statics:
+ match static:
+ case Door():
+ if static.isOpen() and not static.isActive():
+ if not self.level._movableSolidAt(static.pos):
+ static.close()
+
+
+ def isLost(self) -> bool:
+ match self.level.snake:
+ case Snake(): return self.level.snake.hasCollided
+ case _: return False
+
+
diff --git a/GameView.py b/GameView.py
index a670d7c..6ec69fe 100644
--- a/GameView.py
+++ b/GameView.py
@@ -101,25 +101,26 @@ class GameView:
def isRunning(self) -> bool:
- return not self.game.isLost()
+ #return not self.game.isLost()
+ return True
def width(self) -> int:
- return self.game.width() * self.cellWidth
+ return self.game.level.width() * self.cellWidth
def height(self) -> int:
- return self.game.height() * self.cellWidth
+ return self.game.level.height() * self.cellWidth
def render(self, surface: Surface) -> None:
surface.fill("black")
- for cell in self.game.walls.walls():
+ for cell in self.game.level.walls.walls():
self._drawBoxOfColor(surface, "white", cell.x, cell.y)
- for static in self.game.statics:
+ for static in self.game.level.statics:
match static:
case Door():
if static.isOpen():
@@ -134,14 +135,11 @@ class GameView:
else:
self._drawBoxOfColor(surface, "purple", static.pos.x, static.pos.y)
- for box in self.game.boxes:
+ for box in self.game.level.boxes:
self._drawBoxOfColor(surface, "brown", box.pos.x, box.pos.y)
- match self.game.snake:
- case None: raise ValueError("snake not found")
- case _:
- for cell in self.game.snake.cells:
- self._drawBoxOfColor(surface, "red", cell.x, cell.y)
+ for cell in self.game.level.snake.cells:
+ self._drawBoxOfColor(surface, "red", cell.x, cell.y)
def _drawBoxOfColor(self, surface: Surface, color: str, x: int, y: int) -> None:
pygame.draw.rect(surface, color, pygame.Rect(
@@ -158,21 +156,22 @@ class GameView:
match self.nextControlDirection:
case None: None
case _:
- get(self.game.snake).heading = self.nextControlDirection
+ self.game.level.snake.heading = self.nextControlDirection
self.nextControlDirection = None
-# match self.game.snake:
-# case None: return None
-# case _:
-# self.game.snake.heading = self.nextControlDirection
-# self.nextControlDirection = None
self.game.tick()
elif not self.timeBased:
match self.nextControlDirection:
case None: None
case _:
self._previousTick = time
- get(self.game.snake).heading = self.nextControlDirection
+ self.game.level.snake.heading = self.nextControlDirection
self.nextControlDirection = None
self.game.tick()
+ if self.game.level.isCompleted():
+ self.game.nextLevel()
+
+ if self.game.isLost():
+ self.game.restartLevel()
+
diff --git a/Snake.py b/Snake.py
index 84f3505..8aad9ed 100644
--- a/Snake.py
+++ b/Snake.py
@@ -6,16 +6,16 @@ import Game
class Snake:
- def __init__(self, cells: list[Vec2], game: "Game.Game") -> None:
+ def __init__(self, cells: list[Vec2], level: "Game.Level") -> None:
self.heading = Vec.up
self.hasCollided = False
self.cells = cells
- self.game = game
+ self.level = level
def move(self) -> None:
nextPos = self.cells[0] + self.heading
last = self.cells.pop()
- if self.game.enter(nextPos, self.heading):
+ if self.level.enter(nextPos, self.heading):
self.cells.insert(0, nextPos)
else:
self.cells.append(last)
diff --git a/main.py b/main.py
index 688589c..1ccddee 100755
--- a/main.py
+++ b/main.py
@@ -15,21 +15,18 @@ running = True
while running:
- match view.game.snake:
- case None: raise ValueError("no snake")
- case _:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
- elif event.type == pygame.KEYDOWN:
- if event.key == pygame.K_w and view.game.snake.heading != Vec.up.neg():
- view.nextControlDirection = Vec.up
- elif event.key == pygame.K_a and view.game.snake.heading != Vec.left.neg():
- view.nextControlDirection = Vec.left
- elif event.key == pygame.K_r and view.game.snake.heading != Vec.down.neg():
- view.nextControlDirection = Vec.down
- elif event.key == pygame.K_s and view.game.snake.heading != Vec.right.neg():
- view.nextControlDirection = Vec.right
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ running = False
+ elif event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_w and view.game.level.snake.heading != Vec.up.neg():
+ view.nextControlDirection = Vec.up
+ elif event.key == pygame.K_a and view.game.level.snake.heading != Vec.left.neg():
+ view.nextControlDirection = Vec.left
+ elif event.key == pygame.K_r and view.game.level.snake.heading != Vec.down.neg():
+ view.nextControlDirection = Vec.down
+ elif event.key == pygame.K_s and view.game.level.snake.heading != Vec.right.neg():
+ view.nextControlDirection = Vec.right
if view.isRunning():
view.update(pygame.time.get_ticks())