summaryrefslogtreecommitdiff
path: root/Game.py
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2025-11-04 22:30:28 +0200
committerJoel Kronqvist <joel.kronqvist@iki.fi>2025-11-04 22:30:28 +0200
commit50db52d03bc08313c736c754ab0f908ab90086e3 (patch)
tree291b17e0a48e806b8e05853f2be3c80ecbf23c02 /Game.py
parenta60a1403b7335719ceca18c745ff663bd6852e94 (diff)
downloadSnakePuzzle-master.tar.gz
SnakePuzzle-master.zip
refactor: extracted Level from Game, also added level restarting functionalityHEADmaster
Diffstat (limited to 'Game.py')
-rw-r--r--Game.py128
1 files changed, 69 insertions, 59 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
+
+