ai-snake-lab 0.4.5__tar.gz → 0.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/PKG-INFO +1 -1
  2. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/ReplayMemory.py +31 -10
  3. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DDef.py +1 -0
  4. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DDir.py +0 -1
  5. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DFile.py +0 -1
  6. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/game/SnakeGame.py +6 -6
  7. {ai_snake_lab-0.4.5/ai_snake_lab → ai_snake_lab-0.4.7/ai_snake_lab/ui}/AISim.py +5 -1
  8. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/pyproject.toml +2 -2
  9. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/LICENSE +0 -0
  10. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/README.md +0 -0
  11. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/AIAgent.py +0 -0
  12. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/AITrainer.py +0 -0
  13. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/EpsilonAlgo.py +0 -0
  14. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/models/ModelL.py +0 -0
  15. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ai/models/ModelRNN.py +0 -0
  16. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DDb4EPlot.py +0 -0
  17. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DEpsilon.py +0 -0
  18. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DFields.py +0 -0
  19. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DLabels.py +0 -0
  20. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DLayout.py +0 -0
  21. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DModelL.py +0 -0
  22. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DModelLRNN.py +0 -0
  23. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DReplayMemory.py +0 -0
  24. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/DSim.py +0 -0
  25. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/constants/__init__.py +0 -0
  26. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/game/GameBoard.py +0 -0
  27. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/game/GameElements.py +0 -0
  28. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/ui/Db4EPlot.py +0 -0
  29. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/utils/AISim.tcss +0 -0
  30. {ai_snake_lab-0.4.5 → ai_snake_lab-0.4.7}/ai_snake_lab/utils/ConstGroup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-snake-lab
3
- Version: 0.4.5
3
+ Version: 0.4.7
4
4
  Summary: Interactive reinforcement learning sandbox for experimenting with AI agents in a classic Snake Game environment.
5
5
  License: GPL-3.0
6
6
  License-File: LICENSE
@@ -14,10 +14,11 @@ import os
14
14
  from collections import deque
15
15
  import random
16
16
  import sqlite3, pickle
17
+ import tempfile
18
+ import shutil
17
19
 
18
20
  from ai_snake_lab.constants.DReplayMemory import MEM_TYPE
19
- from ai_snake_lab.constants.DFile import DFile
20
- from ai_snake_lab.constants.DDir import DDir
21
+ from ai_snake_lab.constants.DDef import DDef
21
22
 
22
23
 
23
24
  class ReplayMemory:
@@ -31,11 +32,6 @@ class ReplayMemory:
31
32
  self.max_states = 15000
32
33
  self.max_shuffle_games = 40
33
34
  self.max_games = 500
34
- self.db_file = os.path.join(DDir.AI_SNAKE_LAB, DDir.DB, DFile.REPLAY_DB)
35
-
36
- # Delete the replay memory file, if it exists
37
- if os.path.exists(self.db_file):
38
- os.remove(self.db_file)
39
35
 
40
36
  if self._mem_type == MEM_TYPE.SHUFFLE:
41
37
  # States are stored in a deque and a random sample will be returned
@@ -46,13 +42,33 @@ class ReplayMemory:
46
42
  # A complete game will be returned
47
43
  self.cur_memory = []
48
44
 
45
+ # Get a temporary directory for the DB file
46
+ self._tmpfile = tempfile.NamedTemporaryFile(suffix=DDef.DOT_DB, delete=False)
47
+ self.db_file = self._tmpfile.name
48
+
49
49
  # Connect to SQLite
50
50
  self.conn = sqlite3.connect(self.db_file, check_same_thread=False)
51
+
52
+ # Get a cursor
51
53
  self.cursor = self.conn.cursor()
54
+
55
+ # We don't need the file handle anymore
56
+ self._tmpfile.close()
57
+
58
+ # Intialize the schema
52
59
  self.init_db()
53
60
 
