clean up score and exit
authorGeoffrey Allott <geoffrey@allott.email>
Tue, 6 Dec 2022 09:55:08 +0000 (09:55 +0000)
committerGeoffrey Allott <geoffrey@allott.email>
Tue, 6 Dec 2022 09:55:08 +0000 (09:55 +0000)
snake.py

index 9e5c8ebddb3abd69a98ba29005876788ec779dde..94c5ba88b083f4cac059a657a69d64b11353e4b1 100644 (file)
--- a/snake.py
+++ b/snake.py
@@ -5,6 +5,9 @@ import random
 import sys
 from time import sleep
 
+class ExitGameException(BaseException):
+    pass
+
 class TileContents(Enum):
     Empty = "Empty"
     Wall = "Wall"
@@ -58,7 +61,6 @@ class GameArea:
         self.dir = Direction.Right
         self.turbo = 0
         self.random = random.Random()
-        self.score = 0
         self.highscore_file = highscore_file
         try:
             with open(self.highscore_file) as f:
@@ -68,6 +70,9 @@ class GameArea:
         self.orig_highscore = self.highscore
         self.add_fruit()
 
+    def score(self):
+        return len(self.snake) - 1
+
     def paint(self):
         for i, row in enumerate(self.tiles):
             for j, tile in enumerate(row):
@@ -76,7 +81,7 @@ class GameArea:
                 else:
                     self.win.addch(i, j, str(tile).replace('ยง', '*'))
         self.win.addstr(i + 1, 2, f'{self.highscore:04}')
-        self.win.addstr(i + 1, j - 6, f'{self.score:04}')
+        self.win.addstr(i + 1, j - 6, f'{self.score():04}')
         self.win.refresh()
     
     def getch(self):
@@ -104,8 +109,7 @@ class GameArea:
         if ch == 27 or ch == ord('p'):
             self.pause()
         if ch == ord('q'):
-            curses.endwin()
-            sys.exit(0)
+            raise ExitGameException()
 
     def random_empty_tile(self):
         return self.random.choice([
@@ -161,15 +165,14 @@ class GameArea:
             if ch == 27 or ch == ord('p'):
                 break
             if ch == ord('q'):
-                curses.endwin()
-                sys.exit(0)
+                raise ExitGameException()
         self.win.nodelay(True)
         self.paint()
     
     def game_over(self):
         self.paint()
         self.win.addstr(self.height // 2, (self.width - 9) // 2, 'GAME OVER')
-        if self.score > self.orig_highscore:
+        if self.score() > self.orig_highscore:
             self.win.addstr(self.height // 2 + 2, (self.width - 10) // 2, 'HIGH SCORE')
         self.win.refresh()
         self.win.nodelay(False)
@@ -177,8 +180,7 @@ class GameArea:
             ch = self.win.getch()
             if ch == 27 or ch == ord('q'):
                 break
-        curses.endwin()
-        sys.exit(0)
+        raise ExitGameException()
 
     def update(self):
         if self.dir == Direction.Left:
@@ -193,11 +195,9 @@ class GameArea:
         if self.tiles[r][c] is TileContents.Fruit:
             self.fruit = [fruit for fruit in self.fruit if (fruit.row, fruit.column) != (r, c)]
             self.tiles[r][c] = TileContents.Snake
-            self.score += 1
         elif self.tiles[r][c] is TileContents.TurboFruit:
             self.fruit = [fruit for fruit in self.fruit if (fruit.row, fruit.column) != (r, c)]
             self.tiles[r][c] = TileContents.Snake
-            self.score += 1
             self.turbo = 100
         elif self.tiles[r][c] is TileContents.PortalFruit:
             portal_id = [fruit.id for fruit in self.fruit if (fruit.row, fruit.column) == (r, c)]
@@ -215,7 +215,6 @@ class GameArea:
                 self.tiles[r][c] = TileContents.Empty
                 self.snake = self.snake[1:]
             else:
-                self.score += 1
                 dest_portal = self.random.choice(dest_portals)
                 self.snake[-1] = dest_portal
                 self.tiles[r][c] = TileContents.Empty
@@ -230,10 +229,8 @@ class GameArea:
             r, c = self.snake[0]
             self.tiles[r][c] = TileContents.Empty
             self.snake = self.snake[1:]
-        if self.score != len(self.snake) - 1:
-            raise Exception(len(self.snake))
-        if self.score > self.highscore:
-            self.highscore = self.score
+        if self.score() > self.highscore:
+            self.highscore = self.score()
             self.write_highscore()
         if not self.turbo:
             self.decay_fruit()
@@ -256,15 +253,19 @@ def setup():
     return win
 
 if __name__ == '__main__':
-    win = curses.initscr()
     win = setup()
     gamearea = GameArea(win=win, highscore_file=os.path.expanduser('~/.local/snake/highscore'))
-    while True:
-        gamearea.paint()
-        if not gamearea.turbo:
-            sleep(0.1)
-        else:
-            sleep(0.05)
-        gamearea.getch()
-        gamearea.update()
+    try:
+        while True:
+            gamearea.paint()
+            if not gamearea.turbo:
+                sleep(0.1)
+            else:
+                sleep(0.05)
+            gamearea.getch()
+            gamearea.update()
+    except ExitGameException:
+        pass
+    finally:
+        curses.endwin()