-
Notifications
You must be signed in to change notification settings - Fork 11
feat: add some basic classes #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 1 commit
c54cc2d
9a3d356
2ae83b7
90223bc
078158b
99413f3
d768341
732a873
c93dc56
26c31cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# | ||
|
||
from itertools import chain | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer importing full modules. E.g.: import itertools This helps in understanding where imported obhects come from. from typing import Union Wrong: import typing This helps in keeping type signatures readable. |
||
|
||
_dependencies = {} | ||
_dependent_vars = set() | ||
|
||
def addDependency(dep1: str, dep2: str): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Functions, variables and also modules should be named in |
||
global _dependencies, _dependent_vars | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid global variables where possible. Generally, you can always rewrite your code to share objects by other means instead. That said, in this case this seems fine for a prototype. Note that you only need to declare variables as global of you want to change them globally from a local scope. You can always read variables from outer scopes, so it is unnecessary to declare |
||
if dep1 in _dependencies.keys(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When iterating over a |
||
if not dep2 in _dependencies[dep1]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Membership tests should use if dep2 not in _dependencies[dep1]: |
||
_dependencies[dep1].append(dep2) | ||
else: | ||
_dependencies[dep1] = [dep2] | ||
_dependent_vars = set(chain.from_iterable(_dependencies.values())) | ||
|
||
class Dependency: | ||
def _reset_dependent_vars(self, name): | ||
for var in _dependencies[name]: | ||
super().__delattr__(f"{var}") | ||
if var in _dependencies: | ||
self._reset_dependent_vars(var) | ||
|
||
def __setattr__(self, name, value): | ||
global _dependencies, _dependent_vars | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, these globals are not needed. |
||
if name in _dependent_vars: | ||
raise AttributeError("Cannot set this value.") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error would be more helpful if it specified the attribute that cannot be set. |
||
if name in _dependencies: | ||
self._reset_dependent_vars(name) | ||
name = f"_{name}" | ||
super().__setattr__(name, value) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# | ||
|
||
from Dependency import addDependency | ||
|
||
class Mod: | ||
def __init__(self, name: str, type: str, value, source: str, tags: dict = {}): | ||
self.name = name | ||
self.type = type | ||
self.value = value | ||
self.source = source | ||
self.tags = tags | ||
self.process() | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since modifiers in our mod DB are always unique by ID and do not need to be ordered, we could simplify the code in Since we have decided that modifiers should always be inequal to every other modifier than themselves, this is possible to implement correctly even though class Modifier:
...
def __eq__(self, other: Modifier) -> bool:
return self is other
def __hash__(self) -> int:
return id(self) This allows us to turn mod_db.ModifierDatabase into: class ModifierDatabase:
def __init__(self) -> None:
self.db = collections.defaultdict(lambda: collections.defaultdict(set))
def add_entry(self, entry: modifiers.Modifier) -> None:
name = entry.name
type_ = entry.type_
self.db[name][type_].add(entry) and subsequently: def add_entry(self, entry: modifiers.Modifier) -> None:
self.db[entry.name][entry.type_].add(entry) |
||
def process(self): | ||
if 'type' in self.tags.keys() and self.tags['type'] == "Multiplier": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Python, prefer EAFP (easier to ask for forgiveness than permission) over LBYL (look before you leap). So instead of checking whether a key exists, just try to access it and handle the exception if it doesnt exist. |
||
addDependency(self.tags['var'].lower(), f"{self.type.lower()}_{self.name.lower()}") | ||
|
||
def test(): | ||
Mod("Health", "BASE", 12, "", { "type": "Multiplier", "var": "Level" }) | ||
|
||
if __name__ == "__main__": | ||
from Dependency import _dependencies | ||
test() | ||
print(_dependencies) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# | ||
|
||
from functools import cached_property | ||
from math import floor | ||
|
||
from Dependency import Dependency, addDependency | ||
|
||
class Player(Dependency): | ||
def __init__(self, level, strength): | ||
self._level = level | ||
self._strength = strength | ||
self._flat_life = 0 | ||
self._more_life = 0 | ||
self._inc_life = 0 | ||
self._base_health = None | ||
self._max_health = None | ||
|
||
addDependency("level", "base_health") | ||
addDependency("strength", "base_health") | ||
addDependency("flat_life", "base_health") | ||
addDependency("base_health", "max_health") | ||
addDependency("more_life", "max_health") | ||
addDependency("inc_life", "max_health") | ||
|
||
@cached_property | ||
def base_health(self): | ||
print("Base Health calculated") | ||
return 38 + self.level * 12 + floor(self.strength / 2) + self.flat_life | ||
|
||
@cached_property | ||
def max_health(self): | ||
print("Max Health calculated") | ||
return self.base_health * (1 + self.inc_life / 100) * (1 + self.more_life / 100) | ||
|
||
@property | ||
def level(self): | ||
return self._level | ||
|
||
@property | ||
def strength(self): | ||
return self._strength | ||
|
||
@property | ||
def flat_life(self): | ||
return self._flat_life | ||
|
||
@property | ||
def more_life(self): | ||
return self._more_life | ||
|
||
@property | ||
def inc_life(self): | ||
return self._inc_life | ||
|
||
def test(): | ||
player = Player(1, 20) | ||
print(f"{player.max_health}") | ||
|
||
player.level = 5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will shadow the @level.setter
def level(self, value: int) -> None:
self._level = value |
||
print(f"{player.max_health}") | ||
|
||
player.more_life = 100 | ||
print(f"{player.max_health}") | ||
|
||
player.flat_life = 100 | ||
print(f"{player.max_health}") | ||
|
||
if __name__ == "__main__": | ||
test() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does every file begin with "#" here?