54
- def __len__(self):
55
- return len(self.memories)
61
+ def __enter__(self):
62
+ return self
63
+
64
+ def __exit__(self, exc_type, exc_val, exc_tb):
65
+ self.close()
66
+
67
+ def __del__(self):
68
+ try:
69
+ self.close()
70
+ except Exception:
71
+ pass # avoid errors on interpreter shutdown
56
72
 
57
73
  def append(self, transition):
58
74
  """Add a transition to the current game."""
@@ -75,7 +91,12 @@ class ReplayMemory:
75
91
 
76
92
  def close(self):
77
93
  """Close the database connection."""
78
- self.conn.close()
94
+ if getattr(self, "conn", None):
95
+ self.conn.close()
96
+ self.conn = None
97
+ if getattr(self, "db_file", None) and os.path.exists(self.db_file):
98
+ os.remove(self.db_file)
99
+ self.db_file = None
79
100
 
80
101
  def get_random_game(self):
81
102
  """Return a random full game from the database."""
@@ -15,4 +15,5 @@ class DDef(ConstGroup):
15
15
  """Defaults"""
16
16
 
17
17
  APP_TITLE: str = "AI Snake Game Lab"
18
+ DOT_DB: str = ".db"
18
19
  MOVE_DELAY: float = 0.0
@@ -15,5 +15,4 @@ class DDir(ConstGroup):
15
15
  """Directories"""
16
16
 
17
17
  AI_SNAKE_LAB: str = "ai_snake_lab"
18
- DB: str = "db"
19
18
  UTILS: str = "utils"
@@ -15,4 +15,3 @@ class DFile(ConstGroup):
15
15
  """Files"""
16
16
 
17
17
  CSS_FILE: str = "AISim.tcss"
18
- REPLAY_DB: str = "replay_mem.db"
@@ -129,12 +129,6 @@ class SnakeGame:
129
129
  game_over = True
130
130
  reward = -10
131
131
 
132
- # Set a negative reward if the snake head is adjacent to the snake body.
133
- # This is to discourage snake collisions.
134
- for segment in self.snake[1:]:
135
- if abs(self.head.x - segment.x) < 2 and abs(self.head.y - segment.y) < 2:
136
- reward -= -1
137
-
138
132
  if game_over == True:
139
133
  # Game is over: Snake or wall collision or exceeded max moves
140
134
  self.game_reward += reward
@@ -159,6 +153,12 @@ class SnakeGame:
159
153
  reward -= 2
160
154
  self.distance_to_food = cur_distance
161
155
 
156
+ ## 6. Set a negative reward if the snake head is adjacent to the snake body.
157
+ # This is to discourage snake collisions.
158
+ for segment in self.snake[1:]:
159
+ if abs(self.head.x - segment.x) < 2 and abs(self.head.y - segment.y) < 2:
160
+ reward -= -2
161
+
162
162
  self.game_reward += reward
163
163
  self.game_board.update_snake(snake=self.snake, direction=self.direction)
164
164
  self.game_board.update_food(food=self.food)
@@ -426,6 +426,10 @@ def minutes_to_uptime(seconds: int):
426
426
  return f"{seconds}s"
427
427
 
428
428
 
429
- if __name__ == "__main__":
429
+ def main():
430
430
  app = AISim()
431
431
  app.run()
432
+
433
+
434
+ if __name__ == "__main__":
435
+ main()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ai-snake-lab"
3
- version = "0.4.5"
3
+ version = "0.4.7"
4
4
  description = "Interactive reinforcement learning sandbox for experimenting with AI agents in a classic Snake Game environment."
5
5
  authors = [{ name = "Nadim-Daniel Ghaznavi", email = "nghaznavi@gmail.com" }]
6
6
  license = { text = "GPL-3.0" }
@@ -38,7 +38,7 @@ dependencies = [
38
38
  ]
39
39
 
40
40
  [project.scripts]
41
- ai-snake-lab = "ai_snake_lab.AISim:main"
41
+ ai-snake-lab = "ai_snake_lab.ui.AISim:main"
42
42
 
43
43
  [project.urls]
44
44
  "Bug Tracker" = "https://github.com/NadimGhaznavi/ai_snake_lab/issues"
File without changes
File without changes