1import copy
2
3class Potion:
4
5 def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False):
6 self.depleted_effects = set()
7 self.effects = effects
8 self.duration = duration
9 self.sacrificed = sacrificed
10 self.depleted = depleted
11 self.intensities = {}
12 # make the effects methods and add intensity 1 for each name
13 for name, func in self.effects.items():
14 setattr(self, name, func)
15
16 if not intensities:
17 for name, func in self.effects.items():
18 self.intensities.update({name : 1})
19 else:
20 self.intensities = intensities
21
22 def __add__(self, other):
23 if self.depleted or other.depleted:
24 raise TypeError("Potion is depleted.")
25 if self.sacrificed or other.sacrificed:
26 raise TypeError("Potion is now part of something bigger than itself.")
27 self_active_effects = set(self.effects.keys()) - self.depleted_effects
28 other_active_effects = set(other.effects.keys()) - other.depleted_effects
29 #union the effects of both
30 updated_effects_keys = self_active_effects | other_active_effects
31 updated_effects = {}
32 updated_intensities = {}
33 # traverse both intensities dict-s and add to the updated one
34 for name, intensity in self.intensities.items():
35 if name in updated_effects_keys and name not in self.depleted_effects:
36 if updated_intensities.get(name):
37 updated_intensities[name] += intensity
38 else:
39 updated_intensities[name] = intensity
40
41 for name, intensity in other.intensities.items():
42 if name in updated_effects_keys and name not in other.depleted_effects:
43 if updated_intensities.get(name):
44 updated_intensities[name] += intensity
45 else:
46 updated_intensities[name] = intensity
47
48 for effect, func in self.effects.items():
49 if effect in updated_effects_keys:
50 updated_effects.update({effect : func})
51
52 for effect, func in other.effects.items():
53 if effect in updated_effects_keys:
54 updated_effects.update({effect : func})
55
56 self.sacrificed = True
57 other.sacrificed = True
58 return Potion(updated_effects, max(self.duration,other.duration), updated_intensities)
59
60 def __mul__(self,number):
61 if self.depleted:
62 raise TypeError("Potion is depleted.")
63 if self.sacrificed:
64 raise TypeError("Potion is now part of something bigger than itself.")
65 active_effects_keys= set(self.effects.keys()) - self.depleted_effects
66 updated_effects = {}
67 updated_intensities = {}
68 for effect in active_effects_keys:
69 updated_effects.update({effect : self.effects[effect]})
70 for name, intensity in self.intensities.items():
71 if name not in active_effects_keys:
72 continue
73 if intensity * number % 1 == 0.5:
74 updated_intensities.update({name : int(intensity * number)})
75 else:
76 updated_intensities.update({name : round(intensity * number)})
77
78 self.sacrificed=True
79 return Potion(updated_effects, self.duration, updated_intensities)
80
81 def __sub__(self, other):
82 if self.depleted or other.depleted:
83 raise TypeError("Potion is depleted.")
84 if self.sacrificed or other.sacrificed:
85 raise TypeError("Potion is now part of something bigger than itself.")
86 updated_effects = copy.deepcopy(self.effects)
87 updated_intensities = copy.deepcopy(self.intensities)
88 if not set(self.effects.keys()) >= set(other.effects.keys()):
89 raise TypeError("The effects differ in the potions.")
90 # traverse the effects_intensity pairs and if effect not present in the right remove it
91 for name, intensity in self.intensities.items():
92 if not name in set(other.effects.keys()) or name in other.depleted_effects:
93 continue
94 else:
95 diff = intensity - other.intensities[name]
96 if diff <= 0:
97 del updated_intensities[name]
98 del updated_effects[name]
99 continue
100 updated_intensities[name] = diff
101 # remove the effects and coresponding intensities of depleted effects in left potion
102 for effect in self.depleted_effects:
103 del updated_effects[effect]
104 del updated_intensities[effect]
105
106 self.sacrificed = True
107 other.sacrificed = True
108 return Potion(updated_effects, self.duration, updated_intensities)
109
110 def __truediv__(self, number):
111 if self.depleted:
112 raise TypeError("Potion is depleted.")
113 if self.sacrificed:
114 raise TypeError("Potion is now part of something bigger than itself.")
115 active_effects_keys= set(self.effects.keys()) - self.depleted_effects
116 updated_effects = {}
117 for effect in active_effects_keys:
118 updated_effects.update({effect : self.effects[effect]})
119 updated_intensities = {}
120 result = []
121 for name, intensity in self.intensities.items():
122 if name not in active_effects_keys:
123 continue
124 if intensity / number % 1 == 0.5:
125 updated_intensities.update({name : int(intensity / number)})
126 else:
127 updated_intensities.update({name : round(intensity / number)})
128
129 for times in range(number):
130 final_effects = copy.deepcopy(updated_effects)
131 final_intensities = copy.deepcopy(updated_intensities)
132 result.append(Potion(final_effects, self.duration, final_intensities))
133
134 self.sacrificed = True
135 return tuple(result)
136
137 def __eq__(self, other):
138 if self.depleted or other.depleted:
139 raise TypeError("Potion is depleted.")
140 if self.sacrificed or other.sacrificed:
141 raise TypeError("Potion is now part of something bigger than itself.")
142 if set(self.intensities.keys()) != set(other.intensities.keys()):
143 return False
144
145 for name, intensity in self.intensities.items():
146 if self.intensities[name] != other.intensities[name]:
147 return False
148 return True
149
150 def __gt__(self, other):
151 if self.depleted or other.depleted:
152 raise TypeError("Potion is depleted.")
153 if self.sacrificed or other.sacrificed:
154 raise TypeError("Potion is now part of something bigger than itself.")
155
156 sum_first = 0
157 sum_second = 0
158 for name, intensity in self.intensities.items():
159 sum_first += intensity
160 for name, intensity in other.intensities.items():
161 sum_second += intensity
162
163 return sum_first > sum_second
164
165 def __lt__(self, other):
166 if self.depleted or other.depleted:
167 raise TypeError("Potion is depleted.")
168 if self.sacrificed or other.sacrificed:
169 raise TypeError("Potion is now part of something bigger than itself.")
170
171 sum_first = 0
172 sum_second = 0
173 for name, intensity in self.intensities.items():
174 sum_first += intensity
175 for name, intensity in other.intensities.items():
176 sum_second += intensity
177
178 return sum_first < sum_second
179
180 @staticmethod
181 def effect_fortifier(func, times):
182 def effect_fortified(target):
183 for _ in range(times):
184 func(target)
185 return target
186 return effect_fortified
187
188 def __getattribute__(self, name):
189 # if it is not a method or not an effect no problem
190 if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name):
191 return object.__getattribute__(self, name)
192 # if potion has been used in something bigger raise the error
193 if object.__getattribute__(self, "sacrificed"):
194 raise TypeError("Potion is now part of something bigger than itself.")
195 # if potion has been applied already raise the error
196 if object.__getattribute__(self, "depleted"):
197 raise TypeError("Potion is depleted.")
198 # if it hasn't been used before add it to the list of depleted then allow it
199 if name not in object.__getattribute__(self, "depleted_effects"):
200 object.__getattribute__(self, "depleted_effects").add(name)
201 # fortified based on the current intensity
202 return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name])
203 # otherwise throw the error
204 raise TypeError("Effect is depleted.")
205
206
207class ГоспожатаПоХимия:
208
209 def __init__(self):
210 self.active_potions = []
211 self.affected_targets = []
212
213 @staticmethod
214 def molecular_mass(name):
215 mass = 0
216 for pos in range(0, len(name)):
217 mass += ord(name[pos])
218 return mass
219
220 def apply(self, target, potion):
221 # check if the potion is depleted first or has been sac-ed
222 if set(potion.effects.keys()) == potion.depleted_effects:
223 raise TypeError("Potion is depleted.")
224 if potion.sacrificed:
225 raise TypeError("Potion is now part of something bigger than itself.")
226
227 if potion.duration==0:
228 return None
229
230 remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects)
231 remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True)
232 #check if target has been affected already
233 seen = False
234 for target_id, original_data in self.affected_targets:
235 if id(target) == target_id:
236 seen = True
237 # save the original data otherwise
238 if not seen:
239 self.affected_targets.append((id(target), copy.deepcopy(target.__dict__)))
240
241 self.active_potions.append((copy.deepcopy(potion), target))
242
243 for effect in remaining_effects:
244 #apply the effect to the target
245 method=getattr(potion,effect)
246 method(target)
247 # deem the potion depleted after the process
248 potion.depleted = True
249
250 def tick(self):
251 for potion, target in self.active_potions:
252 potion.duration -= 1
253 if potion.duration == 0:
254 # Find the original information and normalize the target
255 for target_id, original_data in self.affected_targets:
256 if id(target) == target_id:
257 target.__dict__ = copy.deepcopy(original_data)
258 # Reapply effects for remaining active potions
259 for potion_2,target_2 in self.active_potions:
260 if potion_2.duration != 0 and target == target_2:
261 for effect in potion_2.effects:
262 method = getattr(potion_2, effect)
263 method(target)
264 # Remove the timed-out potion-target pairs from the list of active ones
265 self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0]
....................
----------------------------------------------------------------------
Ran 20 tests in 0.003s
OK
f | 1 | import copy | f | 1 | import copy |
2 | 2 | ||||
3 | class Potion: | 3 | class Potion: | ||
4 | 4 | ||||
5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | 5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | ||
6 | self.depleted_effects = set() | 6 | self.depleted_effects = set() | ||
7 | self.effects = effects | 7 | self.effects = effects | ||
8 | self.duration = duration | 8 | self.duration = duration | ||
9 | self.sacrificed = sacrificed | 9 | self.sacrificed = sacrificed | ||
10 | self.depleted = depleted | 10 | self.depleted = depleted | ||
11 | self.intensities = {} | 11 | self.intensities = {} | ||
12 | # make the effects methods and add intensity 1 for each name | 12 | # make the effects methods and add intensity 1 for each name | ||
13 | for name, func in self.effects.items(): | 13 | for name, func in self.effects.items(): | ||
14 | setattr(self, name, func) | 14 | setattr(self, name, func) | ||
15 | 15 | ||||
16 | if not intensities: | 16 | if not intensities: | ||
17 | for name, func in self.effects.items(): | 17 | for name, func in self.effects.items(): | ||
18 | self.intensities.update({name : 1}) | 18 | self.intensities.update({name : 1}) | ||
19 | else: | 19 | else: | ||
20 | self.intensities = intensities | 20 | self.intensities = intensities | ||
21 | 21 | ||||
22 | def __add__(self, other): | 22 | def __add__(self, other): | ||
23 | if self.depleted or other.depleted: | 23 | if self.depleted or other.depleted: | ||
24 | raise TypeError("Potion is depleted.") | 24 | raise TypeError("Potion is depleted.") | ||
25 | if self.sacrificed or other.sacrificed: | 25 | if self.sacrificed or other.sacrificed: | ||
26 | raise TypeError("Potion is now part of something bigger than itself.") | 26 | raise TypeError("Potion is now part of something bigger than itself.") | ||
27 | self_active_effects = set(self.effects.keys()) - self.depleted_effects | 27 | self_active_effects = set(self.effects.keys()) - self.depleted_effects | ||
28 | other_active_effects = set(other.effects.keys()) - other.depleted_effects | 28 | other_active_effects = set(other.effects.keys()) - other.depleted_effects | ||
29 | #union the effects of both | 29 | #union the effects of both | ||
30 | updated_effects_keys = self_active_effects | other_active_effects | 30 | updated_effects_keys = self_active_effects | other_active_effects | ||
31 | updated_effects = {} | 31 | updated_effects = {} | ||
32 | updated_intensities = {} | 32 | updated_intensities = {} | ||
33 | # traverse both intensities dict-s and add to the updated one | 33 | # traverse both intensities dict-s and add to the updated one | ||
34 | for name, intensity in self.intensities.items(): | 34 | for name, intensity in self.intensities.items(): | ||
35 | if name in updated_effects_keys and name not in self.depleted_effects: | 35 | if name in updated_effects_keys and name not in self.depleted_effects: | ||
36 | if updated_intensities.get(name): | 36 | if updated_intensities.get(name): | ||
37 | updated_intensities[name] += intensity | 37 | updated_intensities[name] += intensity | ||
38 | else: | 38 | else: | ||
39 | updated_intensities[name] = intensity | 39 | updated_intensities[name] = intensity | ||
40 | 40 | ||||
41 | for name, intensity in other.intensities.items(): | 41 | for name, intensity in other.intensities.items(): | ||
42 | if name in updated_effects_keys and name not in other.depleted_effects: | 42 | if name in updated_effects_keys and name not in other.depleted_effects: | ||
43 | if updated_intensities.get(name): | 43 | if updated_intensities.get(name): | ||
44 | updated_intensities[name] += intensity | 44 | updated_intensities[name] += intensity | ||
45 | else: | 45 | else: | ||
46 | updated_intensities[name] = intensity | 46 | updated_intensities[name] = intensity | ||
47 | 47 | ||||
48 | for effect, func in self.effects.items(): | 48 | for effect, func in self.effects.items(): | ||
49 | if effect in updated_effects_keys: | 49 | if effect in updated_effects_keys: | ||
50 | updated_effects.update({effect : func}) | 50 | updated_effects.update({effect : func}) | ||
51 | 51 | ||||
52 | for effect, func in other.effects.items(): | 52 | for effect, func in other.effects.items(): | ||
53 | if effect in updated_effects_keys: | 53 | if effect in updated_effects_keys: | ||
54 | updated_effects.update({effect : func}) | 54 | updated_effects.update({effect : func}) | ||
55 | 55 | ||||
56 | self.sacrificed = True | 56 | self.sacrificed = True | ||
57 | other.sacrificed = True | 57 | other.sacrificed = True | ||
58 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | 58 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | ||
59 | 59 | ||||
60 | def __mul__(self,number): | 60 | def __mul__(self,number): | ||
61 | if self.depleted: | 61 | if self.depleted: | ||
62 | raise TypeError("Potion is depleted.") | 62 | raise TypeError("Potion is depleted.") | ||
63 | if self.sacrificed: | 63 | if self.sacrificed: | ||
64 | raise TypeError("Potion is now part of something bigger than itself.") | 64 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 65 | updated_intensities = copy.deepcopy(self.intensities) | n | 65 | active_effects_keys= set(self.effects.keys()) - self.depleted_effects |
66 | updated_effects = {} | ||||
67 | updated_intensities = {} | ||||
68 | for effect in active_effects_keys: | ||||
69 | updated_effects.update({effect : self.effects[effect]}) | ||||
66 | for name, intensity in updated_intensities.items(): | 70 | for name, intensity in self.intensities.items(): | ||
71 | if name not in active_effects_keys: | ||||
72 | continue | ||||
67 | if intensity * number % 1 == 0.5: | 73 | if intensity * number % 1 == 0.5: | ||
n | 68 | updated_intensities[name] = int(intensity * number) | n | 74 | updated_intensities.update({name : int(intensity * number)}) |
69 | else: | 75 | else: | ||
n | 70 | updated_intensities[name] = round(intensity * number) | n | 76 | updated_intensities.update({name : round(intensity * number)}) |
71 | 77 | ||||
72 | self.sacrificed=True | 78 | self.sacrificed=True | ||
n | 73 | return Potion(self.effects, self.duration, updated_intensities) | n | 79 | return Potion(updated_effects, self.duration, updated_intensities) |
74 | 80 | ||||
75 | def __sub__(self, other): | 81 | def __sub__(self, other): | ||
76 | if self.depleted or other.depleted: | 82 | if self.depleted or other.depleted: | ||
77 | raise TypeError("Potion is depleted.") | 83 | raise TypeError("Potion is depleted.") | ||
78 | if self.sacrificed or other.sacrificed: | 84 | if self.sacrificed or other.sacrificed: | ||
79 | raise TypeError("Potion is now part of something bigger than itself.") | 85 | raise TypeError("Potion is now part of something bigger than itself.") | ||
80 | updated_effects = copy.deepcopy(self.effects) | 86 | updated_effects = copy.deepcopy(self.effects) | ||
81 | updated_intensities = copy.deepcopy(self.intensities) | 87 | updated_intensities = copy.deepcopy(self.intensities) | ||
82 | if not set(self.effects.keys()) >= set(other.effects.keys()): | 88 | if not set(self.effects.keys()) >= set(other.effects.keys()): | ||
83 | raise TypeError("The effects differ in the potions.") | 89 | raise TypeError("The effects differ in the potions.") | ||
84 | # traverse the effects_intensity pairs and if effect not present in the right remove it | 90 | # traverse the effects_intensity pairs and if effect not present in the right remove it | ||
85 | for name, intensity in self.intensities.items(): | 91 | for name, intensity in self.intensities.items(): | ||
n | 86 | if not name in set(other.effects.keys()): | n | 92 | if not name in set(other.effects.keys()) or name in other.depleted_effects: |
87 | continue | 93 | continue | ||
88 | else: | 94 | else: | ||
89 | diff = intensity - other.intensities[name] | 95 | diff = intensity - other.intensities[name] | ||
n | 90 | if diff < 0: | n | 96 | if diff <= 0: |
91 | del updated_intensities[name] | 97 | del updated_intensities[name] | ||
92 | del updated_effects[name] | 98 | del updated_effects[name] | ||
93 | continue | 99 | continue | ||
94 | updated_intensities[name] = diff | 100 | updated_intensities[name] = diff | ||
95 | # remove the effects and coresponding intensities of depleted effects in left potion | 101 | # remove the effects and coresponding intensities of depleted effects in left potion | ||
96 | for effect in self.depleted_effects: | 102 | for effect in self.depleted_effects: | ||
97 | del updated_effects[effect] | 103 | del updated_effects[effect] | ||
98 | del updated_intensities[effect] | 104 | del updated_intensities[effect] | ||
99 | 105 | ||||
100 | self.sacrificed = True | 106 | self.sacrificed = True | ||
101 | other.sacrificed = True | 107 | other.sacrificed = True | ||
102 | return Potion(updated_effects, self.duration, updated_intensities) | 108 | return Potion(updated_effects, self.duration, updated_intensities) | ||
103 | 109 | ||||
104 | def __truediv__(self, number): | 110 | def __truediv__(self, number): | ||
105 | if self.depleted: | 111 | if self.depleted: | ||
106 | raise TypeError("Potion is depleted.") | 112 | raise TypeError("Potion is depleted.") | ||
107 | if self.sacrificed: | 113 | if self.sacrificed: | ||
108 | raise TypeError("Potion is now part of something bigger than itself.") | 114 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 109 | n | 115 | active_effects_keys= set(self.effects.keys()) - self.depleted_effects | |
110 | updated_intensities = copy.deepcopy(self.intensities) | 116 | updated_effects = {} | ||
117 | for effect in active_effects_keys: | ||||
118 | updated_effects.update({effect : self.effects[effect]}) | ||||
119 | updated_intensities = {} | ||||
111 | result = [] | 120 | result = [] | ||
n | 112 | n | |||
113 | for name, intensity in self.intensities.items(): | 121 | for name, intensity in self.intensities.items(): | ||
n | n | 122 | if name not in active_effects_keys: | ||
123 | continue | ||||
114 | if intensity / number % 1 == 0.5: | 124 | if intensity / number % 1 == 0.5: | ||
n | 115 | updated_intensities[name] = int(intensity / number) | n | 125 | updated_intensities.update({name : int(intensity / number)}) |
116 | else: | 126 | else: | ||
n | 117 | updated_intensities[name] = round(intensity / number) | n | 127 | updated_intensities.update({name : round(intensity / number)}) |
118 | 128 | ||||
119 | for times in range(number): | 129 | for times in range(number): | ||
n | 120 | final_effects = copy.deepcopy(self.effects) | n | 130 | final_effects = copy.deepcopy(updated_effects) |
121 | final_intensities = copy.deepcopy(updated_intensities) | 131 | final_intensities = copy.deepcopy(updated_intensities) | ||
122 | result.append(Potion(final_effects, self.duration, final_intensities)) | 132 | result.append(Potion(final_effects, self.duration, final_intensities)) | ||
123 | 133 | ||||
124 | self.sacrificed = True | 134 | self.sacrificed = True | ||
125 | return tuple(result) | 135 | return tuple(result) | ||
126 | 136 | ||||
127 | def __eq__(self, other): | 137 | def __eq__(self, other): | ||
128 | if self.depleted or other.depleted: | 138 | if self.depleted or other.depleted: | ||
129 | raise TypeError("Potion is depleted.") | 139 | raise TypeError("Potion is depleted.") | ||
130 | if self.sacrificed or other.sacrificed: | 140 | if self.sacrificed or other.sacrificed: | ||
131 | raise TypeError("Potion is now part of something bigger than itself.") | 141 | raise TypeError("Potion is now part of something bigger than itself.") | ||
132 | if set(self.intensities.keys()) != set(other.intensities.keys()): | 142 | if set(self.intensities.keys()) != set(other.intensities.keys()): | ||
133 | return False | 143 | return False | ||
134 | 144 | ||||
135 | for name, intensity in self.intensities.items(): | 145 | for name, intensity in self.intensities.items(): | ||
136 | if self.intensities[name] != other.intensities[name]: | 146 | if self.intensities[name] != other.intensities[name]: | ||
137 | return False | 147 | return False | ||
138 | return True | 148 | return True | ||
139 | 149 | ||||
140 | def __gt__(self, other): | 150 | def __gt__(self, other): | ||
141 | if self.depleted or other.depleted: | 151 | if self.depleted or other.depleted: | ||
142 | raise TypeError("Potion is depleted.") | 152 | raise TypeError("Potion is depleted.") | ||
143 | if self.sacrificed or other.sacrificed: | 153 | if self.sacrificed or other.sacrificed: | ||
144 | raise TypeError("Potion is now part of something bigger than itself.") | 154 | raise TypeError("Potion is now part of something bigger than itself.") | ||
145 | 155 | ||||
146 | sum_first = 0 | 156 | sum_first = 0 | ||
147 | sum_second = 0 | 157 | sum_second = 0 | ||
148 | for name, intensity in self.intensities.items(): | 158 | for name, intensity in self.intensities.items(): | ||
149 | sum_first += intensity | 159 | sum_first += intensity | ||
150 | for name, intensity in other.intensities.items(): | 160 | for name, intensity in other.intensities.items(): | ||
151 | sum_second += intensity | 161 | sum_second += intensity | ||
152 | 162 | ||||
153 | return sum_first > sum_second | 163 | return sum_first > sum_second | ||
154 | 164 | ||||
155 | def __lt__(self, other): | 165 | def __lt__(self, other): | ||
156 | if self.depleted or other.depleted: | 166 | if self.depleted or other.depleted: | ||
157 | raise TypeError("Potion is depleted.") | 167 | raise TypeError("Potion is depleted.") | ||
158 | if self.sacrificed or other.sacrificed: | 168 | if self.sacrificed or other.sacrificed: | ||
159 | raise TypeError("Potion is now part of something bigger than itself.") | 169 | raise TypeError("Potion is now part of something bigger than itself.") | ||
160 | 170 | ||||
161 | sum_first = 0 | 171 | sum_first = 0 | ||
162 | sum_second = 0 | 172 | sum_second = 0 | ||
163 | for name, intensity in self.intensities.items(): | 173 | for name, intensity in self.intensities.items(): | ||
164 | sum_first += intensity | 174 | sum_first += intensity | ||
165 | for name, intensity in other.intensities.items(): | 175 | for name, intensity in other.intensities.items(): | ||
166 | sum_second += intensity | 176 | sum_second += intensity | ||
167 | 177 | ||||
168 | return sum_first < sum_second | 178 | return sum_first < sum_second | ||
169 | 179 | ||||
170 | @staticmethod | 180 | @staticmethod | ||
171 | def effect_fortifier(func, times): | 181 | def effect_fortifier(func, times): | ||
172 | def effect_fortified(target): | 182 | def effect_fortified(target): | ||
173 | for _ in range(times): | 183 | for _ in range(times): | ||
174 | func(target) | 184 | func(target) | ||
175 | return target | 185 | return target | ||
176 | return effect_fortified | 186 | return effect_fortified | ||
177 | 187 | ||||
178 | def __getattribute__(self, name): | 188 | def __getattribute__(self, name): | ||
179 | # if it is not a method or not an effect no problem | 189 | # if it is not a method or not an effect no problem | ||
180 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | 190 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | ||
181 | return object.__getattribute__(self, name) | 191 | return object.__getattribute__(self, name) | ||
182 | # if potion has been used in something bigger raise the error | 192 | # if potion has been used in something bigger raise the error | ||
183 | if object.__getattribute__(self, "sacrificed"): | 193 | if object.__getattribute__(self, "sacrificed"): | ||
184 | raise TypeError("Potion is now part of something bigger than itself.") | 194 | raise TypeError("Potion is now part of something bigger than itself.") | ||
185 | # if potion has been applied already raise the error | 195 | # if potion has been applied already raise the error | ||
186 | if object.__getattribute__(self, "depleted"): | 196 | if object.__getattribute__(self, "depleted"): | ||
187 | raise TypeError("Potion is depleted.") | 197 | raise TypeError("Potion is depleted.") | ||
188 | # if it hasn't been used before add it to the list of depleted then allow it | 198 | # if it hasn't been used before add it to the list of depleted then allow it | ||
189 | if name not in object.__getattribute__(self, "depleted_effects"): | 199 | if name not in object.__getattribute__(self, "depleted_effects"): | ||
190 | object.__getattribute__(self, "depleted_effects").add(name) | 200 | object.__getattribute__(self, "depleted_effects").add(name) | ||
191 | # fortified based on the current intensity | 201 | # fortified based on the current intensity | ||
192 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | 202 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | ||
193 | # otherwise throw the error | 203 | # otherwise throw the error | ||
194 | raise TypeError("Effect is depleted.") | 204 | raise TypeError("Effect is depleted.") | ||
195 | 205 | ||||
196 | 206 | ||||
197 | class ГоспожатаПоХимия: | 207 | class ГоспожатаПоХимия: | ||
198 | 208 | ||||
199 | def __init__(self): | 209 | def __init__(self): | ||
200 | self.active_potions = [] | 210 | self.active_potions = [] | ||
201 | self.affected_targets = [] | 211 | self.affected_targets = [] | ||
202 | 212 | ||||
203 | @staticmethod | 213 | @staticmethod | ||
204 | def molecular_mass(name): | 214 | def molecular_mass(name): | ||
205 | mass = 0 | 215 | mass = 0 | ||
206 | for pos in range(0, len(name)): | 216 | for pos in range(0, len(name)): | ||
207 | mass += ord(name[pos]) | 217 | mass += ord(name[pos]) | ||
208 | return mass | 218 | return mass | ||
209 | 219 | ||||
210 | def apply(self, target, potion): | 220 | def apply(self, target, potion): | ||
211 | # check if the potion is depleted first or has been sac-ed | 221 | # check if the potion is depleted first or has been sac-ed | ||
212 | if set(potion.effects.keys()) == potion.depleted_effects: | 222 | if set(potion.effects.keys()) == potion.depleted_effects: | ||
213 | raise TypeError("Potion is depleted.") | 223 | raise TypeError("Potion is depleted.") | ||
214 | if potion.sacrificed: | 224 | if potion.sacrificed: | ||
215 | raise TypeError("Potion is now part of something bigger than itself.") | 225 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | n | 226 | |||
227 | if potion.duration==0: | ||||
228 | return None | ||||
216 | 229 | ||||
217 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | 230 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | ||
218 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | 231 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | ||
219 | #check if target has been affected already | 232 | #check if target has been affected already | ||
220 | seen = False | 233 | seen = False | ||
221 | for target_id, original_data in self.affected_targets: | 234 | for target_id, original_data in self.affected_targets: | ||
222 | if id(target) == target_id: | 235 | if id(target) == target_id: | ||
223 | seen = True | 236 | seen = True | ||
224 | # save the original data otherwise | 237 | # save the original data otherwise | ||
225 | if not seen: | 238 | if not seen: | ||
226 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | 239 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | ||
227 | 240 | ||||
228 | self.active_potions.append((copy.deepcopy(potion), target)) | 241 | self.active_potions.append((copy.deepcopy(potion), target)) | ||
229 | 242 | ||||
230 | for effect in remaining_effects: | 243 | for effect in remaining_effects: | ||
231 | #apply the effect to the target | 244 | #apply the effect to the target | ||
t | 232 | potion.effects[effect](target) | t | 245 | method=getattr(potion,effect) |
246 | method(target) | ||||
233 | # deem the potion depleted after the process | 247 | # deem the potion depleted after the process | ||
234 | potion.depleted = True | 248 | potion.depleted = True | ||
235 | 249 | ||||
236 | def tick(self): | 250 | def tick(self): | ||
237 | for potion, target in self.active_potions: | 251 | for potion, target in self.active_potions: | ||
238 | potion.duration -= 1 | 252 | potion.duration -= 1 | ||
239 | if potion.duration == 0: | 253 | if potion.duration == 0: | ||
240 | # Find the original information and normalize the target | 254 | # Find the original information and normalize the target | ||
241 | for target_id, original_data in self.affected_targets: | 255 | for target_id, original_data in self.affected_targets: | ||
242 | if id(target) == target_id: | 256 | if id(target) == target_id: | ||
243 | target.__dict__ = copy.deepcopy(original_data) | 257 | target.__dict__ = copy.deepcopy(original_data) | ||
244 | # Reapply effects for remaining active potions | 258 | # Reapply effects for remaining active potions | ||
245 | for potion_2,target_2 in self.active_potions: | 259 | for potion_2,target_2 in self.active_potions: | ||
246 | if potion_2.duration != 0 and target == target_2: | 260 | if potion_2.duration != 0 and target == target_2: | ||
247 | for effect in potion_2.effects: | 261 | for effect in potion_2.effects: | ||
248 | method = getattr(potion_2, effect) | 262 | method = getattr(potion_2, effect) | ||
249 | method(target) | 263 | method(target) | ||
250 | # Remove the timed-out potion-target pairs from the list of active ones | 264 | # Remove the timed-out potion-target pairs from the list of active ones | ||
251 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] | 265 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import copy | f | 1 | import copy |
2 | 2 | ||||
3 | class Potion: | 3 | class Potion: | ||
4 | 4 | ||||
5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | 5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | ||
n | 6 | setattr(self, "depleted_effects", set()) | n | 6 | self.depleted_effects = set() |
7 | self.effects = effects | 7 | self.effects = effects | ||
8 | self.duration = duration | 8 | self.duration = duration | ||
9 | self.sacrificed = sacrificed | 9 | self.sacrificed = sacrificed | ||
10 | self.depleted = depleted | 10 | self.depleted = depleted | ||
11 | self.intensities = {} | 11 | self.intensities = {} | ||
12 | # make the effects methods and add intensity 1 for each name | 12 | # make the effects methods and add intensity 1 for each name | ||
13 | for name, func in self.effects.items(): | 13 | for name, func in self.effects.items(): | ||
14 | setattr(self, name, func) | 14 | setattr(self, name, func) | ||
15 | 15 | ||||
16 | if not intensities: | 16 | if not intensities: | ||
17 | for name, func in self.effects.items(): | 17 | for name, func in self.effects.items(): | ||
18 | self.intensities.update({name : 1}) | 18 | self.intensities.update({name : 1}) | ||
19 | else: | 19 | else: | ||
n | 20 | self.intensities=intensities | n | 20 | self.intensities = intensities |
21 | 21 | ||||
22 | def __add__(self, other): | 22 | def __add__(self, other): | ||
n | 23 | n | |||
24 | if self.depleted or other.depleted: | 23 | if self.depleted or other.depleted: | ||
25 | raise TypeError("Potion is depleted.") | 24 | raise TypeError("Potion is depleted.") | ||
n | 26 | n | |||
27 | if self.sacrificed or other.sacrificed: | 25 | if self.sacrificed or other.sacrificed: | ||
28 | raise TypeError("Potion is now part of something bigger than itself.") | 26 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 29 | n | |||
30 | self_active_effects = set(self.effects.keys())-self.depleted_effects | 27 | self_active_effects = set(self.effects.keys()) - self.depleted_effects | ||
31 | other_active_effects = set(other.effects.keys())-other.depleted_effects | 28 | other_active_effects = set(other.effects.keys()) - other.depleted_effects | ||
32 | #union the effects of both | 29 | #union the effects of both | ||
33 | updated_effects_keys = self_active_effects | other_active_effects | 30 | updated_effects_keys = self_active_effects | other_active_effects | ||
34 | updated_effects = {} | 31 | updated_effects = {} | ||
35 | updated_intensities = {} | 32 | updated_intensities = {} | ||
36 | # traverse both intensities dict-s and add to the updated one | 33 | # traverse both intensities dict-s and add to the updated one | ||
n | 37 | for name,intensity in self.intensities.items(): | n | 34 | for name, intensity in self.intensities.items(): |
38 | if name in updated_effects_keys and name not in self.depleted_effects: | 35 | if name in updated_effects_keys and name not in self.depleted_effects: | ||
39 | if updated_intensities.get(name): | 36 | if updated_intensities.get(name): | ||
40 | updated_intensities[name] += intensity | 37 | updated_intensities[name] += intensity | ||
41 | else: | 38 | else: | ||
42 | updated_intensities[name] = intensity | 39 | updated_intensities[name] = intensity | ||
43 | 40 | ||||
44 | for name, intensity in other.intensities.items(): | 41 | for name, intensity in other.intensities.items(): | ||
45 | if name in updated_effects_keys and name not in other.depleted_effects: | 42 | if name in updated_effects_keys and name not in other.depleted_effects: | ||
46 | if updated_intensities.get(name): | 43 | if updated_intensities.get(name): | ||
47 | updated_intensities[name] += intensity | 44 | updated_intensities[name] += intensity | ||
48 | else: | 45 | else: | ||
49 | updated_intensities[name] = intensity | 46 | updated_intensities[name] = intensity | ||
50 | 47 | ||||
51 | for effect, func in self.effects.items(): | 48 | for effect, func in self.effects.items(): | ||
52 | if effect in updated_effects_keys: | 49 | if effect in updated_effects_keys: | ||
53 | updated_effects.update({effect : func}) | 50 | updated_effects.update({effect : func}) | ||
n | 54 | n | 51 | ||
55 | for effect, func in other.effects.items(): | 52 | for effect, func in other.effects.items(): | ||
56 | if effect in updated_effects_keys: | 53 | if effect in updated_effects_keys: | ||
57 | updated_effects.update({effect : func}) | 54 | updated_effects.update({effect : func}) | ||
n | 58 | n | 55 | ||
59 | self.sacrificed = True | 56 | self.sacrificed = True | ||
60 | other.sacrificed = True | 57 | other.sacrificed = True | ||
61 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | 58 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | ||
n | 62 | n | 59 | ||
63 | def __mul__(self,number): | 60 | def __mul__(self,number): | ||
n | 64 | n | |||
65 | if self.depleted: | 61 | if self.depleted: | ||
66 | raise TypeError("Potion is depleted.") | 62 | raise TypeError("Potion is depleted.") | ||
n | 67 | n | |||
68 | if self.sacrificed: | 63 | if self.sacrificed: | ||
69 | raise TypeError("Potion is now part of something bigger than itself.") | 64 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 70 | n | |||
71 | updated_intensities = copy.deepcopy(self.intensities) | 65 | updated_intensities = copy.deepcopy(self.intensities) | ||
72 | for name, intensity in updated_intensities.items(): | 66 | for name, intensity in updated_intensities.items(): | ||
73 | if intensity * number % 1 == 0.5: | 67 | if intensity * number % 1 == 0.5: | ||
74 | updated_intensities[name] = int(intensity * number) | 68 | updated_intensities[name] = int(intensity * number) | ||
75 | else: | 69 | else: | ||
76 | updated_intensities[name] = round(intensity * number) | 70 | updated_intensities[name] = round(intensity * number) | ||
n | n | 71 | |||
77 | self.sacrificed=True | 72 | self.sacrificed=True | ||
78 | return Potion(self.effects, self.duration, updated_intensities) | 73 | return Potion(self.effects, self.duration, updated_intensities) | ||
n | 79 | n | 74 | ||
80 | def __sub__(self, other): | 75 | def __sub__(self, other): | ||
81 | if self.depleted or other.depleted: | 76 | if self.depleted or other.depleted: | ||
82 | raise TypeError("Potion is depleted.") | 77 | raise TypeError("Potion is depleted.") | ||
n | 83 | n | |||
84 | if self.sacrificed or other.sacrificed: | 78 | if self.sacrificed or other.sacrificed: | ||
85 | raise TypeError("Potion is now part of something bigger than itself.") | 79 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 86 | n | |||
87 | updated_effects = copy.deepcopy(self.effects) | 80 | updated_effects = copy.deepcopy(self.effects) | ||
88 | updated_intensities = copy.deepcopy(self.intensities) | 81 | updated_intensities = copy.deepcopy(self.intensities) | ||
89 | if not set(self.effects.keys()) >= set(other.effects.keys()): | 82 | if not set(self.effects.keys()) >= set(other.effects.keys()): | ||
n | 90 | raise TypeError("The effects differ in the poitions.") | n | 83 | raise TypeError("The effects differ in the potions.") |
91 | 84 | # traverse the effects_intensity pairs and if effect not present in the right remove it | |||
92 | for name, intensity in self.intensities.items(): | 85 | for name, intensity in self.intensities.items(): | ||
n | 93 | diff = intensity - other.intensities[name] | n | 86 | if not name in set(other.effects.keys()): |
94 | if diff < 0: | ||||
95 | del updated_intensities[name] | ||||
96 | del updated_effects[name] | ||||
97 | continue | 87 | continue | ||
n | n | 88 | else: | ||
89 | diff = intensity - other.intensities[name] | ||||
90 | if diff < 0: | ||||
91 | del updated_intensities[name] | ||||
92 | del updated_effects[name] | ||||
93 | continue | ||||
98 | updated_intensities[name] = diff | 94 | updated_intensities[name] = diff | ||
99 | |||||
100 | # remove the effects and coresponding intensities of depleted effects in left potion | 95 | # remove the effects and coresponding intensities of depleted effects in left potion | ||
101 | for effect in self.depleted_effects: | 96 | for effect in self.depleted_effects: | ||
102 | del updated_effects[effect] | 97 | del updated_effects[effect] | ||
103 | del updated_intensities[effect] | 98 | del updated_intensities[effect] | ||
104 | 99 | ||||
105 | self.sacrificed = True | 100 | self.sacrificed = True | ||
106 | other.sacrificed = True | 101 | other.sacrificed = True | ||
107 | return Potion(updated_effects, self.duration, updated_intensities) | 102 | return Potion(updated_effects, self.duration, updated_intensities) | ||
n | 108 | n | 103 | ||
109 | def __truediv__(self, number): | 104 | def __truediv__(self, number): | ||
110 | if self.depleted: | 105 | if self.depleted: | ||
111 | raise TypeError("Potion is depleted.") | 106 | raise TypeError("Potion is depleted.") | ||
n | 112 | n | |||
113 | if self.sacrificed: | 107 | if self.sacrificed: | ||
114 | raise TypeError("Potion is now part of something bigger than itself.") | 108 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 115 | n | 109 | ||
116 | updated_intensities = copy.deepcopy(self.intensities) | 110 | updated_intensities = copy.deepcopy(self.intensities) | ||
117 | result = [] | 111 | result = [] | ||
118 | 112 | ||||
119 | for name, intensity in self.intensities.items(): | 113 | for name, intensity in self.intensities.items(): | ||
n | 120 | if (intensity / number) % 1 == 0.5: | n | 114 | if intensity / number % 1 == 0.5: |
121 | updated_intensities[name] = int(intensity / number) | 115 | updated_intensities[name] = int(intensity / number) | ||
122 | else: | 116 | else: | ||
123 | updated_intensities[name] = round(intensity / number) | 117 | updated_intensities[name] = round(intensity / number) | ||
124 | 118 | ||||
n | 125 | for times in range(0, number): | n | 119 | for times in range(number): |
126 | final_effects = copy.deepcopy(self.effects) | 120 | final_effects = copy.deepcopy(self.effects) | ||
127 | final_intensities = copy.deepcopy(updated_intensities) | 121 | final_intensities = copy.deepcopy(updated_intensities) | ||
128 | result.append(Potion(final_effects, self.duration, final_intensities)) | 122 | result.append(Potion(final_effects, self.duration, final_intensities)) | ||
n | 129 | n | 123 | ||
130 | self.sacrificed = True | 124 | self.sacrificed = True | ||
n | 131 | n | |||
132 | return tuple(result) | 125 | return tuple(result) | ||
n | 133 | n | 126 | ||
134 | def __eq__(self, other): | 127 | def __eq__(self, other): | ||
135 | if self.depleted or other.depleted: | 128 | if self.depleted or other.depleted: | ||
136 | raise TypeError("Potion is depleted.") | 129 | raise TypeError("Potion is depleted.") | ||
n | 137 | n | |||
138 | if self.sacrificed or other.sacrificed: | 130 | if self.sacrificed or other.sacrificed: | ||
139 | raise TypeError("Potion is now part of something bigger than itself.") | 131 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 140 | n | |||
141 | if set(self.intensities.keys()) != set(other.intensities.keys()): | 132 | if set(self.intensities.keys()) != set(other.intensities.keys()): | ||
142 | return False | 133 | return False | ||
n | 143 | n | 134 | ||
144 | for name, intensity in self.intensities.items(): | 135 | for name, intensity in self.intensities.items(): | ||
145 | if self.intensities[name] != other.intensities[name]: | 136 | if self.intensities[name] != other.intensities[name]: | ||
146 | return False | 137 | return False | ||
n | 147 | n | |||
148 | return True | 138 | return True | ||
n | 149 | n | 139 | ||
150 | def __gt__(self, other): | 140 | def __gt__(self, other): | ||
151 | if self.depleted or other.depleted: | 141 | if self.depleted or other.depleted: | ||
152 | raise TypeError("Potion is depleted.") | 142 | raise TypeError("Potion is depleted.") | ||
n | 153 | n | |||
154 | if self.sacrificed or other.sacrificed: | 143 | if self.sacrificed or other.sacrificed: | ||
155 | raise TypeError("Potion is now part of something bigger than itself.") | 144 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 156 | n | 145 | ||
157 | sum_first = 0 | 146 | sum_first = 0 | ||
158 | sum_second = 0 | 147 | sum_second = 0 | ||
159 | for name, intensity in self.intensities.items(): | 148 | for name, intensity in self.intensities.items(): | ||
160 | sum_first += intensity | 149 | sum_first += intensity | ||
n | 161 | n | |||
162 | for name, intensity in other.intensities.items(): | 150 | for name, intensity in other.intensities.items(): | ||
163 | sum_second += intensity | 151 | sum_second += intensity | ||
n | 164 | n | 152 | ||
165 | return sum_first > sum_second | 153 | return sum_first > sum_second | ||
n | 166 | n | 154 | ||
167 | # strictly less == not strictly greater | ||||
168 | def __lt__(self, other): | 155 | def __lt__(self, other): | ||
n | 169 | return not self.__gt__(other) | n | 156 | if self.depleted or other.depleted: |
157 | raise TypeError("Potion is depleted.") | ||||
158 | if self.sacrificed or other.sacrificed: | ||||
159 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
160 | |||||
161 | sum_first = 0 | ||||
162 | sum_second = 0 | ||||
163 | for name, intensity in self.intensities.items(): | ||||
164 | sum_first += intensity | ||||
165 | for name, intensity in other.intensities.items(): | ||||
166 | sum_second += intensity | ||||
167 | |||||
168 | return sum_first < sum_second | ||||
170 | 169 | ||||
171 | @staticmethod | 170 | @staticmethod | ||
172 | def effect_fortifier(func, times): | 171 | def effect_fortifier(func, times): | ||
173 | def effect_fortified(target): | 172 | def effect_fortified(target): | ||
n | 174 | for _ in range(0, times): | n | 173 | for _ in range(times): |
175 | func(target) | 174 | func(target) | ||
176 | return target | 175 | return target | ||
177 | return effect_fortified | 176 | return effect_fortified | ||
n | 178 | n | |||
179 | 177 | ||||
180 | def __getattribute__(self, name): | 178 | def __getattribute__(self, name): | ||
181 | # if it is not a method or not an effect no problem | 179 | # if it is not a method or not an effect no problem | ||
182 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | 180 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | ||
183 | return object.__getattribute__(self, name) | 181 | return object.__getattribute__(self, name) | ||
184 | # if potion has been used in something bigger raise the error | 182 | # if potion has been used in something bigger raise the error | ||
185 | if object.__getattribute__(self, "sacrificed"): | 183 | if object.__getattribute__(self, "sacrificed"): | ||
186 | raise TypeError("Potion is now part of something bigger than itself.") | 184 | raise TypeError("Potion is now part of something bigger than itself.") | ||
187 | # if potion has been applied already raise the error | 185 | # if potion has been applied already raise the error | ||
188 | if object.__getattribute__(self, "depleted"): | 186 | if object.__getattribute__(self, "depleted"): | ||
189 | raise TypeError("Potion is depleted.") | 187 | raise TypeError("Potion is depleted.") | ||
190 | # if it hasn't been used before add it to the list of depleted then allow it | 188 | # if it hasn't been used before add it to the list of depleted then allow it | ||
191 | if name not in object.__getattribute__(self, "depleted_effects"): | 189 | if name not in object.__getattribute__(self, "depleted_effects"): | ||
192 | object.__getattribute__(self, "depleted_effects").add(name) | 190 | object.__getattribute__(self, "depleted_effects").add(name) | ||
193 | # fortified based on the current intensity | 191 | # fortified based on the current intensity | ||
194 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | 192 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | ||
195 | # otherwise throw the error | 193 | # otherwise throw the error | ||
196 | raise TypeError("Effect is depleted.") | 194 | raise TypeError("Effect is depleted.") | ||
197 | 195 | ||||
198 | 196 | ||||
199 | class ГоспожатаПоХимия: | 197 | class ГоспожатаПоХимия: | ||
200 | 198 | ||||
201 | def __init__(self): | 199 | def __init__(self): | ||
202 | self.active_potions = [] | 200 | self.active_potions = [] | ||
203 | self.affected_targets = [] | 201 | self.affected_targets = [] | ||
204 | 202 | ||||
205 | @staticmethod | 203 | @staticmethod | ||
206 | def molecular_mass(name): | 204 | def molecular_mass(name): | ||
207 | mass = 0 | 205 | mass = 0 | ||
208 | for pos in range(0, len(name)): | 206 | for pos in range(0, len(name)): | ||
209 | mass += ord(name[pos]) | 207 | mass += ord(name[pos]) | ||
210 | return mass | 208 | return mass | ||
211 | 209 | ||||
212 | def apply(self, target, potion): | 210 | def apply(self, target, potion): | ||
213 | # check if the potion is depleted first or has been sac-ed | 211 | # check if the potion is depleted first or has been sac-ed | ||
214 | if set(potion.effects.keys()) == potion.depleted_effects: | 212 | if set(potion.effects.keys()) == potion.depleted_effects: | ||
215 | raise TypeError("Potion is depleted.") | 213 | raise TypeError("Potion is depleted.") | ||
n | 216 | n | |||
217 | if potion.sacrificed: | 214 | if potion.sacrificed: | ||
218 | raise TypeError("Potion is now part of something bigger than itself.") | 215 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 219 | n | 216 | ||
220 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | 217 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | ||
n | 221 | n | |||
222 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | 218 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | ||
n | 223 | n | |||
224 | #check if target has been affected already | 219 | #check if target has been affected already | ||
n | 225 | n | |||
226 | seen = False | 220 | seen = False | ||
n | 227 | n | |||
228 | for target_id, original_data in self.affected_targets: | 221 | for target_id, original_data in self.affected_targets: | ||
n | 229 | if id(target) == target_id: | n | 222 | if id(target) == target_id: |
230 | seen = True | 223 | seen = True | ||
231 | # save the original data otherwise | 224 | # save the original data otherwise | ||
232 | if not seen: | 225 | if not seen: | ||
233 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | 226 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | ||
234 | 227 | ||||
235 | self.active_potions.append((copy.deepcopy(potion), target)) | 228 | self.active_potions.append((copy.deepcopy(potion), target)) | ||
236 | 229 | ||||
237 | for effect in remaining_effects: | 230 | for effect in remaining_effects: | ||
238 | #apply the effect to the target | 231 | #apply the effect to the target | ||
239 | potion.effects[effect](target) | 232 | potion.effects[effect](target) | ||
n | 240 | n | |||
241 | # deem the potion depleted after the process | 233 | # deem the potion depleted after the process | ||
242 | potion.depleted = True | 234 | potion.depleted = True | ||
243 | 235 | ||||
244 | def tick(self): | 236 | def tick(self): | ||
245 | for potion, target in self.active_potions: | 237 | for potion, target in self.active_potions: | ||
246 | potion.duration -= 1 | 238 | potion.duration -= 1 | ||
247 | if potion.duration == 0: | 239 | if potion.duration == 0: | ||
248 | # Find the original information and normalize the target | 240 | # Find the original information and normalize the target | ||
249 | for target_id, original_data in self.affected_targets: | 241 | for target_id, original_data in self.affected_targets: | ||
250 | if id(target) == target_id: | 242 | if id(target) == target_id: | ||
251 | target.__dict__ = copy.deepcopy(original_data) | 243 | target.__dict__ = copy.deepcopy(original_data) | ||
n | 252 | n | |||
253 | # Reapply effects for remaining active potions | 244 | # Reapply effects for remaining active potions | ||
254 | for potion_2,target_2 in self.active_potions: | 245 | for potion_2,target_2 in self.active_potions: | ||
255 | if potion_2.duration != 0 and target == target_2: | 246 | if potion_2.duration != 0 and target == target_2: | ||
256 | for effect in potion_2.effects: | 247 | for effect in potion_2.effects: | ||
n | 257 | method=getattr(potion_2,effect) | n | 248 | method = getattr(potion_2, effect) |
258 | method(target) | 249 | method(target) | ||
t | 259 | t | |||
260 | # Remove the timed-out potion-target pairs from the list of active ones | 250 | # Remove the timed-out potion-target pairs from the list of active ones | ||
261 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] | 251 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import copy | f | 1 | import copy |
2 | 2 | ||||
3 | class Potion: | 3 | class Potion: | ||
4 | 4 | ||||
5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | 5 | def __init__(self, effects, duration, intensities=False, sacrificed=False, depleted=False): | ||
6 | setattr(self, "depleted_effects", set()) | 6 | setattr(self, "depleted_effects", set()) | ||
7 | self.effects = effects | 7 | self.effects = effects | ||
8 | self.duration = duration | 8 | self.duration = duration | ||
9 | self.sacrificed = sacrificed | 9 | self.sacrificed = sacrificed | ||
10 | self.depleted = depleted | 10 | self.depleted = depleted | ||
11 | self.intensities = {} | 11 | self.intensities = {} | ||
12 | # make the effects methods and add intensity 1 for each name | 12 | # make the effects methods and add intensity 1 for each name | ||
13 | for name, func in self.effects.items(): | 13 | for name, func in self.effects.items(): | ||
14 | setattr(self, name, func) | 14 | setattr(self, name, func) | ||
15 | 15 | ||||
16 | if not intensities: | 16 | if not intensities: | ||
17 | for name, func in self.effects.items(): | 17 | for name, func in self.effects.items(): | ||
18 | self.intensities.update({name : 1}) | 18 | self.intensities.update({name : 1}) | ||
19 | else: | 19 | else: | ||
20 | self.intensities=intensities | 20 | self.intensities=intensities | ||
21 | 21 | ||||
22 | def __add__(self, other): | 22 | def __add__(self, other): | ||
23 | 23 | ||||
24 | if self.depleted or other.depleted: | 24 | if self.depleted or other.depleted: | ||
25 | raise TypeError("Potion is depleted.") | 25 | raise TypeError("Potion is depleted.") | ||
n | n | 26 | |||
27 | if self.sacrificed or other.sacrificed: | ||||
28 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
26 | 29 | ||||
27 | self_active_effects = set(self.effects.keys())-self.depleted_effects | 30 | self_active_effects = set(self.effects.keys())-self.depleted_effects | ||
28 | other_active_effects = set(other.effects.keys())-other.depleted_effects | 31 | other_active_effects = set(other.effects.keys())-other.depleted_effects | ||
29 | #union the effects of both | 32 | #union the effects of both | ||
30 | updated_effects_keys = self_active_effects | other_active_effects | 33 | updated_effects_keys = self_active_effects | other_active_effects | ||
31 | updated_effects = {} | 34 | updated_effects = {} | ||
32 | updated_intensities = {} | 35 | updated_intensities = {} | ||
33 | # traverse both intensities dict-s and add to the updated one | 36 | # traverse both intensities dict-s and add to the updated one | ||
34 | for name,intensity in self.intensities.items(): | 37 | for name,intensity in self.intensities.items(): | ||
35 | if name in updated_effects_keys and name not in self.depleted_effects: | 38 | if name in updated_effects_keys and name not in self.depleted_effects: | ||
36 | if updated_intensities.get(name): | 39 | if updated_intensities.get(name): | ||
37 | updated_intensities[name] += intensity | 40 | updated_intensities[name] += intensity | ||
38 | else: | 41 | else: | ||
39 | updated_intensities[name] = intensity | 42 | updated_intensities[name] = intensity | ||
40 | 43 | ||||
41 | for name, intensity in other.intensities.items(): | 44 | for name, intensity in other.intensities.items(): | ||
42 | if name in updated_effects_keys and name not in other.depleted_effects: | 45 | if name in updated_effects_keys and name not in other.depleted_effects: | ||
43 | if updated_intensities.get(name): | 46 | if updated_intensities.get(name): | ||
44 | updated_intensities[name] += intensity | 47 | updated_intensities[name] += intensity | ||
45 | else: | 48 | else: | ||
46 | updated_intensities[name] = intensity | 49 | updated_intensities[name] = intensity | ||
47 | 50 | ||||
48 | for effect, func in self.effects.items(): | 51 | for effect, func in self.effects.items(): | ||
49 | if effect in updated_effects_keys: | 52 | if effect in updated_effects_keys: | ||
50 | updated_effects.update({effect : func}) | 53 | updated_effects.update({effect : func}) | ||
51 | 54 | ||||
52 | for effect, func in other.effects.items(): | 55 | for effect, func in other.effects.items(): | ||
53 | if effect in updated_effects_keys: | 56 | if effect in updated_effects_keys: | ||
54 | updated_effects.update({effect : func}) | 57 | updated_effects.update({effect : func}) | ||
55 | 58 | ||||
56 | self.sacrificed = True | 59 | self.sacrificed = True | ||
57 | other.sacrificed = True | 60 | other.sacrificed = True | ||
58 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | 61 | return Potion(updated_effects, max(self.duration,other.duration), updated_intensities) | ||
59 | 62 | ||||
60 | def __mul__(self,number): | 63 | def __mul__(self,number): | ||
61 | 64 | ||||
62 | if self.depleted: | 65 | if self.depleted: | ||
63 | raise TypeError("Potion is depleted.") | 66 | raise TypeError("Potion is depleted.") | ||
n | n | 67 | |||
68 | if self.sacrificed: | ||||
69 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
64 | 70 | ||||
65 | updated_intensities = copy.deepcopy(self.intensities) | 71 | updated_intensities = copy.deepcopy(self.intensities) | ||
66 | for name, intensity in updated_intensities.items(): | 72 | for name, intensity in updated_intensities.items(): | ||
67 | if intensity * number % 1 == 0.5: | 73 | if intensity * number % 1 == 0.5: | ||
68 | updated_intensities[name] = int(intensity * number) | 74 | updated_intensities[name] = int(intensity * number) | ||
69 | else: | 75 | else: | ||
70 | updated_intensities[name] = round(intensity * number) | 76 | updated_intensities[name] = round(intensity * number) | ||
71 | self.sacrificed=True | 77 | self.sacrificed=True | ||
72 | return Potion(self.effects, self.duration, updated_intensities) | 78 | return Potion(self.effects, self.duration, updated_intensities) | ||
73 | 79 | ||||
74 | def __sub__(self, other): | 80 | def __sub__(self, other): | ||
75 | if self.depleted or other.depleted: | 81 | if self.depleted or other.depleted: | ||
76 | raise TypeError("Potion is depleted.") | 82 | raise TypeError("Potion is depleted.") | ||
n | n | 83 | |||
84 | if self.sacrificed or other.sacrificed: | ||||
85 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
77 | 86 | ||||
78 | updated_effects = copy.deepcopy(self.effects) | 87 | updated_effects = copy.deepcopy(self.effects) | ||
79 | updated_intensities = copy.deepcopy(self.intensities) | 88 | updated_intensities = copy.deepcopy(self.intensities) | ||
80 | if not set(self.effects.keys()) >= set(other.effects.keys()): | 89 | if not set(self.effects.keys()) >= set(other.effects.keys()): | ||
81 | raise TypeError("The effects differ in the poitions.") | 90 | raise TypeError("The effects differ in the poitions.") | ||
82 | 91 | ||||
83 | for name, intensity in self.intensities.items(): | 92 | for name, intensity in self.intensities.items(): | ||
84 | diff = intensity - other.intensities[name] | 93 | diff = intensity - other.intensities[name] | ||
85 | if diff < 0: | 94 | if diff < 0: | ||
86 | del updated_intensities[name] | 95 | del updated_intensities[name] | ||
87 | del updated_effects[name] | 96 | del updated_effects[name] | ||
88 | continue | 97 | continue | ||
89 | updated_intensities[name] = diff | 98 | updated_intensities[name] = diff | ||
90 | 99 | ||||
91 | # remove the effects and coresponding intensities of depleted effects in left potion | 100 | # remove the effects and coresponding intensities of depleted effects in left potion | ||
92 | for effect in self.depleted_effects: | 101 | for effect in self.depleted_effects: | ||
93 | del updated_effects[effect] | 102 | del updated_effects[effect] | ||
94 | del updated_intensities[effect] | 103 | del updated_intensities[effect] | ||
95 | 104 | ||||
96 | self.sacrificed = True | 105 | self.sacrificed = True | ||
97 | other.sacrificed = True | 106 | other.sacrificed = True | ||
98 | return Potion(updated_effects, self.duration, updated_intensities) | 107 | return Potion(updated_effects, self.duration, updated_intensities) | ||
99 | 108 | ||||
100 | def __truediv__(self, number): | 109 | def __truediv__(self, number): | ||
101 | if self.depleted: | 110 | if self.depleted: | ||
102 | raise TypeError("Potion is depleted.") | 111 | raise TypeError("Potion is depleted.") | ||
103 | 112 | ||||
n | n | 113 | if self.sacrificed: | ||
114 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
115 | |||||
104 | updated_intensities = copy.deepcopy(self.intensities) | 116 | updated_intensities = copy.deepcopy(self.intensities) | ||
105 | result = [] | 117 | result = [] | ||
106 | 118 | ||||
107 | for name, intensity in self.intensities.items(): | 119 | for name, intensity in self.intensities.items(): | ||
108 | if (intensity / number) % 1 == 0.5: | 120 | if (intensity / number) % 1 == 0.5: | ||
109 | updated_intensities[name] = int(intensity / number) | 121 | updated_intensities[name] = int(intensity / number) | ||
110 | else: | 122 | else: | ||
111 | updated_intensities[name] = round(intensity / number) | 123 | updated_intensities[name] = round(intensity / number) | ||
112 | 124 | ||||
113 | for times in range(0, number): | 125 | for times in range(0, number): | ||
114 | final_effects = copy.deepcopy(self.effects) | 126 | final_effects = copy.deepcopy(self.effects) | ||
115 | final_intensities = copy.deepcopy(updated_intensities) | 127 | final_intensities = copy.deepcopy(updated_intensities) | ||
116 | result.append(Potion(final_effects, self.duration, final_intensities)) | 128 | result.append(Potion(final_effects, self.duration, final_intensities)) | ||
117 | 129 | ||||
118 | self.sacrificed = True | 130 | self.sacrificed = True | ||
119 | 131 | ||||
120 | return tuple(result) | 132 | return tuple(result) | ||
121 | 133 | ||||
122 | def __eq__(self, other): | 134 | def __eq__(self, other): | ||
123 | if self.depleted or other.depleted: | 135 | if self.depleted or other.depleted: | ||
124 | raise TypeError("Potion is depleted.") | 136 | raise TypeError("Potion is depleted.") | ||
125 | 137 | ||||
n | n | 138 | if self.sacrificed or other.sacrificed: | ||
139 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
140 | |||||
126 | if set(self.intensities.keys()) != set(other.intensities.keys()): | 141 | if set(self.intensities.keys()) != set(other.intensities.keys()): | ||
127 | return False | 142 | return False | ||
128 | 143 | ||||
129 | for name, intensity in self.intensities.items(): | 144 | for name, intensity in self.intensities.items(): | ||
130 | if self.intensities[name] != other.intensities[name]: | 145 | if self.intensities[name] != other.intensities[name]: | ||
131 | return False | 146 | return False | ||
132 | 147 | ||||
133 | return True | 148 | return True | ||
134 | 149 | ||||
135 | def __gt__(self, other): | 150 | def __gt__(self, other): | ||
136 | if self.depleted or other.depleted: | 151 | if self.depleted or other.depleted: | ||
137 | raise TypeError("Potion is depleted.") | 152 | raise TypeError("Potion is depleted.") | ||
t | t | 153 | |||
154 | if self.sacrificed or other.sacrificed: | ||||
155 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
138 | 156 | ||||
139 | sum_first = 0 | 157 | sum_first = 0 | ||
140 | sum_second = 0 | 158 | sum_second = 0 | ||
141 | for name, intensity in self.intensities.items(): | 159 | for name, intensity in self.intensities.items(): | ||
142 | sum_first += intensity | 160 | sum_first += intensity | ||
143 | 161 | ||||
144 | for name, intensity in other.intensities.items(): | 162 | for name, intensity in other.intensities.items(): | ||
145 | sum_second += intensity | 163 | sum_second += intensity | ||
146 | 164 | ||||
147 | return sum_first > sum_second | 165 | return sum_first > sum_second | ||
148 | 166 | ||||
149 | # strictly less == not strictly greater | 167 | # strictly less == not strictly greater | ||
150 | def __lt__(self, other): | 168 | def __lt__(self, other): | ||
151 | return not self.__gt__(other) | 169 | return not self.__gt__(other) | ||
152 | 170 | ||||
153 | @staticmethod | 171 | @staticmethod | ||
154 | def effect_fortifier(func, times): | 172 | def effect_fortifier(func, times): | ||
155 | def effect_fortified(target): | 173 | def effect_fortified(target): | ||
156 | for _ in range(0, times): | 174 | for _ in range(0, times): | ||
157 | func(target) | 175 | func(target) | ||
158 | return target | 176 | return target | ||
159 | return effect_fortified | 177 | return effect_fortified | ||
160 | 178 | ||||
161 | 179 | ||||
162 | def __getattribute__(self, name): | 180 | def __getattribute__(self, name): | ||
163 | # if it is not a method or not an effect no problem | 181 | # if it is not a method or not an effect no problem | ||
164 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | 182 | if not callable(object.__getattribute__(self, name)) or not object.__getattribute__(self, "effects").get(name): | ||
165 | return object.__getattribute__(self, name) | 183 | return object.__getattribute__(self, name) | ||
166 | # if potion has been used in something bigger raise the error | 184 | # if potion has been used in something bigger raise the error | ||
167 | if object.__getattribute__(self, "sacrificed"): | 185 | if object.__getattribute__(self, "sacrificed"): | ||
168 | raise TypeError("Potion is now part of something bigger than itself.") | 186 | raise TypeError("Potion is now part of something bigger than itself.") | ||
169 | # if potion has been applied already raise the error | 187 | # if potion has been applied already raise the error | ||
170 | if object.__getattribute__(self, "depleted"): | 188 | if object.__getattribute__(self, "depleted"): | ||
171 | raise TypeError("Potion is depleted.") | 189 | raise TypeError("Potion is depleted.") | ||
172 | # if it hasn't been used before add it to the list of depleted then allow it | 190 | # if it hasn't been used before add it to the list of depleted then allow it | ||
173 | if name not in object.__getattribute__(self, "depleted_effects"): | 191 | if name not in object.__getattribute__(self, "depleted_effects"): | ||
174 | object.__getattribute__(self, "depleted_effects").add(name) | 192 | object.__getattribute__(self, "depleted_effects").add(name) | ||
175 | # fortified based on the current intensity | 193 | # fortified based on the current intensity | ||
176 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | 194 | return Potion.effect_fortifier(object.__getattribute__(self, name), object.__getattribute__(self, "intensities")[name]) | ||
177 | # otherwise throw the error | 195 | # otherwise throw the error | ||
178 | raise TypeError("Effect is depleted.") | 196 | raise TypeError("Effect is depleted.") | ||
179 | 197 | ||||
180 | 198 | ||||
181 | class ГоспожатаПоХимия: | 199 | class ГоспожатаПоХимия: | ||
182 | 200 | ||||
183 | def __init__(self): | 201 | def __init__(self): | ||
184 | self.active_potions = [] | 202 | self.active_potions = [] | ||
185 | self.affected_targets = [] | 203 | self.affected_targets = [] | ||
186 | 204 | ||||
187 | @staticmethod | 205 | @staticmethod | ||
188 | def molecular_mass(name): | 206 | def molecular_mass(name): | ||
189 | mass = 0 | 207 | mass = 0 | ||
190 | for pos in range(0, len(name)): | 208 | for pos in range(0, len(name)): | ||
191 | mass += ord(name[pos]) | 209 | mass += ord(name[pos]) | ||
192 | return mass | 210 | return mass | ||
193 | 211 | ||||
194 | def apply(self, target, potion): | 212 | def apply(self, target, potion): | ||
195 | # check if the potion is depleted first or has been sac-ed | 213 | # check if the potion is depleted first or has been sac-ed | ||
196 | if set(potion.effects.keys()) == potion.depleted_effects: | 214 | if set(potion.effects.keys()) == potion.depleted_effects: | ||
197 | raise TypeError("Potion is depleted.") | 215 | raise TypeError("Potion is depleted.") | ||
198 | 216 | ||||
199 | if potion.sacrificed: | 217 | if potion.sacrificed: | ||
200 | raise TypeError("Potion is now part of something bigger than itself.") | 218 | raise TypeError("Potion is now part of something bigger than itself.") | ||
201 | 219 | ||||
202 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | 220 | remaining_effects = list(set(potion.effects.keys()) - potion.depleted_effects) | ||
203 | 221 | ||||
204 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | 222 | remaining_effects.sort(key=ГоспожатаПоХимия.molecular_mass, reverse=True) | ||
205 | 223 | ||||
206 | #check if target has been affected already | 224 | #check if target has been affected already | ||
207 | 225 | ||||
208 | seen = False | 226 | seen = False | ||
209 | 227 | ||||
210 | for target_id, original_data in self.affected_targets: | 228 | for target_id, original_data in self.affected_targets: | ||
211 | if id(target) == target_id: | 229 | if id(target) == target_id: | ||
212 | seen = True | 230 | seen = True | ||
213 | # save the original data otherwise | 231 | # save the original data otherwise | ||
214 | if not seen: | 232 | if not seen: | ||
215 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | 233 | self.affected_targets.append((id(target), copy.deepcopy(target.__dict__))) | ||
216 | 234 | ||||
217 | self.active_potions.append((copy.deepcopy(potion), target)) | 235 | self.active_potions.append((copy.deepcopy(potion), target)) | ||
218 | 236 | ||||
219 | for effect in remaining_effects: | 237 | for effect in remaining_effects: | ||
220 | #apply the effect to the target | 238 | #apply the effect to the target | ||
221 | potion.effects[effect](target) | 239 | potion.effects[effect](target) | ||
222 | 240 | ||||
223 | # deem the potion depleted after the process | 241 | # deem the potion depleted after the process | ||
224 | potion.depleted = True | 242 | potion.depleted = True | ||
225 | 243 | ||||
226 | def tick(self): | 244 | def tick(self): | ||
227 | for potion, target in self.active_potions: | 245 | for potion, target in self.active_potions: | ||
228 | potion.duration -= 1 | 246 | potion.duration -= 1 | ||
229 | if potion.duration == 0: | 247 | if potion.duration == 0: | ||
230 | # Find the original information and normalize the target | 248 | # Find the original information and normalize the target | ||
231 | for target_id, original_data in self.affected_targets: | 249 | for target_id, original_data in self.affected_targets: | ||
232 | if id(target) == target_id: | 250 | if id(target) == target_id: | ||
233 | target.__dict__ = copy.deepcopy(original_data) | 251 | target.__dict__ = copy.deepcopy(original_data) | ||
234 | 252 | ||||
235 | # Reapply effects for remaining active potions | 253 | # Reapply effects for remaining active potions | ||
236 | for potion_2,target_2 in self.active_potions: | 254 | for potion_2,target_2 in self.active_potions: | ||
237 | if potion_2.duration != 0 and target == target_2: | 255 | if potion_2.duration != 0 and target == target_2: | ||
238 | for effect in potion_2.effects: | 256 | for effect in potion_2.effects: | ||
239 | method=getattr(potion_2,effect) | 257 | method=getattr(potion_2,effect) | ||
240 | method(target) | 258 | method(target) | ||
241 | 259 | ||||
242 | # Remove the timed-out potion-target pairs from the list of active ones | 260 | # Remove the timed-out potion-target pairs from the list of active ones | ||
243 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] | 261 | self.active_potions = [(potion, target) for potion, target in self.active_potions if potion.duration != 0] |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|