From 2728612699a94503badb509836e89bc0f16178fc Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 6 Nov 2020 14:29:05 +0100 Subject: [PATCH 1/5] Create settings class --- dungeonbattle/settings.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 dungeonbattle/settings.py diff --git a/dungeonbattle/settings.py b/dungeonbattle/settings.py new file mode 100644 index 0000000..7e44427 --- /dev/null +++ b/dungeonbattle/settings.py @@ -0,0 +1,39 @@ +from typing import Any + + +class Settings: + def __init__(self): + self.KEY_UP_PRIMARY = 'z', 'Touche principale pour aller vers le haut' + self.KEY_UP_SECONDARY = 'KEY_UP', 'Touche secondaire pour aller vers le haut' + self.KEY_DOWN_PRIMARY = 's', 'Touche principale pour aller vers le bas' + self.KEY_DOWN_SECONDARY = 'KEY_DOWN', 'Touche secondaire pour aller vers le bas' + self.KEY_LEFT_PRIMARY = 'q', 'Touche principale pour aller vers la gauche' + self.KEY_LEFT_SECONDARY = 'KEY_LEFT', 'Touche secondaire pour aller vers la gauche' + self.KEY_RIGHT_PRIMARY = 'd', 'Touche principale pour aller vers la droite' + self.KEY_RIGHT_SECONDARY = 'KEY_RIGHT', 'Touche secondaire pour aller vers la droite' + self.TEXTURE_PACK = 'ASCII', 'Pack de textures utilisé' + + def __getattribute__(self, item: str) -> Any: + superattribute = super().__getattribute__(item) + if isinstance(superattribute, tuple) and item.isupper(): + return super().__getattribute__(item)[0] + return superattribute + + def get_comment(self, item: str) -> str: + """ + Retrieve the comment of a setting. + """ + if hasattr(self, item) and isinstance(object.__getattribute__(self, item), tuple): + return object.__getattribute__(self, item)[1] + for key in self.settings_keys: + print(key) + if getattr(self, key) == item: + return object.__getattribute__(self, key)[1] + + @property + def settings_keys(self): + """ + Get the list of all parameters. + """ + return (key for key in self.__dict__) + From af363dabfee3b8161f1bdfd1d729182ed1ce5644 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 6 Nov 2020 14:56:21 +0100 Subject: [PATCH 2/5] Add write and load settings --- .gitignore | 3 ++ dungeonbattle/settings.py | 70 +++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 3269e7f..7221e66 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ venv/ .pytest_cache/ __pycache__ + +# Don't commit settings +settings.json diff --git a/dungeonbattle/settings.py b/dungeonbattle/settings.py index 7e44427..e3808e8 100644 --- a/dungeonbattle/settings.py +++ b/dungeonbattle/settings.py @@ -1,24 +1,37 @@ -from typing import Any +import json +from typing import Any, Generator class Settings: + """ + This class stores the settings of the game. + Settings can be get by using for example settings.TEXTURE_PACK directly. + The comment can be get by using settings.get_comment('TEXTURE_PACK'). + We can define the setting by simply use settings.TEXTURE_PACK = 'new_key' + """ def __init__(self): - self.KEY_UP_PRIMARY = 'z', 'Touche principale pour aller vers le haut' - self.KEY_UP_SECONDARY = 'KEY_UP', 'Touche secondaire pour aller vers le haut' - self.KEY_DOWN_PRIMARY = 's', 'Touche principale pour aller vers le bas' - self.KEY_DOWN_SECONDARY = 'KEY_DOWN', 'Touche secondaire pour aller vers le bas' - self.KEY_LEFT_PRIMARY = 'q', 'Touche principale pour aller vers la gauche' - self.KEY_LEFT_SECONDARY = 'KEY_LEFT', 'Touche secondaire pour aller vers la gauche' - self.KEY_RIGHT_PRIMARY = 'd', 'Touche principale pour aller vers la droite' - self.KEY_RIGHT_SECONDARY = 'KEY_RIGHT', 'Touche secondaire pour aller vers la droite' - self.TEXTURE_PACK = 'ASCII', 'Pack de textures utilisé' + self.KEY_UP_PRIMARY = ['z', 'Touche principale pour aller vers le haut'] + self.KEY_UP_SECONDARY = ['KEY_UP', 'Touche secondaire pour aller vers le haut'] + self.KEY_DOWN_PRIMARY = ['s', 'Touche principale pour aller vers le bas'] + self.KEY_DOWN_SECONDARY = ['KEY_DOWN', 'Touche secondaire pour aller vers le bas'] + self.KEY_LEFT_PRIMARY = ['q', 'Touche principale pour aller vers la gauche'] + self.KEY_LEFT_SECONDARY = ['KEY_LEFT', 'Touche secondaire pour aller vers la gauche'] + self.KEY_RIGHT_PRIMARY = ['d', 'Touche principale pour aller vers la droite'] + self.KEY_RIGHT_SECONDARY = ['KEY_RIGHT', 'Touche secondaire pour aller vers la droite'] + self.TEXTURE_PACK = ['ASCII', 'Pack de textures utilisé'] def __getattribute__(self, item: str) -> Any: superattribute = super().__getattribute__(item) - if isinstance(superattribute, tuple) and item.isupper(): - return super().__getattribute__(item)[0] + if item.isupper() and item in self.settings_keys: + return superattribute[0] return superattribute + def __setattr__(self, name: str, value: Any) -> None: + if name in self.settings_keys: + object.__getattribute__(self, name)[0] = value + return + return super().__setattr__(name, value) + def get_comment(self, item: str) -> str: """ Retrieve the comment of a setting. @@ -26,14 +39,43 @@ class Settings: if hasattr(self, item) and isinstance(object.__getattribute__(self, item), tuple): return object.__getattribute__(self, item)[1] for key in self.settings_keys: - print(key) if getattr(self, key) == item: return object.__getattribute__(self, key)[1] @property - def settings_keys(self): + def settings_keys(self) -> Generator[str, Any, None]: """ Get the list of all parameters. """ return (key for key in self.__dict__) + def loads_from_string(self, json_str: str) -> None: + """ + Dump settings + """ + d = json.loads(json_str) + for key in d: + setattr(self, key, d[key]) + + def dumps_to_string(self) -> str: + """ + Dump settings + """ + d = dict() + for key in self.settings_keys: + d[key] = getattr(self, key) + return json.dumps(d) + + def load_settings(self) -> None: + """ + Loads the settings from a file + """ + with open("settings.json", "r") as f: + self.loads_from_string(f.read()) + + def write_settings(self) -> None: + """ + Dumps the settings into a file + """ + with open("settings.json", "w") as f: + f.write(self.dumps_to_string()) From 5ca28277062a005b1a6ed96c4004f285e455bfcd Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 6 Nov 2020 14:59:27 +0100 Subject: [PATCH 3/5] Write and load settings at the start of the game --- dungeonbattle/game.py | 4 ++++ dungeonbattle/settings.py | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dungeonbattle/game.py b/dungeonbattle/game.py index 9efd63f..b793fdd 100644 --- a/dungeonbattle/game.py +++ b/dungeonbattle/game.py @@ -1,5 +1,6 @@ from .interfaces import Map from .mapdisplay import MapDisplay +from .settings import Settings from .term_manager import TermManager @@ -8,6 +9,9 @@ class Game: def init(self) -> None: Game.INSTANCE = self + self.settings = Settings() + self.settings.load_settings() + self.settings.write_settings() with TermManager() as term_manager: self._start_game(term_manager.screen) diff --git a/dungeonbattle/settings.py b/dungeonbattle/settings.py index e3808e8..634118e 100644 --- a/dungeonbattle/settings.py +++ b/dungeonbattle/settings.py @@ -1,4 +1,5 @@ import json +import os from typing import Any, Generator @@ -64,14 +65,15 @@ class Settings: d = dict() for key in self.settings_keys: d[key] = getattr(self, key) - return json.dumps(d) + return json.dumps(d, indent=4) def load_settings(self) -> None: """ Loads the settings from a file """ - with open("settings.json", "r") as f: - self.loads_from_string(f.read()) + if os.path.isfile("settings.json"): + with open("settings.json", "r") as f: + self.loads_from_string(f.read()) def write_settings(self) -> None: """ From 9f6c94627909d8d898d6af5fd24bc2f3178d5b4c Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 6 Nov 2020 15:05:10 +0100 Subject: [PATCH 4/5] Test settings --- dungeonbattle/settings_test.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dungeonbattle/settings_test.py diff --git a/dungeonbattle/settings_test.py b/dungeonbattle/settings_test.py new file mode 100644 index 0000000..4841b5f --- /dev/null +++ b/dungeonbattle/settings_test.py @@ -0,0 +1,30 @@ +import unittest + +from dungeonbattle.settings import Settings + + +class TestSettings(unittest.TestCase): + def test_settings(self) -> None: + """ + Ensure that settings are well loaded. + """ + settings = Settings() + self.assertEqual(settings.KEY_UP_PRIMARY, 'z') + self.assertEqual(settings.KEY_DOWN_PRIMARY, 's') + self.assertEqual(settings.KEY_LEFT_PRIMARY, 'q') + self.assertEqual(settings.KEY_RIGHT_PRIMARY, 'd') + self.assertEqual(settings.KEY_UP_SECONDARY, 'KEY_UP') + self.assertEqual(settings.KEY_DOWN_SECONDARY, 'KEY_DOWN') + self.assertEqual(settings.KEY_LEFT_SECONDARY, 'KEY_LEFT') + self.assertEqual(settings.KEY_RIGHT_SECONDARY, 'KEY_RIGHT') + self.assertEqual(settings.TEXTURE_PACK, 'ASCII') + self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), settings.get_comment('TEXTURE_PACK')) + self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), 'Pack de textures utilisé') + + settings.TEXTURE_PACK = 'UNICODE' + self.assertEqual(settings.TEXTURE_PACK, 'UNICODE') + + settings.write_settings() + settings.load_settings() + + self.assertEqual(settings.TEXTURE_PACK, 'UNICODE') From 7469f4855fff4d5157558ba39a5ce356e1bc08f2 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Fri, 6 Nov 2020 15:08:29 +0100 Subject: [PATCH 5/5] We don't use tuples for settings now --- dungeonbattle/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dungeonbattle/settings.py b/dungeonbattle/settings.py index 634118e..064ad69 100644 --- a/dungeonbattle/settings.py +++ b/dungeonbattle/settings.py @@ -37,7 +37,7 @@ class Settings: """ Retrieve the comment of a setting. """ - if hasattr(self, item) and isinstance(object.__getattribute__(self, item), tuple): + if item in self.settings_keys: return object.__getattribute__(self, item)[1] for key in self.settings_keys: if getattr(self, key) == item: