1import math
2
3
4class Potion:
5 def __init__(self, effects, duration, intensities=None):
6 self.effects = effects
7 self.intensities = intensities or {effect: 1 for effect in effects}
8 self.duration = duration
9 self.remaining_duration = duration
10 self.initial_state = None
11 self.applied_effects = set()
12 self.used = False
13
14 for effect_name in effects:
15 setattr(self, effect_name, lambda target, name=effect_name: self.apply_effect(name, target))
16
17 def apply_effect(self, effect, target, intensity=1):
18 if self.used:
19 raise TypeError("Potion is now part of something bigger than itself.")
20
21 if effect in self.applied_effects:
22 raise TypeError("Effect is depleted.")
23
24 if effect in self.effects:
25 if effect in self.intensities:
26 intensity = self.intensities[effect]
27
28 if self.initial_state is None:
29 self.initial_state = self.save_state(target)
30
31 for _ in range(intensity):
32 self.effects[effect](target)
33 self.applied_effects.add(effect)
34 else:
35 raise ValueError("Invalid effect name.")
36
37 def apply_all_effects(self, target):
38 for effect in self.effects:
39 self.apply_effect(effect, target)
40
41 def save_state(self, target):
42 return vars(target).copy()
43
44 def revert_state(self, target):
45 if self.initial_state is not None:
46 for attr, value in self.initial_state.items():
47 setattr(target, attr, value)
48
49 def round_intensity(self, intensity, power):
50 if not isinstance(power, int) or power < 1:
51 return math.floor(intensity * power) if intensity <= power else math.ceil(intensity * power)
52 else:
53 return intensity * power
54
55 def __add__(self, other):
56 combined_effects = {}
57 combined_intensities = {}
58
59 for effect, intensity in self.intensities.items():
60 combined_effects[effect] = self.effects[effect]
61 combined_intensities[effect] = intensity
62
63 for effect, intensity in other.intensities.items():
64 if effect in combined_effects:
65 combined_intensities[effect] += intensity
66 else:
67 combined_effects[effect] = other.effects[effect]
68 combined_intensities[effect] = intensity
69 combined_duration = max(self.duration, other.duration)
70 self.used = True
71 return Potion(combined_effects, combined_duration, intensities=combined_intensities)
72
73 def __mul__(self, power):
74 updated_effects = {}
75 updated_intensities = {}
76
77 for effect, intensity in self.intensities.items():
78 updated_effects[effect] = self.effects[effect]
79 updated_intensities[effect] = self.round_intensity(intensity, power)
80
81 self.used = True
82 return Potion(updated_effects, self.duration * power, intensities=updated_intensities)
83
84 def __sub__(self, other):
85 if not isinstance(other, Potion):
86 raise TypeError("Subtraction can only be performed with another Potion.")
87 if not all(effect in self.effects for effect in other.effects):
88 raise TypeError("Cannot subtract. 'self' does not contain all effects of 'other'.")
89
90 subtracted_effects = {}
91 subtracted_intensities = {}
92 subtracted_duration = self.duration
93
94 for effect, intensity in self.intensities.items():
95 other_intensity = other.intensities.get(effect, 0)
96 new_intensity = intensity - other_intensity
97 if new_intensity >= 0:
98
99 subtracted_effects[effect] = self.effects[effect]
100 subtracted_intensities[effect] = new_intensity
101 elif new_intensity < 0:
102 raise TypeError("Negative intensity not allowed during subtraction.")
103
104 self.used = True
105 return Potion(subtracted_effects, subtracted_duration, intensities=subtracted_intensities)
106
107 def __truediv__(self, divisor):
108 if not isinstance(divisor, int) or divisor < 1:
109 raise ValueError("Divisor must be a natural number greater than zero.")
110
111 part_duration = self.duration / divisor
112 part_intensities = {name: round(intensity / divisor) if intensity > 0 else 0 for name, intensity in
113 self.intensities.items()}
114
115 parts = tuple(Potion(self.effects, part_duration, intensities=part_intensities) for _ in range(divisor))
116 self.used = True
117 return parts
118
119 def tick(self, target):
120 if self.duration > 0:
121 self.duration -= 1
122 if self.duration == 0:
123 self.used = True
124 if self.initial_state is not None:
125 self.revert_state(target)
126
127 def __eq__(self, other):
128 return self.effects == other.effects and self.intensities == other.intensities
129
130 def __lt__(self, other):
131 return sum(self.intensities.values()) < sum(other.intensities.values())
132
133 def __gt__(self, other):
134 return sum(self.intensities.values()) > sum(other.intensities.values())
135
136 def __hash__(self):
137 return hash(tuple(sorted(self.effects.items())))
138
139 def __getattr__(self, attr):
140 if attr.startswith('make_') and attr[5:] in self.effects:
141 effect_name = attr[5:]
142
143 def repeated_effect(target, intensity=self.effects[effect_name]):
144 for _ in range(intensity):
145 self.apply_effect(effect_name, target)
146
147 return repeated_effect
148
149 raise AttributeError(f"'Potion' object has no attribute '{attr}'")
150
151 def __call__(self, target):
152 self.apply_all_effects(target)
153
154
155class ГоспожатаПоХимия:
156 def __init__(self):
157 self.used_potions = set()
158 self.target = None
159
160 def apply(self, target, potion):
161 if potion in self.used_potions:
162 raise TypeError("Potion is depleted.")
163
164 if self.target is None:
165 self.target = target
166
167 effects_sorted = sorted(potion.intensities.keys(), key=lambda effect: sum(ord(char) for char in effect),
168 reverse=True)
169
170 for effect in effects_sorted:
171 if effect not in potion.applied_effects:
172 for _ in range(potion.intensities[effect]):
173 potion.apply_effect(effect, target)
174 potion.applied_effects.add(effect)
175
176 potion.used = True
177 self.used_potions.add(potion)
178
179 def tick(self):
180 potions_to_remove = set()
181
182 for potion in self.used_potions.copy():
183 potion.tick(self.target)
184
185 if potion.duration == 0:
186 potions_to_remove.add(potion)
187
188 for potion in potions_to_remove:
189 self.used_potions.remove(potion)
.......FF.FFF...EEEF
======================================================================
ERROR: test_ticking_immutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with immutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 424, in test_ticking_immutable
self._dimitrichka.apply(self._target, potion)
File "/tmp/solution.py", line 173, in apply
potion.apply_effect(effect, target)
File "/tmp/solution.py", line 22, in apply_effect
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.
======================================================================
ERROR: test_ticking_multiple_potions (test.TestГоспожатаПоХимия)
Test ticking after applying multiple potions which affect the same attribute.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 455, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion2)
File "/tmp/solution.py", line 162, in apply
raise TypeError("Potion is depleted.")
TypeError: Potion is depleted.
======================================================================
ERROR: test_ticking_multiple_targets (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 485, in test_ticking_multiple_targets
self._dimitrichka.apply(target1, potion1)
File "/tmp/solution.py", line 173, in apply
potion.apply_effect(effect, target)
File "/tmp/solution.py", line 22, in apply_effect
raise TypeError("Effect is depleted.")
TypeError: Effect is depleted.
======================================================================
FAIL: test_deprecation (test.TestPotionOperations)
Test deprecation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 259, in test_deprecation
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised
======================================================================
FAIL: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 120, in test_dilution
self.assertEqual(self._target.int_attr, 5)
AssertionError: 50 != 5
======================================================================
FAIL: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 168, in test_purification
with self.assertRaises(AttributeError):
AssertionError: AttributeError not raised
======================================================================
FAIL: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 245, in test_separation
self.assertEqual(self._target.int_attr, 50)
AssertionError: 500 != 50
======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 382, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: TypeError not raised
======================================================================
FAIL: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 446, in test_ticking_mutable
self.assertEqual(self._target.list_attr, [1, 2, 3])
AssertionError: Lists differ: [1, 2, 3, 4] != [1, 2, 3]
First list contains 1 additional elements.
First extra element 3:
4
- [1, 2, 3, 4]
? ---
+ [1, 2, 3]
----------------------------------------------------------------------
Ran 20 tests in 0.002s
FAILED (failures=6, errors=3)
Георги Кунчев
05.12.2023 11:39Може да работи и по повече таргети.
"дали би било правилно да пазя референция към target-a в класа ГоспожатаПоХимия" - би било, но имай предвид, че може да имаш повече от една госпожа, така че пази данните не в класа, а в инстанциите на класа. Е, ние, няма да тестваме с повече госпожи, но това би бил правилният вариант.
|
Габриела Костева
05.12.2023 11:23Имам въпрос по класа ГоспожатаПоХимия. Една инстанция на този клас само върху един target ли може да прилага отвари? Защото към момента не ми работи правилно метода tick, тъй като не мога да върна target-a в началното му състояние, защото нямам референция към него. И се чудех дали би било правилно да пазя референция към target-a в класа ГоспожатаПоХимия
|
Георги Кунчев
05.12.2023 09:29Чисто и ясно решение. Добро качество на кода.
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | 3 | ||||
4 | class Potion: | 4 | class Potion: | ||
5 | def __init__(self, effects, duration, intensities=None): | 5 | def __init__(self, effects, duration, intensities=None): | ||
6 | self.effects = effects | 6 | self.effects = effects | ||
7 | self.intensities = intensities or {effect: 1 for effect in effects} | 7 | self.intensities = intensities or {effect: 1 for effect in effects} | ||
8 | self.duration = duration | 8 | self.duration = duration | ||
9 | self.remaining_duration = duration | 9 | self.remaining_duration = duration | ||
10 | self.initial_state = None | 10 | self.initial_state = None | ||
11 | self.applied_effects = set() | 11 | self.applied_effects = set() | ||
12 | self.used = False | 12 | self.used = False | ||
13 | 13 | ||||
14 | for effect_name in effects: | 14 | for effect_name in effects: | ||
15 | setattr(self, effect_name, lambda target, name=effect_name: self.apply_effect(name, target)) | 15 | setattr(self, effect_name, lambda target, name=effect_name: self.apply_effect(name, target)) | ||
16 | 16 | ||||
17 | def apply_effect(self, effect, target, intensity=1): | 17 | def apply_effect(self, effect, target, intensity=1): | ||
18 | if self.used: | 18 | if self.used: | ||
19 | raise TypeError("Potion is now part of something bigger than itself.") | 19 | raise TypeError("Potion is now part of something bigger than itself.") | ||
20 | 20 | ||||
21 | if effect in self.applied_effects: | 21 | if effect in self.applied_effects: | ||
22 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
23 | 23 | ||||
24 | if effect in self.effects: | 24 | if effect in self.effects: | ||
25 | if effect in self.intensities: | 25 | if effect in self.intensities: | ||
26 | intensity = self.intensities[effect] | 26 | intensity = self.intensities[effect] | ||
27 | 27 | ||||
28 | if self.initial_state is None: | 28 | if self.initial_state is None: | ||
29 | self.initial_state = self.save_state(target) | 29 | self.initial_state = self.save_state(target) | ||
30 | 30 | ||||
31 | for _ in range(intensity): | 31 | for _ in range(intensity): | ||
32 | self.effects[effect](target) | 32 | self.effects[effect](target) | ||
33 | self.applied_effects.add(effect) | 33 | self.applied_effects.add(effect) | ||
34 | else: | 34 | else: | ||
35 | raise ValueError("Invalid effect name.") | 35 | raise ValueError("Invalid effect name.") | ||
36 | 36 | ||||
37 | def apply_all_effects(self, target): | 37 | def apply_all_effects(self, target): | ||
38 | for effect in self.effects: | 38 | for effect in self.effects: | ||
39 | self.apply_effect(effect, target) | 39 | self.apply_effect(effect, target) | ||
40 | 40 | ||||
41 | def save_state(self, target): | 41 | def save_state(self, target): | ||
42 | return vars(target).copy() | 42 | return vars(target).copy() | ||
43 | 43 | ||||
44 | def revert_state(self, target): | 44 | def revert_state(self, target): | ||
n | 45 | target = self.initial_state | n | 45 | if self.initial_state is not None: |
46 | for attr, value in self.initial_state.items(): | ||||
47 | setattr(target, attr, value) | ||||
48 | |||||
49 | def round_intensity(self, intensity, power): | ||||
50 | if not isinstance(power, int) or power < 1: | ||||
51 | return math.floor(intensity * power) if intensity <= power else math.ceil(intensity * power) | ||||
52 | else: | ||||
53 | return intensity * power | ||||
46 | 54 | ||||
47 | def __add__(self, other): | 55 | def __add__(self, other): | ||
48 | combined_effects = {} | 56 | combined_effects = {} | ||
49 | combined_intensities = {} | 57 | combined_intensities = {} | ||
50 | 58 | ||||
51 | for effect, intensity in self.intensities.items(): | 59 | for effect, intensity in self.intensities.items(): | ||
52 | combined_effects[effect] = self.effects[effect] | 60 | combined_effects[effect] = self.effects[effect] | ||
53 | combined_intensities[effect] = intensity | 61 | combined_intensities[effect] = intensity | ||
54 | 62 | ||||
55 | for effect, intensity in other.intensities.items(): | 63 | for effect, intensity in other.intensities.items(): | ||
56 | if effect in combined_effects: | 64 | if effect in combined_effects: | ||
57 | combined_intensities[effect] += intensity | 65 | combined_intensities[effect] += intensity | ||
58 | else: | 66 | else: | ||
59 | combined_effects[effect] = other.effects[effect] | 67 | combined_effects[effect] = other.effects[effect] | ||
60 | combined_intensities[effect] = intensity | 68 | combined_intensities[effect] = intensity | ||
61 | combined_duration = max(self.duration, other.duration) | 69 | combined_duration = max(self.duration, other.duration) | ||
62 | self.used = True | 70 | self.used = True | ||
63 | return Potion(combined_effects, combined_duration, intensities=combined_intensities) | 71 | return Potion(combined_effects, combined_duration, intensities=combined_intensities) | ||
64 | 72 | ||||
65 | def __mul__(self, power): | 73 | def __mul__(self, power): | ||
66 | updated_effects = {} | 74 | updated_effects = {} | ||
67 | updated_intensities = {} | 75 | updated_intensities = {} | ||
68 | 76 | ||||
n | 69 | if not isinstance(power, int) or power < 1: | n | ||
70 | for effect, intensity in self.intensities.items(): | 77 | for effect, intensity in self.intensities.items(): | ||
71 | diluted_intensity = math.floor(intensity * power) if intensity <= power else math.ceil( | ||||
72 | intensity * power) | ||||
73 | updated_effects[effect] = self.effects[effect] | 78 | updated_effects[effect] = self.effects[effect] | ||
74 | updated_intensities[effect] = diluted_intensity if diluted_intensity > 0 else 1 | ||||
75 | else: | ||||
76 | for effect, intensity in self.intensities.items(): | ||||
77 | updated_effects[effect] = self.effects[effect] | ||||
78 | updated_intensities[effect] = intensity * power | 79 | updated_intensities[effect] = self.round_intensity(intensity, power) | ||
80 | |||||
79 | self.used = True | 81 | self.used = True | ||
80 | return Potion(updated_effects, self.duration * power, intensities=updated_intensities) | 82 | return Potion(updated_effects, self.duration * power, intensities=updated_intensities) | ||
81 | 83 | ||||
82 | def __sub__(self, other): | 84 | def __sub__(self, other): | ||
83 | if not isinstance(other, Potion): | 85 | if not isinstance(other, Potion): | ||
84 | raise TypeError("Subtraction can only be performed with another Potion.") | 86 | raise TypeError("Subtraction can only be performed with another Potion.") | ||
85 | if not all(effect in self.effects for effect in other.effects): | 87 | if not all(effect in self.effects for effect in other.effects): | ||
86 | raise TypeError("Cannot subtract. 'self' does not contain all effects of 'other'.") | 88 | raise TypeError("Cannot subtract. 'self' does not contain all effects of 'other'.") | ||
87 | 89 | ||||
88 | subtracted_effects = {} | 90 | subtracted_effects = {} | ||
89 | subtracted_intensities = {} | 91 | subtracted_intensities = {} | ||
90 | subtracted_duration = self.duration | 92 | subtracted_duration = self.duration | ||
91 | 93 | ||||
92 | for effect, intensity in self.intensities.items(): | 94 | for effect, intensity in self.intensities.items(): | ||
93 | other_intensity = other.intensities.get(effect, 0) | 95 | other_intensity = other.intensities.get(effect, 0) | ||
94 | new_intensity = intensity - other_intensity | 96 | new_intensity = intensity - other_intensity | ||
n | 95 | if new_intensity > 0: | n | 97 | if new_intensity >= 0: |
98 | |||||
96 | subtracted_effects[effect] = self.effects[effect] | 99 | subtracted_effects[effect] = self.effects[effect] | ||
97 | subtracted_intensities[effect] = new_intensity | 100 | subtracted_intensities[effect] = new_intensity | ||
98 | elif new_intensity < 0: | 101 | elif new_intensity < 0: | ||
99 | raise TypeError("Negative intensity not allowed during subtraction.") | 102 | raise TypeError("Negative intensity not allowed during subtraction.") | ||
100 | 103 | ||||
101 | self.used = True | 104 | self.used = True | ||
102 | return Potion(subtracted_effects, subtracted_duration, intensities=subtracted_intensities) | 105 | return Potion(subtracted_effects, subtracted_duration, intensities=subtracted_intensities) | ||
103 | 106 | ||||
104 | def __truediv__(self, divisor): | 107 | def __truediv__(self, divisor): | ||
105 | if not isinstance(divisor, int) or divisor < 1: | 108 | if not isinstance(divisor, int) or divisor < 1: | ||
106 | raise ValueError("Divisor must be a natural number greater than zero.") | 109 | raise ValueError("Divisor must be a natural number greater than zero.") | ||
107 | 110 | ||||
108 | part_duration = self.duration / divisor | 111 | part_duration = self.duration / divisor | ||
109 | part_intensities = {name: round(intensity / divisor) if intensity > 0 else 0 for name, intensity in | 112 | part_intensities = {name: round(intensity / divisor) if intensity > 0 else 0 for name, intensity in | ||
110 | self.intensities.items()} | 113 | self.intensities.items()} | ||
111 | 114 | ||||
112 | parts = tuple(Potion(self.effects, part_duration, intensities=part_intensities) for _ in range(divisor)) | 115 | parts = tuple(Potion(self.effects, part_duration, intensities=part_intensities) for _ in range(divisor)) | ||
113 | self.used = True | 116 | self.used = True | ||
114 | return parts | 117 | return parts | ||
115 | 118 | ||||
n | 116 | def tick(self): | n | 119 | def tick(self, target): |
117 | if not self.used and self.duration > 0: | 120 | if self.duration > 0: | ||
118 | self.duration -= 1 | 121 | self.duration -= 1 | ||
119 | if self.duration == 0: | 122 | if self.duration == 0: | ||
120 | self.used = True | 123 | self.used = True | ||
n | 121 | if self.initial_state is not None and self.target is not None: | n | 124 | if self.initial_state is not None: |
122 | self.revert_state(self.target) | 125 | self.revert_state(target) | ||
123 | 126 | ||||
124 | def __eq__(self, other): | 127 | def __eq__(self, other): | ||
125 | return self.effects == other.effects and self.intensities == other.intensities | 128 | return self.effects == other.effects and self.intensities == other.intensities | ||
126 | 129 | ||||
127 | def __lt__(self, other): | 130 | def __lt__(self, other): | ||
128 | return sum(self.intensities.values()) < sum(other.intensities.values()) | 131 | return sum(self.intensities.values()) < sum(other.intensities.values()) | ||
129 | 132 | ||||
130 | def __gt__(self, other): | 133 | def __gt__(self, other): | ||
131 | return sum(self.intensities.values()) > sum(other.intensities.values()) | 134 | return sum(self.intensities.values()) > sum(other.intensities.values()) | ||
132 | 135 | ||||
133 | def __hash__(self): | 136 | def __hash__(self): | ||
134 | return hash(tuple(sorted(self.effects.items()))) | 137 | return hash(tuple(sorted(self.effects.items()))) | ||
135 | 138 | ||||
136 | def __getattr__(self, attr): | 139 | def __getattr__(self, attr): | ||
137 | if attr.startswith('make_') and attr[5:] in self.effects: | 140 | if attr.startswith('make_') and attr[5:] in self.effects: | ||
138 | effect_name = attr[5:] | 141 | effect_name = attr[5:] | ||
139 | 142 | ||||
140 | def repeated_effect(target, intensity=self.effects[effect_name]): | 143 | def repeated_effect(target, intensity=self.effects[effect_name]): | ||
141 | for _ in range(intensity): | 144 | for _ in range(intensity): | ||
142 | self.apply_effect(effect_name, target) | 145 | self.apply_effect(effect_name, target) | ||
143 | 146 | ||||
144 | return repeated_effect | 147 | return repeated_effect | ||
145 | 148 | ||||
146 | raise AttributeError(f"'Potion' object has no attribute '{attr}'") | 149 | raise AttributeError(f"'Potion' object has no attribute '{attr}'") | ||
147 | 150 | ||||
148 | def __call__(self, target): | 151 | def __call__(self, target): | ||
149 | self.apply_all_effects(target) | 152 | self.apply_all_effects(target) | ||
150 | 153 | ||||
151 | 154 | ||||
152 | class ГоспожатаПоХимия: | 155 | class ГоспожатаПоХимия: | ||
153 | def __init__(self): | 156 | def __init__(self): | ||
154 | self.used_potions = set() | 157 | self.used_potions = set() | ||
n | n | 158 | self.target = None | ||
155 | 159 | ||||
156 | def apply(self, target, potion): | 160 | def apply(self, target, potion): | ||
157 | if potion in self.used_potions: | 161 | if potion in self.used_potions: | ||
158 | raise TypeError("Potion is depleted.") | 162 | raise TypeError("Potion is depleted.") | ||
n | n | 163 | |||
164 | if self.target is None: | ||||
165 | self.target = target | ||||
159 | 166 | ||||
160 | effects_sorted = sorted(potion.intensities.keys(), key=lambda effect: sum(ord(char) for char in effect), | 167 | effects_sorted = sorted(potion.intensities.keys(), key=lambda effect: sum(ord(char) for char in effect), | ||
161 | reverse=True) | 168 | reverse=True) | ||
162 | 169 | ||||
163 | for effect in effects_sorted: | 170 | for effect in effects_sorted: | ||
164 | if effect not in potion.applied_effects: | 171 | if effect not in potion.applied_effects: | ||
165 | for _ in range(potion.intensities[effect]): | 172 | for _ in range(potion.intensities[effect]): | ||
166 | potion.apply_effect(effect, target) | 173 | potion.apply_effect(effect, target) | ||
167 | potion.applied_effects.add(effect) | 174 | potion.applied_effects.add(effect) | ||
168 | 175 | ||||
169 | potion.used = True | 176 | potion.used = True | ||
170 | self.used_potions.add(potion) | 177 | self.used_potions.add(potion) | ||
171 | 178 | ||||
172 | def tick(self): | 179 | def tick(self): | ||
n | n | 180 | potions_to_remove = set() | ||
181 | |||||
173 | for potion in self.used_potions.copy(): | 182 | for potion in self.used_potions.copy(): | ||
n | 174 | potion.tick() | n | 183 | potion.tick(self.target) |
175 | 184 | ||||
n | 176 | for potion in self.used_potions: | n | ||
177 | if potion.duration == 0: | 185 | if potion.duration == 0: | ||
t | t | 186 | potions_to_remove.add(potion) | ||
187 | |||||
188 | for potion in potions_to_remove: | ||||
178 | self.used_potions.remove(potion) | 189 | self.used_potions.remove(potion) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|