ai-snake-lab 0.4.6__py3-none-any.whl → 0.4.8__py3-none-any.whl

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.
@@ -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"
ai_snake_lab/ui/AISim.py CHANGED
@@ -63,7 +63,7 @@ class AISim(App):
63
63
  """A Textual app that has an AI Agent playing the Snake Game."""
64
64
 
65
65
  TITLE = DDef.APP_TITLE
66
- CSS_PATH = os.path.join(DDir.UTILS, DFile.CSS_FILE)
66
+ CSS_PATH = DFile.CSS_FILE
67
67
 
68
68
  ## Runtime values
69
69
  # Current epsilon value (degrades in real-time)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-snake-lab
3
- Version: 0.4.6
3
+ Version: 0.4.8
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
@@ -1,15 +1,15 @@
1
1
  ai_snake_lab/ai/AIAgent.py,sha256=p_O7zC15s_tBcI7oqu60X2-3AbrzAWlGXWkrLVC4UsQ,3005
2
2
  ai_snake_lab/ai/AITrainer.py,sha256=ssX6B03yZLEKhNCJv9D83iFAEEhU3_XbW4sA0z5QMRM,3304
3
3
  ai_snake_lab/ai/EpsilonAlgo.py,sha256=Q2U_Ow28ZRQn1hlLybWEhB2Gn101x99mrQWupAooRjk,2142
4
- ai_snake_lab/ai/ReplayMemory.py,sha256=dtF6CkYWBvjqnKPdNA_0Dgr1DWQYAE-KMpB9IIxkoCk,4020
4
+ ai_snake_lab/ai/ReplayMemory.py,sha256=yX_dTEkzXxJyK6OjWHDUDoWHTB2sah1Vgg-X9MpK4e4,4529
5
5
  ai_snake_lab/ai/models/ModelL.py,sha256=hK7MoPyIF1_K43R_9xW_MYuaweQGo9qSMUIVrHDQZnQ,1249
6
6
  ai_snake_lab/ai/models/ModelRNN.py,sha256=Ky63BUqJEmwe1PbM4gtjvqd7SmSy_2XA1n-yu8DNexI,1104
7
7
  ai_snake_lab/constants/DDb4EPlot.py,sha256=2g8SdDVZWrTVSTw-rpO84OrNfl7ToBYtf6J7sYB7q8w,442
8
- ai_snake_lab/constants/DDef.py,sha256=XABLL9P_WUkCiNr2L-phiNL6cnxc_E0uD4vW6WhtZs0,378
9
- ai_snake_lab/constants/DDir.py,sha256=e8pNvZJpR4R6Cm3VRGljry_g-GAODYkz1ZrU8OudXuQ,395
8
+ ai_snake_lab/constants/DDef.py,sha256=InS6P0tUCvwZE_xiQtcxrrmLrts0HpO6CpU75UNXVnQ,402
9
+ ai_snake_lab/constants/DDir.py,sha256=6XiS6OTsqL-3AhYyZAZApziMFpw8kNd2QY4v0GLrb-Q,376
10
10
  ai_snake_lab/constants/DEpsilon.py,sha256=HuhMGxy3WIebcFQ2XZvlOpl03JwPYhHZdO40Bzph9yM,420
11
11
  ai_snake_lab/constants/DFields.py,sha256=0MV21hLy-Ojnn4Qa3C9_dQLPjC-3VYBjes_YU5V1Bio,521
12
- ai_snake_lab/constants/DFile.py,sha256=jYnYgrMqw3BMa3XEJw5XtC5buHfE0v7QFLv25BKNHW0,378
12
+ ai_snake_lab/constants/DFile.py,sha256=VAVH5qf2sFY62J6jcIJhfDnbGuEGpndqnwZr-ysFb7E,341
13
13
  ai_snake_lab/constants/DLabels.py,sha256=Nv7vCs8pxpF6Px5FD3JFkI7KEPWy6G8wLqzv31_nXxw,1501
14
14
  ai_snake_lab/constants/DLayout.py,sha256=XhRMpOqgzOkL0kcFz4pfS-HuVsYZZLBC6GIAq-E1_Ik,1616
15
15
  ai_snake_lab/constants/DModelL.py,sha256=VzAK5Uqkb0ovMPKTo_DJ2lQmIJkpRQyF-z3g3y4-j20,506
@@ -20,12 +20,12 @@ ai_snake_lab/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
20
20
  ai_snake_lab/game/GameBoard.py,sha256=iNgain-8YQg2Ky0GkmGX-ViVmL8P7zPiZYU6Qwrp9Cc,8465
21
21
  ai_snake_lab/game/GameElements.py,sha256=9vcNH2YWAzYyBZosvj1DzO6ZmUCUMUd8MaIhORWQ8go,470
22
22
  ai_snake_lab/game/SnakeGame.py,sha256=ADJSVD-bXBruSHf0rzQFh2P9hPWUAnCkQ95B-RFk1vI,6506
23
- ai_snake_lab/ui/AISim.py,sha256=_XUJtiQ_CMWB7beiXq3o9wgmIL-3QGwjHxy8KbSmd_c,15173
23
+ ai_snake_lab/ui/AISim.py,sha256=xAesy3utDuGaVzdTGLYeqIB4bZ6kg4EL16CMvRzMEOg,15147
24
+ ai_snake_lab/ui/AISim.tcss,sha256=XnhqjuxtOiNQHDyXFrbAYSlCw-6ch4e1o52nbytoeF0,2118
24
25
  ai_snake_lab/ui/Db4EPlot.py,sha256=pcEb0ydXNX2wL0EFBSrqhIoTEhryk4GD0Ua8FFEaZHY,5352
25
- ai_snake_lab/utils/AISim.tcss,sha256=XnhqjuxtOiNQHDyXFrbAYSlCw-6ch4e1o52nbytoeF0,2118
26
26
  ai_snake_lab/utils/ConstGroup.py,sha256=ZYyQxFd9PudBUZmc_NsNvWCp___utOe1MptqD3eyVH8,1174
27
- ai_snake_lab-0.4.6.dist-info/METADATA,sha256=shfnaQS9q3tefXcTuISZbAJRVCGUQ79ivMNrHgDQkKE,3689
28
- ai_snake_lab-0.4.6.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
29
- ai_snake_lab-0.4.6.dist-info/entry_points.txt,sha256=ThFx-0yPF5pdwOXUbEo95FEXLUUbOcjfhgMv67PHuIw,59
30
- ai_snake_lab-0.4.6.dist-info/licenses/LICENSE,sha256=f-FHFu0xzHH8O_mvKTw2jUZKhTpw6obpmVOI9rnpKeU,35151
31
- ai_snake_lab-0.4.6.dist-info/RECORD,,
27
+ ai_snake_lab-0.4.8.dist-info/METADATA,sha256=DbfR2kfsRDLU6ZEJ5cMzYgqc3cphigWSjgFYp2bSEpw,3689
28
+ ai_snake_lab-0.4.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
29
+ ai_snake_lab-0.4.8.dist-info/entry_points.txt,sha256=ThFx-0yPF5pdwOXUbEo95FEXLUUbOcjfhgMv67PHuIw,59
30
+ ai_snake_lab-0.4.8.dist-info/licenses/LICENSE,sha256=f-FHFu0xzHH8O_mvKTw2jUZKhTpw6obpmVOI9rnpKeU,35151
31
+ ai_snake_lab-0.4.8.dist-info/RECORD,,
File without changes