1import copy
2import math
3
4class Effect:
5 def __init__(self, name, func, intensity=1):
6 self.name = name
7 self.func = func
8 self.is_used = False
9 self.intensity = intensity
10 self.is_active = True
11
12 @property
13 def molecular_mass(self):
14 return sum([ord(letter) for letter in self.name])
15
16 def __call__(self, target, is_continuing=False):
17 if not self.is_used or is_continuing:
18 for _ in range(self.intensity):
19 self.func(target)
20 self.is_used = True
21 else:
22 raise TypeError("Effect is depleted.")
23
24
25class Potion:
26 def __init__(self, effects, duration=2, intensities=None):
27 self.effects = {}
28 self.is_itself = True
29 self.is_used = False
30
31 for effect_name in effects:
32 effect_func = effects[effect_name]
33 effects[effect_name].is_called = False
34
35 self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name])
36
37 self.duration = duration
38
39 def effect(self, target, is_continuing=False):
40 if not is_continuing and not self.is_itself:
41 raise TypeError("Potion is now part of something bigger than itself.")
42
43 if self.is_used and not is_continuing:
44 raise TypeError("Potion is depleted.")
45
46 self.is_used = True
47 self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True))
48
49 for effect in self.effects.values():
50 if not effect.is_active:
51 continue
52 effect(target, True)
53
54 def __getattr__(self, effect_name):
55 if effect_name not in self.effects:
56 raise AttributeError("Effect is not in potion.")
57
58 if self.is_used:
59 raise TypeError("Potion is depleted.")
60
61 if not self.effects[effect_name].is_active:
62 raise TypeError("Effect is depleted.")
63
64 if not self.is_itself:
65 raise TypeError("Potion is now part of something bigger than itself.")
66
67 self.effects[effect_name].is_active = False
68
69 return self.effects[effect_name]
70
71 def __add__(self, other):
72 """Combining two potions."""
73 if not self.is_itself or not other.is_itself:
74 raise TypeError("Potion is now part of something bigger than itself.")
75
76 if self.is_used:
77 raise TypeError("Potion is depleted.")
78
79 effects = {}
80 intensities = {}
81
82 for effect_name, effect in self.effects.items():
83 if not effect.is_active:
84 continue
85 effects[effect_name] = effect.func
86 intensities[effect_name] = effect.intensity
87
88 for effect_name, effect in other.effects.items():
89 if not effect.is_active:
90 continue
91
92 if effect_name not in effects:
93 effects[effect_name] = effect.func
94 intensities[effect_name] = effect.intensity
95 else:
96 intensities[effect_name] += effect.intensity
97
98 self.is_itself = False
99 other.is_itself = False
100
101 return Potion(effects, max(self.duration, other.duration), intensities)
102
103 def __mul__(self, number):
104 """Potentiation of two potions."""
105 if not self.is_itself:
106 raise TypeError("Potion is now part of something bigger than itself.")
107
108 if self.is_used:
109 raise TypeError("Potion is depleted.")
110
111 effects = {}
112 intensities = {}
113
114 for effect_name, effect in self.effects.items():
115 if not effect.is_active:
116 continue
117
118 intensities[effect_name] = effect.intensity * number
119
120 if intensities[effect_name] % 1 <= 0.5:
121 intensities[effect_name] = math.floor(intensities[effect_name])
122 else:
123 intensities[effect_name] = math.ceil(intensities[effect_name])
124
125 effects[effect_name] = effect.func
126
127 self.is_itself = False
128 return Potion(effects, self.duration, intensities)
129
130 def __sub__(self, other):
131 """Purification of two potions."""
132 if not self.is_itself or not other.is_itself:
133 raise TypeError("Potion is now part of something bigger than itself.")
134
135 if self.is_used:
136 raise TypeError("Potion is depleted.")
137
138 for effect in other.effects:
139 if effect not in self.effects:
140 raise TypeError("Effect is not in potion.")
141
142 effects = {}
143 intensities = {}
144
145 for effect_name, effect in self.effects.items():
146 intensities[effect_name] = effect.intensity
147 effects[effect_name] = effect.func
148
149 if not effect.is_active:
150 intensities[effect_name] = max(intensities[effect_name] - 1, 0)
151
152 for effect in other.effects:
153 intensities[effect] -= other.effects[effect].intensity
154
155 if not other.effects[effect].is_active and other.effects[effect].intensity > 0:
156 intensities[effect] += 1
157
158 if intensities[effect] <= 0:
159 effects.pop(effect)
160 intensities.pop(effect)
161
162 self.is_itself = False
163 other.is_itself = False
164 return Potion(effects, self.duration, intensities)
165
166 def __truediv__(self, number:int):
167 """Dividing two potions."""
168 if not self.is_itself:
169 raise TypeError("Potion is now part of something bigger than itself.")
170
171 if self.is_used:
172 raise TypeError("Potion is depleted.")
173
174 effects = {}
175 intensities = {}
176
177 for effect_name, effect in self.effects.items():
178 if not effect.is_active:
179 continue
180
181 intensities[effect_name] = int(effect.intensity) / number
182 effects[effect_name] = effect.func
183
184 if intensities[effect_name] % 1 <= 0.5:
185 intensities[effect_name] = math.floor(intensities[effect_name])
186 else:
187 intensities[effect_name] = math.ceil(intensities[effect_name])
188
189 self.is_itself = False
190 return tuple(Potion(effects, self.duration, intensities) for _ in range(number))
191
192 def __eq__(self, other):
193
194 if not self.is_itself or not other.is_itself:
195 raise TypeError("Potion is now part of something bigger than itself.")
196
197 if self.is_used:
198 raise TypeError("Potion is depleted.")
199
200 for effect in self.effects:
201 if effect not in other.effects:
202 return False
203
204 if not self.effects[effect].is_active:
205 self.effects[effect].intensity = 0
206
207 if not other.effects[effect].is_active:
208 other.effects[effect].intensity = 0
209
210 if self.effects[effect].intensity != other.effects[effect].intensity:
211 return False
212
213 for effect in other.effects:
214 if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity:
215 return False
216
217 return True
218
219 def __lt__(self, other):
220
221 if not self.is_itself or not other.is_itself:
222 raise TypeError("Potion is now part of something bigger than itself.")
223
224 if self.is_used:
225 raise TypeError("Potion is depleted.")
226
227
228 return sum(effect.intensity if effect.is_active else 0 for effect in self.effects.values()) < sum(effect.intensity if effect.is_active else 0 for effect in other.effects.values())
229
230 def __dir__(self):
231 return list(self.effects.keys())
232
233
234class Target:
235 def __init__(self, target):
236 self.curr_target = target
237 self.original = copy.deepcopy(target.__dict__)
238
239 @property
240 def original_state(self):
241 return copy.deepcopy(self.original)
242
243 def back_to_original(self):
244 self.curr_target.__dict__ = self.original_state
245
246 def __eq__(self, other):
247 if isinstance(other, Target):
248 return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__
249 return False
250
251 def __hash__(self):
252 return hash(self.curr_target.__class__.__name__)
253
254class ГоспожатаПоХимия:
255 def __init__(self):
256 self.active_potions = {}
257
258 def apply(self, target_obj, potion):
259 target = Target(target_obj)
260
261 if self.active_potions.get(target) is None:
262 self.active_potions[target] = []
263
264 if potion.duration > 0:
265 potion.effect(target.curr_target)
266 self.active_potions[target].append([potion.duration - 1, potion])
267
268 def tick(self):
269 for target in self.active_potions:
270 target.back_to_original()
271 to_remove = []
272
273 for curr in self.active_potions[target]:
274 remaining_time, potion = curr
275 curr[0] -= 1
276
277 if remaining_time <= 0:
278 to_remove.append(curr)
279 else:
280 potion.effect(target.curr_target, True)
281
282 for curr in to_remove:
283 self.active_potions[target].remove(curr)
.................FF.
======================================================================
FAIL: 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 471, in test_ticking_multiple_potions
self.assertEqual(self._target.int_attr, 5)
AssertionError: 50 != 5
======================================================================
FAIL: 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 490, in test_ticking_multiple_targets
self.assertEqual(target1.int_attr, 5)
AssertionError: 50 != 5
----------------------------------------------------------------------
Ran 20 tests in 0.002s
FAILED (failures=2)
| f | 1 | import copy | f | 1 | import copy |
| 2 | import math | 2 | import math | ||
| 3 | 3 | ||||
| 4 | class Effect: | 4 | class Effect: | ||
| 5 | def __init__(self, name, func, intensity=1): | 5 | def __init__(self, name, func, intensity=1): | ||
| 6 | self.name = name | 6 | self.name = name | ||
| 7 | self.func = func | 7 | self.func = func | ||
| 8 | self.is_used = False | 8 | self.is_used = False | ||
| 9 | self.intensity = intensity | 9 | self.intensity = intensity | ||
| 10 | self.is_active = True | 10 | self.is_active = True | ||
| 11 | 11 | ||||
| 12 | @property | 12 | @property | ||
| 13 | def molecular_mass(self): | 13 | def molecular_mass(self): | ||
| 14 | return sum([ord(letter) for letter in self.name]) | 14 | return sum([ord(letter) for letter in self.name]) | ||
| 15 | 15 | ||||
| 16 | def __call__(self, target, is_continuing=False): | 16 | def __call__(self, target, is_continuing=False): | ||
| 17 | if not self.is_used or is_continuing: | 17 | if not self.is_used or is_continuing: | ||
| 18 | for _ in range(self.intensity): | 18 | for _ in range(self.intensity): | ||
| 19 | self.func(target) | 19 | self.func(target) | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | else: | 21 | else: | ||
| 22 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class Potion: | 25 | class Potion: | ||
| 26 | def __init__(self, effects, duration=2, intensities=None): | 26 | def __init__(self, effects, duration=2, intensities=None): | ||
| 27 | self.effects = {} | 27 | self.effects = {} | ||
| 28 | self.is_itself = True | 28 | self.is_itself = True | ||
| 29 | self.is_used = False | 29 | self.is_used = False | ||
| 30 | 30 | ||||
| 31 | for effect_name in effects: | 31 | for effect_name in effects: | ||
| 32 | effect_func = effects[effect_name] | 32 | effect_func = effects[effect_name] | ||
| 33 | effects[effect_name].is_called = False | 33 | effects[effect_name].is_called = False | ||
| 34 | 34 | ||||
| 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 36 | 36 | ||||
| 37 | self.duration = duration | 37 | self.duration = duration | ||
| 38 | 38 | ||||
| 39 | def effect(self, target, is_continuing=False): | 39 | def effect(self, target, is_continuing=False): | ||
| 40 | if not is_continuing and not self.is_itself: | 40 | if not is_continuing and not self.is_itself: | ||
| 41 | raise TypeError("Potion is now part of something bigger than itself.") | 41 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 42 | 42 | ||||
| 43 | if self.is_used and not is_continuing: | 43 | if self.is_used and not is_continuing: | ||
| 44 | raise TypeError("Potion is depleted.") | 44 | raise TypeError("Potion is depleted.") | ||
| 45 | 45 | ||||
| 46 | self.is_used = True | 46 | self.is_used = True | ||
| 47 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | 47 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | ||
| 48 | 48 | ||||
| 49 | for effect in self.effects.values(): | 49 | for effect in self.effects.values(): | ||
| 50 | if not effect.is_active: | 50 | if not effect.is_active: | ||
| 51 | continue | 51 | continue | ||
| 52 | effect(target, True) | 52 | effect(target, True) | ||
| 53 | 53 | ||||
| 54 | def __getattr__(self, effect_name): | 54 | def __getattr__(self, effect_name): | ||
| 55 | if effect_name not in self.effects: | 55 | if effect_name not in self.effects: | ||
| 56 | raise AttributeError("Effect is not in potion.") | 56 | raise AttributeError("Effect is not in potion.") | ||
| 57 | 57 | ||||
| 58 | if self.is_used: | 58 | if self.is_used: | ||
| 59 | raise TypeError("Potion is depleted.") | 59 | raise TypeError("Potion is depleted.") | ||
| 60 | 60 | ||||
| 61 | if not self.effects[effect_name].is_active: | 61 | if not self.effects[effect_name].is_active: | ||
| 62 | raise TypeError("Effect is depleted.") | 62 | raise TypeError("Effect is depleted.") | ||
| 63 | 63 | ||||
| 64 | if not self.is_itself: | 64 | if not self.is_itself: | ||
| 65 | raise TypeError("Potion is now part of something bigger than itself.") | 65 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 66 | 66 | ||||
| 67 | self.effects[effect_name].is_active = False | 67 | self.effects[effect_name].is_active = False | ||
| 68 | 68 | ||||
| 69 | return self.effects[effect_name] | 69 | return self.effects[effect_name] | ||
| 70 | 70 | ||||
| 71 | def __add__(self, other): | 71 | def __add__(self, other): | ||
| 72 | """Combining two potions.""" | 72 | """Combining two potions.""" | ||
| 73 | if not self.is_itself or not other.is_itself: | 73 | if not self.is_itself or not other.is_itself: | ||
| 74 | raise TypeError("Potion is now part of something bigger than itself.") | 74 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 75 | 75 | ||||
| 76 | if self.is_used: | 76 | if self.is_used: | ||
| 77 | raise TypeError("Potion is depleted.") | 77 | raise TypeError("Potion is depleted.") | ||
| 78 | 78 | ||||
| 79 | effects = {} | 79 | effects = {} | ||
| 80 | intensities = {} | 80 | intensities = {} | ||
| 81 | 81 | ||||
| 82 | for effect_name, effect in self.effects.items(): | 82 | for effect_name, effect in self.effects.items(): | ||
| 83 | if not effect.is_active: | 83 | if not effect.is_active: | ||
| 84 | continue | 84 | continue | ||
| 85 | effects[effect_name] = effect.func | 85 | effects[effect_name] = effect.func | ||
| 86 | intensities[effect_name] = effect.intensity | 86 | intensities[effect_name] = effect.intensity | ||
| 87 | 87 | ||||
| 88 | for effect_name, effect in other.effects.items(): | 88 | for effect_name, effect in other.effects.items(): | ||
| 89 | if not effect.is_active: | 89 | if not effect.is_active: | ||
| 90 | continue | 90 | continue | ||
| 91 | 91 | ||||
| 92 | if effect_name not in effects: | 92 | if effect_name not in effects: | ||
| 93 | effects[effect_name] = effect.func | 93 | effects[effect_name] = effect.func | ||
| 94 | intensities[effect_name] = effect.intensity | 94 | intensities[effect_name] = effect.intensity | ||
| 95 | else: | 95 | else: | ||
| 96 | intensities[effect_name] += effect.intensity | 96 | intensities[effect_name] += effect.intensity | ||
| 97 | 97 | ||||
| 98 | self.is_itself = False | 98 | self.is_itself = False | ||
| 99 | other.is_itself = False | 99 | other.is_itself = False | ||
| 100 | 100 | ||||
| 101 | return Potion(effects, max(self.duration, other.duration), intensities) | 101 | return Potion(effects, max(self.duration, other.duration), intensities) | ||
| 102 | 102 | ||||
| 103 | def __mul__(self, number): | 103 | def __mul__(self, number): | ||
| 104 | """Potentiation of two potions.""" | 104 | """Potentiation of two potions.""" | ||
| 105 | if not self.is_itself: | 105 | if not self.is_itself: | ||
| 106 | raise TypeError("Potion is now part of something bigger than itself.") | 106 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 107 | 107 | ||||
| 108 | if self.is_used: | 108 | if self.is_used: | ||
| 109 | raise TypeError("Potion is depleted.") | 109 | raise TypeError("Potion is depleted.") | ||
| 110 | 110 | ||||
| 111 | effects = {} | 111 | effects = {} | ||
| 112 | intensities = {} | 112 | intensities = {} | ||
| 113 | 113 | ||||
| 114 | for effect_name, effect in self.effects.items(): | 114 | for effect_name, effect in self.effects.items(): | ||
| 115 | if not effect.is_active: | 115 | if not effect.is_active: | ||
| 116 | continue | 116 | continue | ||
| 117 | 117 | ||||
| 118 | intensities[effect_name] = effect.intensity * number | 118 | intensities[effect_name] = effect.intensity * number | ||
| 119 | 119 | ||||
| 120 | if intensities[effect_name] % 1 <= 0.5: | 120 | if intensities[effect_name] % 1 <= 0.5: | ||
| 121 | intensities[effect_name] = math.floor(intensities[effect_name]) | 121 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 122 | else: | 122 | else: | ||
| 123 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 123 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 124 | 124 | ||||
| 125 | effects[effect_name] = effect.func | 125 | effects[effect_name] = effect.func | ||
| 126 | 126 | ||||
| 127 | self.is_itself = False | 127 | self.is_itself = False | ||
| 128 | return Potion(effects, self.duration, intensities) | 128 | return Potion(effects, self.duration, intensities) | ||
| 129 | 129 | ||||
| 130 | def __sub__(self, other): | 130 | def __sub__(self, other): | ||
| 131 | """Purification of two potions.""" | 131 | """Purification of two potions.""" | ||
| 132 | if not self.is_itself or not other.is_itself: | 132 | if not self.is_itself or not other.is_itself: | ||
| 133 | raise TypeError("Potion is now part of something bigger than itself.") | 133 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 134 | 134 | ||||
| 135 | if self.is_used: | 135 | if self.is_used: | ||
| 136 | raise TypeError("Potion is depleted.") | 136 | raise TypeError("Potion is depleted.") | ||
| 137 | 137 | ||||
| 138 | for effect in other.effects: | 138 | for effect in other.effects: | ||
| 139 | if effect not in self.effects: | 139 | if effect not in self.effects: | ||
| 140 | raise TypeError("Effect is not in potion.") | 140 | raise TypeError("Effect is not in potion.") | ||
| 141 | 141 | ||||
| 142 | effects = {} | 142 | effects = {} | ||
| 143 | intensities = {} | 143 | intensities = {} | ||
| 144 | 144 | ||||
| 145 | for effect_name, effect in self.effects.items(): | 145 | for effect_name, effect in self.effects.items(): | ||
| 146 | intensities[effect_name] = effect.intensity | 146 | intensities[effect_name] = effect.intensity | ||
| 147 | effects[effect_name] = effect.func | 147 | effects[effect_name] = effect.func | ||
| 148 | 148 | ||||
| 149 | if not effect.is_active: | 149 | if not effect.is_active: | ||
| 150 | intensities[effect_name] = max(intensities[effect_name] - 1, 0) | 150 | intensities[effect_name] = max(intensities[effect_name] - 1, 0) | ||
| 151 | 151 | ||||
| 152 | for effect in other.effects: | 152 | for effect in other.effects: | ||
| 153 | intensities[effect] -= other.effects[effect].intensity | 153 | intensities[effect] -= other.effects[effect].intensity | ||
| 154 | 154 | ||||
| 155 | if not other.effects[effect].is_active and other.effects[effect].intensity > 0: | 155 | if not other.effects[effect].is_active and other.effects[effect].intensity > 0: | ||
| 156 | intensities[effect] += 1 | 156 | intensities[effect] += 1 | ||
| 157 | 157 | ||||
| 158 | if intensities[effect] <= 0: | 158 | if intensities[effect] <= 0: | ||
| 159 | effects.pop(effect) | 159 | effects.pop(effect) | ||
| 160 | intensities.pop(effect) | 160 | intensities.pop(effect) | ||
| 161 | 161 | ||||
| 162 | self.is_itself = False | 162 | self.is_itself = False | ||
| 163 | other.is_itself = False | 163 | other.is_itself = False | ||
| 164 | return Potion(effects, self.duration, intensities) | 164 | return Potion(effects, self.duration, intensities) | ||
| 165 | 165 | ||||
| 166 | def __truediv__(self, number:int): | 166 | def __truediv__(self, number:int): | ||
| 167 | """Dividing two potions.""" | 167 | """Dividing two potions.""" | ||
| 168 | if not self.is_itself: | 168 | if not self.is_itself: | ||
| 169 | raise TypeError("Potion is now part of something bigger than itself.") | 169 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 170 | 170 | ||||
| 171 | if self.is_used: | 171 | if self.is_used: | ||
| 172 | raise TypeError("Potion is depleted.") | 172 | raise TypeError("Potion is depleted.") | ||
| 173 | 173 | ||||
| 174 | effects = {} | 174 | effects = {} | ||
| 175 | intensities = {} | 175 | intensities = {} | ||
| 176 | 176 | ||||
| 177 | for effect_name, effect in self.effects.items(): | 177 | for effect_name, effect in self.effects.items(): | ||
| 178 | if not effect.is_active: | 178 | if not effect.is_active: | ||
| 179 | continue | 179 | continue | ||
| 180 | 180 | ||||
| 181 | intensities[effect_name] = int(effect.intensity) / number | 181 | intensities[effect_name] = int(effect.intensity) / number | ||
| 182 | effects[effect_name] = effect.func | 182 | effects[effect_name] = effect.func | ||
| 183 | 183 | ||||
| 184 | if intensities[effect_name] % 1 <= 0.5: | 184 | if intensities[effect_name] % 1 <= 0.5: | ||
| 185 | intensities[effect_name] = math.floor(intensities[effect_name]) | 185 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 186 | else: | 186 | else: | ||
| 187 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 187 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 188 | 188 | ||||
| 189 | self.is_itself = False | 189 | self.is_itself = False | ||
| 190 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | 190 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | ||
| 191 | 191 | ||||
| 192 | def __eq__(self, other): | 192 | def __eq__(self, other): | ||
| 193 | 193 | ||||
| 194 | if not self.is_itself or not other.is_itself: | 194 | if not self.is_itself or not other.is_itself: | ||
| 195 | raise TypeError("Potion is now part of something bigger than itself.") | 195 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 196 | 196 | ||||
| 197 | if self.is_used: | 197 | if self.is_used: | ||
| 198 | raise TypeError("Potion is depleted.") | 198 | raise TypeError("Potion is depleted.") | ||
| 199 | 199 | ||||
| 200 | for effect in self.effects: | 200 | for effect in self.effects: | ||
| 201 | if effect not in other.effects: | 201 | if effect not in other.effects: | ||
| 202 | return False | 202 | return False | ||
| 203 | 203 | ||||
| 204 | if not self.effects[effect].is_active: | 204 | if not self.effects[effect].is_active: | ||
| 205 | self.effects[effect].intensity = 0 | 205 | self.effects[effect].intensity = 0 | ||
| 206 | 206 | ||||
| 207 | if not other.effects[effect].is_active: | 207 | if not other.effects[effect].is_active: | ||
| 208 | other.effects[effect].intensity = 0 | 208 | other.effects[effect].intensity = 0 | ||
| 209 | 209 | ||||
| 210 | if self.effects[effect].intensity != other.effects[effect].intensity: | 210 | if self.effects[effect].intensity != other.effects[effect].intensity: | ||
| 211 | return False | 211 | return False | ||
| 212 | 212 | ||||
| 213 | for effect in other.effects: | 213 | for effect in other.effects: | ||
| 214 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | 214 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||
| 215 | return False | 215 | return False | ||
| 216 | 216 | ||||
| 217 | return True | 217 | return True | ||
| 218 | 218 | ||||
| 219 | def __lt__(self, other): | 219 | def __lt__(self, other): | ||
| 220 | 220 | ||||
| 221 | if not self.is_itself or not other.is_itself: | 221 | if not self.is_itself or not other.is_itself: | ||
| 222 | raise TypeError("Potion is now part of something bigger than itself.") | 222 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 223 | 223 | ||||
| 224 | if self.is_used: | 224 | if self.is_used: | ||
| 225 | raise TypeError("Potion is depleted.") | 225 | raise TypeError("Potion is depleted.") | ||
| 226 | 226 | ||||
| t | t | 227 | |||
| 227 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | 228 | return sum(effect.intensity if effect.is_active else 0 for effect in self.effects.values()) < sum(effect.intensity if effect.is_active else 0 for effect in other.effects.values()) | ||
| 228 | |||||
| 229 | def __gt__(self, other): | ||||
| 230 | |||||
| 231 | if not self.is_itself or not other.is_itself: | ||||
| 232 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 233 | |||||
| 234 | if self.is_used: | ||||
| 235 | raise TypeError("Potion is depleted.") | ||||
| 236 | |||||
| 237 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | ||||
| 238 | 229 | ||||
| 239 | def __dir__(self): | 230 | def __dir__(self): | ||
| 240 | return list(self.effects.keys()) | 231 | return list(self.effects.keys()) | ||
| 241 | 232 | ||||
| 242 | 233 | ||||
| 243 | class Target: | 234 | class Target: | ||
| 244 | def __init__(self, target): | 235 | def __init__(self, target): | ||
| 245 | self.curr_target = target | 236 | self.curr_target = target | ||
| 246 | self.original = copy.deepcopy(target.__dict__) | 237 | self.original = copy.deepcopy(target.__dict__) | ||
| 247 | 238 | ||||
| 248 | @property | 239 | @property | ||
| 249 | def original_state(self): | 240 | def original_state(self): | ||
| 250 | return copy.deepcopy(self.original) | 241 | return copy.deepcopy(self.original) | ||
| 251 | 242 | ||||
| 252 | def back_to_original(self): | 243 | def back_to_original(self): | ||
| 253 | self.curr_target.__dict__ = self.original_state | 244 | self.curr_target.__dict__ = self.original_state | ||
| 254 | 245 | ||||
| 255 | def __eq__(self, other): | 246 | def __eq__(self, other): | ||
| 256 | if isinstance(other, Target): | 247 | if isinstance(other, Target): | ||
| 257 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | 248 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | ||
| 258 | return False | 249 | return False | ||
| 259 | 250 | ||||
| 260 | def __hash__(self): | 251 | def __hash__(self): | ||
| 261 | return hash(self.curr_target.__class__.__name__) | 252 | return hash(self.curr_target.__class__.__name__) | ||
| 262 | 253 | ||||
| 263 | class ГоспожатаПоХимия: | 254 | class ГоспожатаПоХимия: | ||
| 264 | def __init__(self): | 255 | def __init__(self): | ||
| 265 | self.active_potions = {} | 256 | self.active_potions = {} | ||
| 266 | 257 | ||||
| 267 | def apply(self, target_obj, potion): | 258 | def apply(self, target_obj, potion): | ||
| 268 | target = Target(target_obj) | 259 | target = Target(target_obj) | ||
| 269 | 260 | ||||
| 270 | if self.active_potions.get(target) is None: | 261 | if self.active_potions.get(target) is None: | ||
| 271 | self.active_potions[target] = [] | 262 | self.active_potions[target] = [] | ||
| 272 | 263 | ||||
| 273 | if potion.duration > 0: | 264 | if potion.duration > 0: | ||
| 274 | potion.effect(target.curr_target) | 265 | potion.effect(target.curr_target) | ||
| 275 | self.active_potions[target].append([potion.duration - 1, potion]) | 266 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 276 | 267 | ||||
| 277 | def tick(self): | 268 | def tick(self): | ||
| 278 | for target in self.active_potions: | 269 | for target in self.active_potions: | ||
| 279 | target.back_to_original() | 270 | target.back_to_original() | ||
| 280 | to_remove = [] | 271 | to_remove = [] | ||
| 281 | 272 | ||||
| 282 | for curr in self.active_potions[target]: | 273 | for curr in self.active_potions[target]: | ||
| 283 | remaining_time, potion = curr | 274 | remaining_time, potion = curr | ||
| 284 | curr[0] -= 1 | 275 | curr[0] -= 1 | ||
| 285 | 276 | ||||
| 286 | if remaining_time <= 0: | 277 | if remaining_time <= 0: | ||
| 287 | to_remove.append(curr) | 278 | to_remove.append(curr) | ||
| 288 | else: | 279 | else: | ||
| 289 | potion.effect(target.curr_target, True) | 280 | potion.effect(target.curr_target, True) | ||
| 290 | 281 | ||||
| 291 | for curr in to_remove: | 282 | for curr in to_remove: | ||
| 292 | self.active_potions[target].remove(curr) | 283 | self.active_potions[target].remove(curr) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| 2 | import math | 2 | import math | ||
| 3 | 3 | ||||
| 4 | class Effect: | 4 | class Effect: | ||
| 5 | def __init__(self, name, func, intensity=1): | 5 | def __init__(self, name, func, intensity=1): | ||
| 6 | self.name = name | 6 | self.name = name | ||
| 7 | self.func = func | 7 | self.func = func | ||
| 8 | self.is_used = False | 8 | self.is_used = False | ||
| 9 | self.intensity = intensity | 9 | self.intensity = intensity | ||
| 10 | self.is_active = True | 10 | self.is_active = True | ||
| 11 | 11 | ||||
| 12 | @property | 12 | @property | ||
| 13 | def molecular_mass(self): | 13 | def molecular_mass(self): | ||
| 14 | return sum([ord(letter) for letter in self.name]) | 14 | return sum([ord(letter) for letter in self.name]) | ||
| 15 | 15 | ||||
| 16 | def __call__(self, target, is_continuing=False): | 16 | def __call__(self, target, is_continuing=False): | ||
| 17 | if not self.is_used or is_continuing: | 17 | if not self.is_used or is_continuing: | ||
| 18 | for _ in range(self.intensity): | 18 | for _ in range(self.intensity): | ||
| 19 | self.func(target) | 19 | self.func(target) | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | else: | 21 | else: | ||
| 22 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class Potion: | 25 | class Potion: | ||
| 26 | def __init__(self, effects, duration=2, intensities=None): | 26 | def __init__(self, effects, duration=2, intensities=None): | ||
| 27 | self.effects = {} | 27 | self.effects = {} | ||
| 28 | self.is_itself = True | 28 | self.is_itself = True | ||
| 29 | self.is_used = False | 29 | self.is_used = False | ||
| 30 | 30 | ||||
| 31 | for effect_name in effects: | 31 | for effect_name in effects: | ||
| 32 | effect_func = effects[effect_name] | 32 | effect_func = effects[effect_name] | ||
| 33 | effects[effect_name].is_called = False | 33 | effects[effect_name].is_called = False | ||
| 34 | 34 | ||||
| 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 36 | 36 | ||||
| 37 | self.duration = duration | 37 | self.duration = duration | ||
| 38 | 38 | ||||
| 39 | def effect(self, target, is_continuing=False): | 39 | def effect(self, target, is_continuing=False): | ||
| 40 | if not is_continuing and not self.is_itself: | 40 | if not is_continuing and not self.is_itself: | ||
| 41 | raise TypeError("Potion is now part of something bigger than itself.") | 41 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| n | n | 42 | |||
| 42 | if self.is_used and not is_continuing: | 43 | if self.is_used and not is_continuing: | ||
| 43 | raise TypeError("Potion is depleted.") | 44 | raise TypeError("Potion is depleted.") | ||
| n | n | 45 | |||
| 44 | self.is_used = True | 46 | self.is_used = True | ||
| 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | 47 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | ||
| 46 | 48 | ||||
| 47 | for effect in self.effects.values(): | 49 | for effect in self.effects.values(): | ||
| 48 | if not effect.is_active: | 50 | if not effect.is_active: | ||
| 49 | continue | 51 | continue | ||
| 50 | effect(target, True) | 52 | effect(target, True) | ||
| 51 | 53 | ||||
| 52 | def __getattr__(self, effect_name): | 54 | def __getattr__(self, effect_name): | ||
| n | 53 | if(effect_name not in self.effects): | n | 55 | if effect_name not in self.effects: |
| 54 | raise TypeError("Effect is not in potion.") | 56 | raise AttributeError("Effect is not in potion.") | ||
| 57 | |||||
| 58 | if self.is_used: | ||||
| 59 | raise TypeError("Potion is depleted.") | ||||
| 55 | 60 | ||||
| 56 | if not self.effects[effect_name].is_active: | 61 | if not self.effects[effect_name].is_active: | ||
| 57 | raise TypeError("Effect is depleted.") | 62 | raise TypeError("Effect is depleted.") | ||
| 58 | 63 | ||||
| 59 | if not self.is_itself: | 64 | if not self.is_itself: | ||
| 60 | raise TypeError("Potion is now part of something bigger than itself.") | 65 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 61 | 66 | ||||
| 62 | self.effects[effect_name].is_active = False | 67 | self.effects[effect_name].is_active = False | ||
| 63 | 68 | ||||
| 64 | return self.effects[effect_name] | 69 | return self.effects[effect_name] | ||
| 65 | 70 | ||||
| 66 | def __add__(self, other): | 71 | def __add__(self, other): | ||
| 67 | """Combining two potions.""" | 72 | """Combining two potions.""" | ||
| 68 | if not self.is_itself or not other.is_itself: | 73 | if not self.is_itself or not other.is_itself: | ||
| 69 | raise TypeError("Potion is now part of something bigger than itself.") | 74 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 70 | 75 | ||||
| 71 | if self.is_used: | 76 | if self.is_used: | ||
| 72 | raise TypeError("Potion is depleted.") | 77 | raise TypeError("Potion is depleted.") | ||
| 73 | 78 | ||||
| 74 | effects = {} | 79 | effects = {} | ||
| 75 | intensities = {} | 80 | intensities = {} | ||
| 76 | 81 | ||||
| 77 | for effect_name, effect in self.effects.items(): | 82 | for effect_name, effect in self.effects.items(): | ||
| n | n | 83 | if not effect.is_active: | ||
| 84 | continue | ||||
| 78 | effects[effect_name] = effect.func | 85 | effects[effect_name] = effect.func | ||
| 79 | intensities[effect_name] = effect.intensity | 86 | intensities[effect_name] = effect.intensity | ||
| 80 | 87 | ||||
| 81 | for effect_name, effect in other.effects.items(): | 88 | for effect_name, effect in other.effects.items(): | ||
| n | n | 89 | if not effect.is_active: | ||
| 90 | continue | ||||
| 91 | |||||
| 82 | if effect_name not in effects: | 92 | if effect_name not in effects: | ||
| 83 | effects[effect_name] = effect.func | 93 | effects[effect_name] = effect.func | ||
| 84 | intensities[effect_name] = effect.intensity | 94 | intensities[effect_name] = effect.intensity | ||
| 85 | else: | 95 | else: | ||
| 86 | intensities[effect_name] += effect.intensity | 96 | intensities[effect_name] += effect.intensity | ||
| 87 | 97 | ||||
| 88 | self.is_itself = False | 98 | self.is_itself = False | ||
| 89 | other.is_itself = False | 99 | other.is_itself = False | ||
| n | n | 100 | |||
| 90 | return Potion(effects, max(self.duration, other.duration), intensities) | 101 | return Potion(effects, max(self.duration, other.duration), intensities) | ||
| 91 | 102 | ||||
| 92 | def __mul__(self, number): | 103 | def __mul__(self, number): | ||
| 93 | """Potentiation of two potions.""" | 104 | """Potentiation of two potions.""" | ||
| 94 | if not self.is_itself: | 105 | if not self.is_itself: | ||
| 95 | raise TypeError("Potion is now part of something bigger than itself.") | 106 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 96 | 107 | ||||
| 97 | if self.is_used: | 108 | if self.is_used: | ||
| 98 | raise TypeError("Potion is depleted.") | 109 | raise TypeError("Potion is depleted.") | ||
| 99 | 110 | ||||
| 100 | effects = {} | 111 | effects = {} | ||
| 101 | intensities = {} | 112 | intensities = {} | ||
| 102 | 113 | ||||
| 103 | for effect_name, effect in self.effects.items(): | 114 | for effect_name, effect in self.effects.items(): | ||
| n | n | 115 | if not effect.is_active: | ||
| 116 | continue | ||||
| 117 | |||||
| 104 | intensities[effect_name] = effect.intensity * number | 118 | intensities[effect_name] = effect.intensity * number | ||
| 105 | 119 | ||||
| 106 | if intensities[effect_name] % 1 <= 0.5: | 120 | if intensities[effect_name] % 1 <= 0.5: | ||
| 107 | intensities[effect_name] = math.floor(intensities[effect_name]) | 121 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 108 | else: | 122 | else: | ||
| 109 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 123 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 110 | 124 | ||||
| 111 | effects[effect_name] = effect.func | 125 | effects[effect_name] = effect.func | ||
| 112 | 126 | ||||
| 113 | self.is_itself = False | 127 | self.is_itself = False | ||
| 114 | return Potion(effects, self.duration, intensities) | 128 | return Potion(effects, self.duration, intensities) | ||
| 115 | 129 | ||||
| 116 | def __sub__(self, other): | 130 | def __sub__(self, other): | ||
| 117 | """Purification of two potions.""" | 131 | """Purification of two potions.""" | ||
| 118 | if not self.is_itself or not other.is_itself: | 132 | if not self.is_itself or not other.is_itself: | ||
| 119 | raise TypeError("Potion is now part of something bigger than itself.") | 133 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 120 | 134 | ||||
| 121 | if self.is_used: | 135 | if self.is_used: | ||
| 122 | raise TypeError("Potion is depleted.") | 136 | raise TypeError("Potion is depleted.") | ||
| 123 | 137 | ||||
| 124 | for effect in other.effects: | 138 | for effect in other.effects: | ||
| 125 | if effect not in self.effects: | 139 | if effect not in self.effects: | ||
| 126 | raise TypeError("Effect is not in potion.") | 140 | raise TypeError("Effect is not in potion.") | ||
| 127 | 141 | ||||
| 128 | effects = {} | 142 | effects = {} | ||
| 129 | intensities = {} | 143 | intensities = {} | ||
| 130 | 144 | ||||
| 131 | for effect_name, effect in self.effects.items(): | 145 | for effect_name, effect in self.effects.items(): | ||
| 132 | intensities[effect_name] = effect.intensity | 146 | intensities[effect_name] = effect.intensity | ||
| 133 | effects[effect_name] = effect.func | 147 | effects[effect_name] = effect.func | ||
| 134 | 148 | ||||
| n | n | 149 | if not effect.is_active: | ||
| 150 | intensities[effect_name] = max(intensities[effect_name] - 1, 0) | ||||
| 151 | |||||
| 135 | for effect in other.effects: | 152 | for effect in other.effects: | ||
| 136 | intensities[effect] -= other.effects[effect].intensity | 153 | intensities[effect] -= other.effects[effect].intensity | ||
| n | n | 154 | |||
| 155 | if not other.effects[effect].is_active and other.effects[effect].intensity > 0: | ||||
| 156 | intensities[effect] += 1 | ||||
| 137 | 157 | ||||
| 138 | if intensities[effect] <= 0: | 158 | if intensities[effect] <= 0: | ||
| 139 | effects.pop(effect) | 159 | effects.pop(effect) | ||
| 140 | intensities.pop(effect) | 160 | intensities.pop(effect) | ||
| 141 | 161 | ||||
| 142 | self.is_itself = False | 162 | self.is_itself = False | ||
| 143 | other.is_itself = False | 163 | other.is_itself = False | ||
| 144 | return Potion(effects, self.duration, intensities) | 164 | return Potion(effects, self.duration, intensities) | ||
| 145 | 165 | ||||
| 146 | def __truediv__(self, number:int): | 166 | def __truediv__(self, number:int): | ||
| 147 | """Dividing two potions.""" | 167 | """Dividing two potions.""" | ||
| 148 | if not self.is_itself: | 168 | if not self.is_itself: | ||
| 149 | raise TypeError("Potion is now part of something bigger than itself.") | 169 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 150 | 170 | ||||
| 151 | if self.is_used: | 171 | if self.is_used: | ||
| 152 | raise TypeError("Potion is depleted.") | 172 | raise TypeError("Potion is depleted.") | ||
| 153 | 173 | ||||
| 154 | effects = {} | 174 | effects = {} | ||
| 155 | intensities = {} | 175 | intensities = {} | ||
| 156 | 176 | ||||
| 157 | for effect_name, effect in self.effects.items(): | 177 | for effect_name, effect in self.effects.items(): | ||
| n | n | 178 | if not effect.is_active: | ||
| 179 | continue | ||||
| 180 | |||||
| 158 | intensities[effect_name] = int(effect.intensity) / number | 181 | intensities[effect_name] = int(effect.intensity) / number | ||
| 159 | effects[effect_name] = effect.func | 182 | effects[effect_name] = effect.func | ||
| 160 | 183 | ||||
| 161 | if intensities[effect_name] % 1 <= 0.5: | 184 | if intensities[effect_name] % 1 <= 0.5: | ||
| 162 | intensities[effect_name] = math.floor(intensities[effect_name]) | 185 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 163 | else: | 186 | else: | ||
| 164 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 187 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 165 | 188 | ||||
| 166 | self.is_itself = False | 189 | self.is_itself = False | ||
| 167 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | 190 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | ||
| 168 | 191 | ||||
| 169 | def __eq__(self, other): | 192 | def __eq__(self, other): | ||
| n | n | 193 | |||
| 194 | if not self.is_itself or not other.is_itself: | ||||
| 195 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 196 | |||||
| 197 | if self.is_used: | ||||
| 198 | raise TypeError("Potion is depleted.") | ||||
| 199 | |||||
| 170 | for effect in self.effects: | 200 | for effect in self.effects: | ||
| n | 171 | if effect not in other.effects or self.effects[effect].intensity != other.effects[effect].intensity: | n | 201 | if effect not in other.effects: |
| 172 | return False | 202 | return False | ||
| n | n | 203 | |||
| 204 | if not self.effects[effect].is_active: | ||||
| 205 | self.effects[effect].intensity = 0 | ||||
| 206 | |||||
| 207 | if not other.effects[effect].is_active: | ||||
| 208 | other.effects[effect].intensity = 0 | ||||
| 209 | |||||
| 210 | if self.effects[effect].intensity != other.effects[effect].intensity: | ||||
| 211 | return False | ||||
| 212 | |||||
| 173 | for effect in other.effects: | 213 | for effect in other.effects: | ||
| 174 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | 214 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||
| 175 | return False | 215 | return False | ||
| 176 | 216 | ||||
| 177 | return True | 217 | return True | ||
| 178 | 218 | ||||
| 179 | def __lt__(self, other): | 219 | def __lt__(self, other): | ||
| n | n | 220 | |||
| 221 | if not self.is_itself or not other.is_itself: | ||||
| 222 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 223 | |||||
| 224 | if self.is_used: | ||||
| 225 | raise TypeError("Potion is depleted.") | ||||
| 226 | |||||
| 180 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | 227 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | ||
| 181 | 228 | ||||
| 182 | def __gt__(self, other): | 229 | def __gt__(self, other): | ||
| n | n | 230 | |||
| 231 | if not self.is_itself or not other.is_itself: | ||||
| 232 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 233 | |||||
| 234 | if self.is_used: | ||||
| 235 | raise TypeError("Potion is depleted.") | ||||
| 236 | |||||
| 183 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | 237 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | ||
| n | n | 238 | |||
| 239 | def __dir__(self): | ||||
| 240 | return list(self.effects.keys()) | ||||
| 184 | 241 | ||||
| 185 | 242 | ||||
| 186 | class Target: | 243 | class Target: | ||
| 187 | def __init__(self, target): | 244 | def __init__(self, target): | ||
| 188 | self.curr_target = target | 245 | self.curr_target = target | ||
| 189 | self.original = copy.deepcopy(target.__dict__) | 246 | self.original = copy.deepcopy(target.__dict__) | ||
| 190 | 247 | ||||
| 191 | @property | 248 | @property | ||
| 192 | def original_state(self): | 249 | def original_state(self): | ||
| 193 | return copy.deepcopy(self.original) | 250 | return copy.deepcopy(self.original) | ||
| 194 | 251 | ||||
| 195 | def back_to_original(self): | 252 | def back_to_original(self): | ||
| 196 | self.curr_target.__dict__ = self.original_state | 253 | self.curr_target.__dict__ = self.original_state | ||
| 197 | 254 | ||||
| 198 | def __eq__(self, other): | 255 | def __eq__(self, other): | ||
| 199 | if isinstance(other, Target): | 256 | if isinstance(other, Target): | ||
| 200 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | 257 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | ||
| 201 | return False | 258 | return False | ||
| 202 | 259 | ||||
| 203 | def __hash__(self): | 260 | def __hash__(self): | ||
| 204 | return hash(self.curr_target.__class__.__name__) | 261 | return hash(self.curr_target.__class__.__name__) | ||
| 205 | 262 | ||||
| 206 | class ГоспожатаПоХимия: | 263 | class ГоспожатаПоХимия: | ||
| 207 | def __init__(self): | 264 | def __init__(self): | ||
| 208 | self.active_potions = {} | 265 | self.active_potions = {} | ||
| 209 | 266 | ||||
| 210 | def apply(self, target_obj, potion): | 267 | def apply(self, target_obj, potion): | ||
| 211 | target = Target(target_obj) | 268 | target = Target(target_obj) | ||
| n | n | 269 | |||
| 212 | if self.active_potions.get(target) is None: | 270 | if self.active_potions.get(target) is None: | ||
| 213 | self.active_potions[target] = [] | 271 | self.active_potions[target] = [] | ||
| 214 | 272 | ||||
| n | n | 273 | if potion.duration > 0: | ||
| 215 | potion.effect(target.curr_target) | 274 | potion.effect(target.curr_target) | ||
| 216 | self.active_potions[target].append([potion.duration - 1, potion]) | 275 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 217 | 276 | ||||
| 218 | def tick(self): | 277 | def tick(self): | ||
| 219 | for target in self.active_potions: | 278 | for target in self.active_potions: | ||
| 220 | target.back_to_original() | 279 | target.back_to_original() | ||
| 221 | to_remove = [] | 280 | to_remove = [] | ||
| n | n | 281 | |||
| 222 | for curr in self.active_potions[target]: | 282 | for curr in self.active_potions[target]: | ||
| 223 | remaining_time, potion = curr | 283 | remaining_time, potion = curr | ||
| 224 | curr[0] -= 1 | 284 | curr[0] -= 1 | ||
| n | n | 285 | |||
| 225 | if remaining_time <= 0: | 286 | if remaining_time <= 0: | ||
| 226 | to_remove.append(curr) | 287 | to_remove.append(curr) | ||
| 227 | else: | 288 | else: | ||
| 228 | potion.effect(target.curr_target, True) | 289 | potion.effect(target.curr_target, True) | ||
| n | n | 290 | |||
| 229 | for curr in to_remove: | 291 | for curr in to_remove: | ||
| 230 | self.active_potions[target].remove(curr) | 292 | self.active_potions[target].remove(curr) | ||
| t | 231 | t | |||
| 232 | |||||
| 233 | def get_grow_potion(): | ||||
| 234 | effects = {'grow': lambda target: setattr( | ||||
| 235 | target, 'size', target.size*2)} | ||||
| 236 | |||||
| 237 | grow_potion = Potion(effects, duration=2) | ||||
| 238 | |||||
| 239 | return grow_potion | ||||
| 240 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| 2 | import math | 2 | import math | ||
| 3 | 3 | ||||
| 4 | class Effect: | 4 | class Effect: | ||
| 5 | def __init__(self, name, func, intensity=1): | 5 | def __init__(self, name, func, intensity=1): | ||
| 6 | self.name = name | 6 | self.name = name | ||
| 7 | self.func = func | 7 | self.func = func | ||
| 8 | self.is_used = False | 8 | self.is_used = False | ||
| 9 | self.intensity = intensity | 9 | self.intensity = intensity | ||
| 10 | self.is_active = True | 10 | self.is_active = True | ||
| 11 | 11 | ||||
| 12 | @property | 12 | @property | ||
| 13 | def molecular_mass(self): | 13 | def molecular_mass(self): | ||
| 14 | return sum([ord(letter) for letter in self.name]) | 14 | return sum([ord(letter) for letter in self.name]) | ||
| 15 | 15 | ||||
| 16 | def __call__(self, target, is_continuing=False): | 16 | def __call__(self, target, is_continuing=False): | ||
| 17 | if not self.is_used or is_continuing: | 17 | if not self.is_used or is_continuing: | ||
| 18 | for _ in range(self.intensity): | 18 | for _ in range(self.intensity): | ||
| 19 | self.func(target) | 19 | self.func(target) | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | else: | 21 | else: | ||
| 22 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class Potion: | 25 | class Potion: | ||
| 26 | def __init__(self, effects, duration=2, intensities=None): | 26 | def __init__(self, effects, duration=2, intensities=None): | ||
| 27 | self.effects = {} | 27 | self.effects = {} | ||
| 28 | self.is_itself = True | 28 | self.is_itself = True | ||
| 29 | self.is_used = False | 29 | self.is_used = False | ||
| 30 | 30 | ||||
| 31 | for effect_name in effects: | 31 | for effect_name in effects: | ||
| 32 | effect_func = effects[effect_name] | 32 | effect_func = effects[effect_name] | ||
| 33 | effects[effect_name].is_called = False | 33 | effects[effect_name].is_called = False | ||
| 34 | 34 | ||||
| 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 36 | 36 | ||||
| 37 | self.duration = duration | 37 | self.duration = duration | ||
| 38 | 38 | ||||
| 39 | def effect(self, target, is_continuing=False): | 39 | def effect(self, target, is_continuing=False): | ||
| 40 | if not is_continuing and not self.is_itself: | 40 | if not is_continuing and not self.is_itself: | ||
| 41 | raise TypeError("Potion is now part of something bigger than itself.") | 41 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 42 | if self.is_used and not is_continuing: | 42 | if self.is_used and not is_continuing: | ||
| 43 | raise TypeError("Potion is depleted.") | 43 | raise TypeError("Potion is depleted.") | ||
| 44 | self.is_used = True | 44 | self.is_used = True | ||
| 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | ||
| 46 | 46 | ||||
| 47 | for effect in self.effects.values(): | 47 | for effect in self.effects.values(): | ||
| n | n | 48 | if not effect.is_active: | ||
| 49 | continue | ||||
| 48 | effect(target, True) | 50 | effect(target, True) | ||
| 49 | 51 | ||||
| 50 | def __getattr__(self, effect_name): | 52 | def __getattr__(self, effect_name): | ||
| 51 | if(effect_name not in self.effects): | 53 | if(effect_name not in self.effects): | ||
| 52 | raise TypeError("Effect is not in potion.") | 54 | raise TypeError("Effect is not in potion.") | ||
| 53 | 55 | ||||
| 54 | if not self.effects[effect_name].is_active: | 56 | if not self.effects[effect_name].is_active: | ||
| 55 | raise TypeError("Effect is depleted.") | 57 | raise TypeError("Effect is depleted.") | ||
| 56 | 58 | ||||
| 57 | if not self.is_itself: | 59 | if not self.is_itself: | ||
| 58 | raise TypeError("Potion is now part of something bigger than itself.") | 60 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 59 | 61 | ||||
| 60 | self.effects[effect_name].is_active = False | 62 | self.effects[effect_name].is_active = False | ||
| 61 | 63 | ||||
| 62 | return self.effects[effect_name] | 64 | return self.effects[effect_name] | ||
| 63 | 65 | ||||
| 64 | def __add__(self, other): | 66 | def __add__(self, other): | ||
| 65 | """Combining two potions.""" | 67 | """Combining two potions.""" | ||
| 66 | if not self.is_itself or not other.is_itself: | 68 | if not self.is_itself or not other.is_itself: | ||
| 67 | raise TypeError("Potion is now part of something bigger than itself.") | 69 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 68 | 70 | ||||
| 69 | if self.is_used: | 71 | if self.is_used: | ||
| 70 | raise TypeError("Potion is depleted.") | 72 | raise TypeError("Potion is depleted.") | ||
| 71 | 73 | ||||
| 72 | effects = {} | 74 | effects = {} | ||
| 73 | intensities = {} | 75 | intensities = {} | ||
| 74 | 76 | ||||
| 75 | for effect_name, effect in self.effects.items(): | 77 | for effect_name, effect in self.effects.items(): | ||
| 76 | effects[effect_name] = effect.func | 78 | effects[effect_name] = effect.func | ||
| 77 | intensities[effect_name] = effect.intensity | 79 | intensities[effect_name] = effect.intensity | ||
| 78 | 80 | ||||
| 79 | for effect_name, effect in other.effects.items(): | 81 | for effect_name, effect in other.effects.items(): | ||
| 80 | if effect_name not in effects: | 82 | if effect_name not in effects: | ||
| 81 | effects[effect_name] = effect.func | 83 | effects[effect_name] = effect.func | ||
| 82 | intensities[effect_name] = effect.intensity | 84 | intensities[effect_name] = effect.intensity | ||
| 83 | else: | 85 | else: | ||
| 84 | intensities[effect_name] += effect.intensity | 86 | intensities[effect_name] += effect.intensity | ||
| 85 | 87 | ||||
| 86 | self.is_itself = False | 88 | self.is_itself = False | ||
| 87 | other.is_itself = False | 89 | other.is_itself = False | ||
| 88 | return Potion(effects, max(self.duration, other.duration), intensities) | 90 | return Potion(effects, max(self.duration, other.duration), intensities) | ||
| 89 | 91 | ||||
| 90 | def __mul__(self, number): | 92 | def __mul__(self, number): | ||
| 91 | """Potentiation of two potions.""" | 93 | """Potentiation of two potions.""" | ||
| 92 | if not self.is_itself: | 94 | if not self.is_itself: | ||
| 93 | raise TypeError("Potion is now part of something bigger than itself.") | 95 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 94 | 96 | ||||
| 95 | if self.is_used: | 97 | if self.is_used: | ||
| 96 | raise TypeError("Potion is depleted.") | 98 | raise TypeError("Potion is depleted.") | ||
| 97 | 99 | ||||
| 98 | effects = {} | 100 | effects = {} | ||
| 99 | intensities = {} | 101 | intensities = {} | ||
| 100 | 102 | ||||
| 101 | for effect_name, effect in self.effects.items(): | 103 | for effect_name, effect in self.effects.items(): | ||
| 102 | intensities[effect_name] = effect.intensity * number | 104 | intensities[effect_name] = effect.intensity * number | ||
| 103 | 105 | ||||
| 104 | if intensities[effect_name] % 1 <= 0.5: | 106 | if intensities[effect_name] % 1 <= 0.5: | ||
| 105 | intensities[effect_name] = math.floor(intensities[effect_name]) | 107 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 106 | else: | 108 | else: | ||
| 107 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 109 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 108 | 110 | ||||
| 109 | effects[effect_name] = effect.func | 111 | effects[effect_name] = effect.func | ||
| 110 | 112 | ||||
| 111 | self.is_itself = False | 113 | self.is_itself = False | ||
| 112 | return Potion(effects, self.duration, intensities) | 114 | return Potion(effects, self.duration, intensities) | ||
| 113 | 115 | ||||
| 114 | def __sub__(self, other): | 116 | def __sub__(self, other): | ||
| 115 | """Purification of two potions.""" | 117 | """Purification of two potions.""" | ||
| 116 | if not self.is_itself or not other.is_itself: | 118 | if not self.is_itself or not other.is_itself: | ||
| 117 | raise TypeError("Potion is now part of something bigger than itself.") | 119 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 118 | 120 | ||||
| 119 | if self.is_used: | 121 | if self.is_used: | ||
| 120 | raise TypeError("Potion is depleted.") | 122 | raise TypeError("Potion is depleted.") | ||
| 121 | 123 | ||||
| 122 | for effect in other.effects: | 124 | for effect in other.effects: | ||
| 123 | if effect not in self.effects: | 125 | if effect not in self.effects: | ||
| 124 | raise TypeError("Effect is not in potion.") | 126 | raise TypeError("Effect is not in potion.") | ||
| 125 | 127 | ||||
| 126 | effects = {} | 128 | effects = {} | ||
| 127 | intensities = {} | 129 | intensities = {} | ||
| 128 | 130 | ||||
| 129 | for effect_name, effect in self.effects.items(): | 131 | for effect_name, effect in self.effects.items(): | ||
| 130 | intensities[effect_name] = effect.intensity | 132 | intensities[effect_name] = effect.intensity | ||
| 131 | effects[effect_name] = effect.func | 133 | effects[effect_name] = effect.func | ||
| 132 | 134 | ||||
| 133 | for effect in other.effects: | 135 | for effect in other.effects: | ||
| 134 | intensities[effect] -= other.effects[effect].intensity | 136 | intensities[effect] -= other.effects[effect].intensity | ||
| 135 | 137 | ||||
| 136 | if intensities[effect] <= 0: | 138 | if intensities[effect] <= 0: | ||
| 137 | effects.pop(effect) | 139 | effects.pop(effect) | ||
| 138 | intensities.pop(effect) | 140 | intensities.pop(effect) | ||
| 139 | 141 | ||||
| 140 | self.is_itself = False | 142 | self.is_itself = False | ||
| 141 | other.is_itself = False | 143 | other.is_itself = False | ||
| 142 | return Potion(effects, self.duration, intensities) | 144 | return Potion(effects, self.duration, intensities) | ||
| 143 | 145 | ||||
| 144 | def __truediv__(self, number:int): | 146 | def __truediv__(self, number:int): | ||
| 145 | """Dividing two potions.""" | 147 | """Dividing two potions.""" | ||
| 146 | if not self.is_itself: | 148 | if not self.is_itself: | ||
| 147 | raise TypeError("Potion is now part of something bigger than itself.") | 149 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 148 | 150 | ||||
| 149 | if self.is_used: | 151 | if self.is_used: | ||
| 150 | raise TypeError("Potion is depleted.") | 152 | raise TypeError("Potion is depleted.") | ||
| 151 | 153 | ||||
| 152 | effects = {} | 154 | effects = {} | ||
| 153 | intensities = {} | 155 | intensities = {} | ||
| 154 | 156 | ||||
| 155 | for effect_name, effect in self.effects.items(): | 157 | for effect_name, effect in self.effects.items(): | ||
| 156 | intensities[effect_name] = int(effect.intensity) / number | 158 | intensities[effect_name] = int(effect.intensity) / number | ||
| 157 | effects[effect_name] = effect.func | 159 | effects[effect_name] = effect.func | ||
| 158 | 160 | ||||
| 159 | if intensities[effect_name] % 1 <= 0.5: | 161 | if intensities[effect_name] % 1 <= 0.5: | ||
| 160 | intensities[effect_name] = math.floor(intensities[effect_name]) | 162 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 161 | else: | 163 | else: | ||
| 162 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 164 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 163 | 165 | ||||
| 164 | self.is_itself = False | 166 | self.is_itself = False | ||
| 165 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | 167 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | ||
| 166 | 168 | ||||
| 167 | def __eq__(self, other): | 169 | def __eq__(self, other): | ||
| 168 | for effect in self.effects: | 170 | for effect in self.effects: | ||
| 169 | if effect not in other.effects or self.effects[effect].intensity != other.effects[effect].intensity: | 171 | if effect not in other.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||
| 170 | return False | 172 | return False | ||
| 171 | for effect in other.effects: | 173 | for effect in other.effects: | ||
| 172 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | 174 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||
| 173 | return False | 175 | return False | ||
| 174 | 176 | ||||
| 175 | return True | 177 | return True | ||
| 176 | 178 | ||||
| 177 | def __lt__(self, other): | 179 | def __lt__(self, other): | ||
| n | 178 | for effect in self.effects: | n | 180 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) |
| 179 | if effect not in other.effects or self.effects[effect].intensity > other.effects[effect].intensity: | 181 | |||
| 180 | return False | ||||
| 181 | return True | ||||
| 182 | |||||
| 183 | def __gt__(self, other): | 182 | def __gt__(self, other): | ||
| n | 184 | for effect in other.effects: | n | 183 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) |
| 185 | if effect not in self.effects or self.effects[effect].intensity < other.effects[effect].intensity: | ||||
| 186 | return False | ||||
| 187 | 184 | ||||
| 188 | 185 | ||||
| 189 | class Target: | 186 | class Target: | ||
| 190 | def __init__(self, target): | 187 | def __init__(self, target): | ||
| 191 | self.curr_target = target | 188 | self.curr_target = target | ||
| 192 | self.original = copy.deepcopy(target.__dict__) | 189 | self.original = copy.deepcopy(target.__dict__) | ||
| 193 | 190 | ||||
| 194 | @property | 191 | @property | ||
| 195 | def original_state(self): | 192 | def original_state(self): | ||
| 196 | return copy.deepcopy(self.original) | 193 | return copy.deepcopy(self.original) | ||
| 197 | 194 | ||||
| 198 | def back_to_original(self): | 195 | def back_to_original(self): | ||
| 199 | self.curr_target.__dict__ = self.original_state | 196 | self.curr_target.__dict__ = self.original_state | ||
| 200 | 197 | ||||
| 201 | def __eq__(self, other): | 198 | def __eq__(self, other): | ||
| 202 | if isinstance(other, Target): | 199 | if isinstance(other, Target): | ||
| 203 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | 200 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | ||
| 204 | return False | 201 | return False | ||
| 205 | 202 | ||||
| 206 | def __hash__(self): | 203 | def __hash__(self): | ||
| 207 | return hash(self.curr_target.__class__.__name__) | 204 | return hash(self.curr_target.__class__.__name__) | ||
| 208 | 205 | ||||
| 209 | class ГоспожатаПоХимия: | 206 | class ГоспожатаПоХимия: | ||
| 210 | def __init__(self): | 207 | def __init__(self): | ||
| 211 | self.active_potions = {} | 208 | self.active_potions = {} | ||
| 212 | 209 | ||||
| 213 | def apply(self, target_obj, potion): | 210 | def apply(self, target_obj, potion): | ||
| 214 | target = Target(target_obj) | 211 | target = Target(target_obj) | ||
| 215 | if self.active_potions.get(target) is None: | 212 | if self.active_potions.get(target) is None: | ||
| 216 | self.active_potions[target] = [] | 213 | self.active_potions[target] = [] | ||
| 217 | 214 | ||||
| 218 | potion.effect(target.curr_target) | 215 | potion.effect(target.curr_target) | ||
| 219 | self.active_potions[target].append([potion.duration - 1, potion]) | 216 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 220 | 217 | ||||
| 221 | def tick(self): | 218 | def tick(self): | ||
| 222 | for target in self.active_potions: | 219 | for target in self.active_potions: | ||
| 223 | target.back_to_original() | 220 | target.back_to_original() | ||
| 224 | to_remove = [] | 221 | to_remove = [] | ||
| 225 | for curr in self.active_potions[target]: | 222 | for curr in self.active_potions[target]: | ||
| 226 | remaining_time, potion = curr | 223 | remaining_time, potion = curr | ||
| 227 | curr[0] -= 1 | 224 | curr[0] -= 1 | ||
| 228 | if remaining_time <= 0: | 225 | if remaining_time <= 0: | ||
| 229 | to_remove.append(curr) | 226 | to_remove.append(curr) | ||
| 230 | else: | 227 | else: | ||
| 231 | potion.effect(target.curr_target, True) | 228 | potion.effect(target.curr_target, True) | ||
| 232 | for curr in to_remove: | 229 | for curr in to_remove: | ||
| 233 | self.active_potions[target].remove(curr) | 230 | self.active_potions[target].remove(curr) | ||
| 234 | 231 | ||||
| t | t | 232 | |||
| 233 | def get_grow_potion(): | ||||
| 234 | effects = {'grow': lambda target: setattr( | ||||
| 235 | target, 'size', target.size*2)} | ||||
| 236 | |||||
| 237 | grow_potion = Potion(effects, duration=2) | ||||
| 238 | |||||
| 239 | return grow_potion | ||||
| 235 | 240 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| 2 | import math | 2 | import math | ||
| 3 | 3 | ||||
| 4 | class Effect: | 4 | class Effect: | ||
| 5 | def __init__(self, name, func, intensity=1): | 5 | def __init__(self, name, func, intensity=1): | ||
| 6 | self.name = name | 6 | self.name = name | ||
| 7 | self.func = func | 7 | self.func = func | ||
| 8 | self.is_used = False | 8 | self.is_used = False | ||
| 9 | self.intensity = intensity | 9 | self.intensity = intensity | ||
| 10 | self.is_active = True | 10 | self.is_active = True | ||
| 11 | 11 | ||||
| 12 | @property | 12 | @property | ||
| 13 | def molecular_mass(self): | 13 | def molecular_mass(self): | ||
| 14 | return sum([ord(letter) for letter in self.name]) | 14 | return sum([ord(letter) for letter in self.name]) | ||
| 15 | 15 | ||||
| 16 | def __call__(self, target, is_continuing=False): | 16 | def __call__(self, target, is_continuing=False): | ||
| 17 | if not self.is_used or is_continuing: | 17 | if not self.is_used or is_continuing: | ||
| 18 | for _ in range(self.intensity): | 18 | for _ in range(self.intensity): | ||
| 19 | self.func(target) | 19 | self.func(target) | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | else: | 21 | else: | ||
| 22 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class Potion: | 25 | class Potion: | ||
| 26 | def __init__(self, effects, duration=2, intensities=None): | 26 | def __init__(self, effects, duration=2, intensities=None): | ||
| 27 | self.effects = {} | 27 | self.effects = {} | ||
| 28 | self.is_itself = True | 28 | self.is_itself = True | ||
| 29 | self.is_used = False | 29 | self.is_used = False | ||
| 30 | 30 | ||||
| 31 | for effect_name in effects: | 31 | for effect_name in effects: | ||
| 32 | effect_func = effects[effect_name] | 32 | effect_func = effects[effect_name] | ||
| 33 | effects[effect_name].is_called = False | 33 | effects[effect_name].is_called = False | ||
| 34 | 34 | ||||
| 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 36 | 36 | ||||
| 37 | self.duration = duration | 37 | self.duration = duration | ||
| 38 | 38 | ||||
| 39 | def effect(self, target, is_continuing=False): | 39 | def effect(self, target, is_continuing=False): | ||
| 40 | if not is_continuing and not self.is_itself: | 40 | if not is_continuing and not self.is_itself: | ||
| 41 | raise TypeError("Potion is now part of something bigger than itself.") | 41 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 42 | if self.is_used and not is_continuing: | 42 | if self.is_used and not is_continuing: | ||
| 43 | raise TypeError("Potion is depleted.") | 43 | raise TypeError("Potion is depleted.") | ||
| 44 | self.is_used = True | 44 | self.is_used = True | ||
| 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | ||
| 46 | 46 | ||||
| 47 | for effect in self.effects.values(): | 47 | for effect in self.effects.values(): | ||
| 48 | effect(target, True) | 48 | effect(target, True) | ||
| 49 | 49 | ||||
| 50 | def __getattr__(self, effect_name): | 50 | def __getattr__(self, effect_name): | ||
| 51 | if(effect_name not in self.effects): | 51 | if(effect_name not in self.effects): | ||
| 52 | raise TypeError("Effect is not in potion.") | 52 | raise TypeError("Effect is not in potion.") | ||
| 53 | 53 | ||||
| 54 | if not self.effects[effect_name].is_active: | 54 | if not self.effects[effect_name].is_active: | ||
| 55 | raise TypeError("Effect is depleted.") | 55 | raise TypeError("Effect is depleted.") | ||
| 56 | 56 | ||||
| 57 | if not self.is_itself: | 57 | if not self.is_itself: | ||
| 58 | raise TypeError("Potion is now part of something bigger than itself.") | 58 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 59 | 59 | ||||
| 60 | self.effects[effect_name].is_active = False | 60 | self.effects[effect_name].is_active = False | ||
| 61 | 61 | ||||
| 62 | return self.effects[effect_name] | 62 | return self.effects[effect_name] | ||
| 63 | 63 | ||||
| 64 | def __add__(self, other): | 64 | def __add__(self, other): | ||
| 65 | """Combining two potions.""" | 65 | """Combining two potions.""" | ||
| 66 | if not self.is_itself or not other.is_itself: | 66 | if not self.is_itself or not other.is_itself: | ||
| 67 | raise TypeError("Potion is now part of something bigger than itself.") | 67 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 68 | 68 | ||||
| 69 | if self.is_used: | 69 | if self.is_used: | ||
| 70 | raise TypeError("Potion is depleted.") | 70 | raise TypeError("Potion is depleted.") | ||
| 71 | 71 | ||||
| 72 | effects = {} | 72 | effects = {} | ||
| 73 | intensities = {} | 73 | intensities = {} | ||
| 74 | 74 | ||||
| 75 | for effect_name, effect in self.effects.items(): | 75 | for effect_name, effect in self.effects.items(): | ||
| 76 | effects[effect_name] = effect.func | 76 | effects[effect_name] = effect.func | ||
| 77 | intensities[effect_name] = effect.intensity | 77 | intensities[effect_name] = effect.intensity | ||
| 78 | 78 | ||||
| 79 | for effect_name, effect in other.effects.items(): | 79 | for effect_name, effect in other.effects.items(): | ||
| 80 | if effect_name not in effects: | 80 | if effect_name not in effects: | ||
| 81 | effects[effect_name] = effect.func | 81 | effects[effect_name] = effect.func | ||
| 82 | intensities[effect_name] = effect.intensity | 82 | intensities[effect_name] = effect.intensity | ||
| 83 | else: | 83 | else: | ||
| 84 | intensities[effect_name] += effect.intensity | 84 | intensities[effect_name] += effect.intensity | ||
| 85 | 85 | ||||
| 86 | self.is_itself = False | 86 | self.is_itself = False | ||
| 87 | other.is_itself = False | 87 | other.is_itself = False | ||
| 88 | return Potion(effects, max(self.duration, other.duration), intensities) | 88 | return Potion(effects, max(self.duration, other.duration), intensities) | ||
| 89 | 89 | ||||
| 90 | def __mul__(self, number): | 90 | def __mul__(self, number): | ||
| 91 | """Potentiation of two potions.""" | 91 | """Potentiation of two potions.""" | ||
| 92 | if not self.is_itself: | 92 | if not self.is_itself: | ||
| 93 | raise TypeError("Potion is now part of something bigger than itself.") | 93 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 94 | 94 | ||||
| 95 | if self.is_used: | 95 | if self.is_used: | ||
| 96 | raise TypeError("Potion is depleted.") | 96 | raise TypeError("Potion is depleted.") | ||
| 97 | 97 | ||||
| 98 | effects = {} | 98 | effects = {} | ||
| 99 | intensities = {} | 99 | intensities = {} | ||
| 100 | 100 | ||||
| 101 | for effect_name, effect in self.effects.items(): | 101 | for effect_name, effect in self.effects.items(): | ||
| 102 | intensities[effect_name] = effect.intensity * number | 102 | intensities[effect_name] = effect.intensity * number | ||
| 103 | 103 | ||||
| 104 | if intensities[effect_name] % 1 <= 0.5: | 104 | if intensities[effect_name] % 1 <= 0.5: | ||
| 105 | intensities[effect_name] = math.floor(intensities[effect_name]) | 105 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 106 | else: | 106 | else: | ||
| 107 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 107 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 108 | 108 | ||||
| 109 | effects[effect_name] = effect.func | 109 | effects[effect_name] = effect.func | ||
| 110 | 110 | ||||
| 111 | self.is_itself = False | 111 | self.is_itself = False | ||
| 112 | return Potion(effects, self.duration, intensities) | 112 | return Potion(effects, self.duration, intensities) | ||
| 113 | 113 | ||||
| 114 | def __sub__(self, other): | 114 | def __sub__(self, other): | ||
| 115 | """Purification of two potions.""" | 115 | """Purification of two potions.""" | ||
| 116 | if not self.is_itself or not other.is_itself: | 116 | if not self.is_itself or not other.is_itself: | ||
| 117 | raise TypeError("Potion is now part of something bigger than itself.") | 117 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 118 | 118 | ||||
| 119 | if self.is_used: | 119 | if self.is_used: | ||
| 120 | raise TypeError("Potion is depleted.") | 120 | raise TypeError("Potion is depleted.") | ||
| 121 | 121 | ||||
| 122 | for effect in other.effects: | 122 | for effect in other.effects: | ||
| 123 | if effect not in self.effects: | 123 | if effect not in self.effects: | ||
| 124 | raise TypeError("Effect is not in potion.") | 124 | raise TypeError("Effect is not in potion.") | ||
| 125 | 125 | ||||
| 126 | effects = {} | 126 | effects = {} | ||
| 127 | intensities = {} | 127 | intensities = {} | ||
| 128 | 128 | ||||
| 129 | for effect_name, effect in self.effects.items(): | 129 | for effect_name, effect in self.effects.items(): | ||
| 130 | intensities[effect_name] = effect.intensity | 130 | intensities[effect_name] = effect.intensity | ||
| 131 | effects[effect_name] = effect.func | 131 | effects[effect_name] = effect.func | ||
| 132 | 132 | ||||
| 133 | for effect in other.effects: | 133 | for effect in other.effects: | ||
| 134 | intensities[effect] -= other.effects[effect].intensity | 134 | intensities[effect] -= other.effects[effect].intensity | ||
| 135 | 135 | ||||
| 136 | if intensities[effect] <= 0: | 136 | if intensities[effect] <= 0: | ||
| 137 | effects.pop(effect) | 137 | effects.pop(effect) | ||
| 138 | intensities.pop(effect) | 138 | intensities.pop(effect) | ||
| 139 | 139 | ||||
| 140 | self.is_itself = False | 140 | self.is_itself = False | ||
| 141 | other.is_itself = False | 141 | other.is_itself = False | ||
| 142 | return Potion(effects, self.duration, intensities) | 142 | return Potion(effects, self.duration, intensities) | ||
| 143 | 143 | ||||
| 144 | def __truediv__(self, number:int): | 144 | def __truediv__(self, number:int): | ||
| 145 | """Dividing two potions.""" | 145 | """Dividing two potions.""" | ||
| 146 | if not self.is_itself: | 146 | if not self.is_itself: | ||
| 147 | raise TypeError("Potion is now part of something bigger than itself.") | 147 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 148 | 148 | ||||
| 149 | if self.is_used: | 149 | if self.is_used: | ||
| 150 | raise TypeError("Potion is depleted.") | 150 | raise TypeError("Potion is depleted.") | ||
| 151 | 151 | ||||
| 152 | effects = {} | 152 | effects = {} | ||
| 153 | intensities = {} | 153 | intensities = {} | ||
| 154 | 154 | ||||
| 155 | for effect_name, effect in self.effects.items(): | 155 | for effect_name, effect in self.effects.items(): | ||
| 156 | intensities[effect_name] = int(effect.intensity) / number | 156 | intensities[effect_name] = int(effect.intensity) / number | ||
| 157 | effects[effect_name] = effect.func | 157 | effects[effect_name] = effect.func | ||
| 158 | 158 | ||||
| 159 | if intensities[effect_name] % 1 <= 0.5: | 159 | if intensities[effect_name] % 1 <= 0.5: | ||
| 160 | intensities[effect_name] = math.floor(intensities[effect_name]) | 160 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||
| 161 | else: | 161 | else: | ||
| 162 | intensities[effect_name] = math.ceil(intensities[effect_name]) | 162 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||
| 163 | 163 | ||||
| 164 | self.is_itself = False | 164 | self.is_itself = False | ||
| 165 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | 165 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | ||
| 166 | 166 | ||||
| 167 | def __eq__(self, other): | 167 | def __eq__(self, other): | ||
| n | 168 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | n | 168 | for effect in self.effects: |
| 169 | if effect not in other.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||||
| 170 | return False | ||||
| 171 | for effect in other.effects: | ||||
| 172 | if effect not in self.effects or self.effects[effect].intensity != other.effects[effect].intensity: | ||||
| 173 | return False | ||||
| 174 | |||||
| 175 | return True | ||||
| 169 | 176 | ||||
| 170 | def __lt__(self, other): | 177 | def __lt__(self, other): | ||
| n | 171 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | n | 178 | for effect in self.effects: |
| 179 | if effect not in other.effects or self.effects[effect].intensity > other.effects[effect].intensity: | ||||
| 180 | return False | ||||
| 181 | return True | ||||
| 172 | 182 | ||||
| 173 | def __gt__(self, other): | 183 | def __gt__(self, other): | ||
| n | 174 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | n | 184 | for effect in other.effects: |
| 185 | if effect not in self.effects or self.effects[effect].intensity < other.effects[effect].intensity: | ||||
| 186 | return False | ||||
| 175 | 187 | ||||
| 176 | 188 | ||||
| 177 | class Target: | 189 | class Target: | ||
| 178 | def __init__(self, target): | 190 | def __init__(self, target): | ||
| 179 | self.curr_target = target | 191 | self.curr_target = target | ||
| 180 | self.original = copy.deepcopy(target.__dict__) | 192 | self.original = copy.deepcopy(target.__dict__) | ||
| 181 | 193 | ||||
| 182 | @property | 194 | @property | ||
| 183 | def original_state(self): | 195 | def original_state(self): | ||
| 184 | return copy.deepcopy(self.original) | 196 | return copy.deepcopy(self.original) | ||
| 185 | 197 | ||||
| 186 | def back_to_original(self): | 198 | def back_to_original(self): | ||
| 187 | self.curr_target.__dict__ = self.original_state | 199 | self.curr_target.__dict__ = self.original_state | ||
| 188 | 200 | ||||
| 189 | def __eq__(self, other): | 201 | def __eq__(self, other): | ||
| 190 | if isinstance(other, Target): | 202 | if isinstance(other, Target): | ||
| 191 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | 203 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | ||
| 192 | return False | 204 | return False | ||
| 193 | 205 | ||||
| 194 | def __hash__(self): | 206 | def __hash__(self): | ||
| 195 | return hash(self.curr_target.__class__.__name__) | 207 | return hash(self.curr_target.__class__.__name__) | ||
| 196 | 208 | ||||
| 197 | class ГоспожатаПоХимия: | 209 | class ГоспожатаПоХимия: | ||
| 198 | def __init__(self): | 210 | def __init__(self): | ||
| 199 | self.active_potions = {} | 211 | self.active_potions = {} | ||
| 200 | 212 | ||||
| 201 | def apply(self, target_obj, potion): | 213 | def apply(self, target_obj, potion): | ||
| 202 | target = Target(target_obj) | 214 | target = Target(target_obj) | ||
| 203 | if self.active_potions.get(target) is None: | 215 | if self.active_potions.get(target) is None: | ||
| 204 | self.active_potions[target] = [] | 216 | self.active_potions[target] = [] | ||
| 205 | 217 | ||||
| 206 | potion.effect(target.curr_target) | 218 | potion.effect(target.curr_target) | ||
| 207 | self.active_potions[target].append([potion.duration - 1, potion]) | 219 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 208 | 220 | ||||
| 209 | def tick(self): | 221 | def tick(self): | ||
| 210 | for target in self.active_potions: | 222 | for target in self.active_potions: | ||
| 211 | target.back_to_original() | 223 | target.back_to_original() | ||
| 212 | to_remove = [] | 224 | to_remove = [] | ||
| 213 | for curr in self.active_potions[target]: | 225 | for curr in self.active_potions[target]: | ||
| 214 | remaining_time, potion = curr | 226 | remaining_time, potion = curr | ||
| 215 | curr[0] -= 1 | 227 | curr[0] -= 1 | ||
| 216 | if remaining_time <= 0: | 228 | if remaining_time <= 0: | ||
| 217 | to_remove.append(curr) | 229 | to_remove.append(curr) | ||
| 218 | else: | 230 | else: | ||
| 219 | potion.effect(target.curr_target, True) | 231 | potion.effect(target.curr_target, True) | ||
| 220 | for curr in to_remove: | 232 | for curr in to_remove: | ||
| 221 | self.active_potions[target].remove(curr) | 233 | self.active_potions[target].remove(curr) | ||
| t | t | 234 | |||
| 235 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| n | n | 2 | import math | ||
| 2 | 3 | ||||
| 3 | class Effect: | 4 | class Effect: | ||
| 4 | def __init__(self, name, func, intensity=1): | 5 | def __init__(self, name, func, intensity=1): | ||
| 5 | self.name = name | 6 | self.name = name | ||
| 6 | self.func = func | 7 | self.func = func | ||
| 7 | self.is_used = False | 8 | self.is_used = False | ||
| 8 | self.intensity = intensity | 9 | self.intensity = intensity | ||
| n | n | 10 | self.is_active = True | ||
| 9 | 11 | ||||
| 10 | @property | 12 | @property | ||
| 11 | def molecular_mass(self): | 13 | def molecular_mass(self): | ||
| 12 | return sum([ord(letter) for letter in self.name]) | 14 | return sum([ord(letter) for letter in self.name]) | ||
| n | 13 | n | 15 | ||
| 14 | def __call__(self, target, is_continuing=False): | 16 | def __call__(self, target, is_continuing=False): | ||
| 15 | if not self.is_used or is_continuing: | 17 | if not self.is_used or is_continuing: | ||
| 16 | for _ in range(self.intensity): | 18 | for _ in range(self.intensity): | ||
| 17 | self.func(target) | 19 | self.func(target) | ||
| n | n | 20 | self.is_used = True | ||
| 18 | else: | 21 | else: | ||
| 19 | raise TypeError("Effect is depleted.") | 22 | raise TypeError("Effect is depleted.") | ||
| n | 20 | self.is_used = True | n | ||
| 21 | 23 | ||||
| 22 | 24 | ||||
| 23 | class Potion: | 25 | class Potion: | ||
| 24 | def __init__(self, effects, duration=2, intensities=None): | 26 | def __init__(self, effects, duration=2, intensities=None): | ||
| 25 | self.effects = {} | 27 | self.effects = {} | ||
| 26 | self.is_itself = True | 28 | self.is_itself = True | ||
| n | n | 29 | self.is_used = False | ||
| 27 | 30 | ||||
| 28 | for effect_name in effects: | 31 | for effect_name in effects: | ||
| 29 | effect_func = effects[effect_name] | 32 | effect_func = effects[effect_name] | ||
| 30 | effects[effect_name].is_called = False | 33 | effects[effect_name].is_called = False | ||
| 31 | 34 | ||||
| 32 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 35 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 33 | 36 | ||||
| 34 | self.duration = duration | 37 | self.duration = duration | ||
| 35 | 38 | ||||
| 36 | def effect(self, target, is_continuing=False): | 39 | def effect(self, target, is_continuing=False): | ||
| n | 37 | if not is_continuing or not self.is_itself: | n | 40 | if not is_continuing and not self.is_itself: |
| 38 | raise TypeError("Potion is now part of something bigger than itself.") | 41 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| n | 39 | n | 42 | if self.is_used and not is_continuing: | |
| 43 | raise TypeError("Potion is depleted.") | ||||
| 44 | self.is_used = True | ||||
| 40 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass)) | 45 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass, reverse=True)) | ||
| 41 | 46 | ||||
| 42 | for effect in self.effects.values(): | 47 | for effect in self.effects.values(): | ||
| 43 | effect(target, True) | 48 | effect(target, True) | ||
| 44 | 49 | ||||
| 45 | def __getattr__(self, effect_name): | 50 | def __getattr__(self, effect_name): | ||
| 46 | if(effect_name not in self.effects): | 51 | if(effect_name not in self.effects): | ||
| 47 | raise TypeError("Effect is not in potion.") | 52 | raise TypeError("Effect is not in potion.") | ||
| 48 | 53 | ||||
| n | 49 | self.is_itself = False | n | 54 | if not self.effects[effect_name].is_active: |
| 55 | raise TypeError("Effect is depleted.") | ||||
| 56 | |||||
| 57 | if not self.is_itself: | ||||
| 58 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 59 | |||||
| 60 | self.effects[effect_name].is_active = False | ||||
| 61 | |||||
| 50 | return self.effects[effect_name] | 62 | return self.effects[effect_name] | ||
| 51 | 63 | ||||
| 52 | def __add__(self, other): | 64 | def __add__(self, other): | ||
| 53 | """Combining two potions.""" | 65 | """Combining two potions.""" | ||
| n | 54 | n | 66 | if not self.is_itself or not other.is_itself: | |
| 67 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 68 | |||||
| 69 | if self.is_used: | ||||
| 70 | raise TypeError("Potion is depleted.") | ||||
| 71 | |||||
| 55 | effects = {} | 72 | effects = {} | ||
| 56 | intensities = {} | 73 | intensities = {} | ||
| 57 | 74 | ||||
| 58 | for effect_name, effect in self.effects.items(): | 75 | for effect_name, effect in self.effects.items(): | ||
| n | 59 | effects[effect_name] = copy.deepcopy(effect) | n | 76 | effects[effect_name] = effect.func |
| 60 | intensities[effect_name] = 1 | 77 | intensities[effect_name] = effect.intensity | ||
| 61 | 78 | ||||
| 62 | for effect_name, effect in other.effects.items(): | 79 | for effect_name, effect in other.effects.items(): | ||
| 63 | if effect_name not in effects: | 80 | if effect_name not in effects: | ||
| n | 64 | effects[effect_name] = copy.deepcopy(effect) | n | 81 | effects[effect_name] = effect.func |
| 65 | intensities[effect_name] = 1 | 82 | intensities[effect_name] = effect.intensity | ||
| 66 | else: | 83 | else: | ||
| 67 | intensities[effect_name] += effect.intensity | 84 | intensities[effect_name] += effect.intensity | ||
| 68 | 85 | ||||
| 69 | self.is_itself = False | 86 | self.is_itself = False | ||
| n | n | 87 | other.is_itself = False | ||
| 70 | return Potion(effects, self.duration + other.duration, intensities) | 88 | return Potion(effects, max(self.duration, other.duration), intensities) | ||
| 71 | 89 | ||||
| n | 72 | #Потенцииране и Разреждане | n | ||
| 73 | def __mul__(self, number): | 90 | def __mul__(self, number): | ||
| 74 | """Potentiation of two potions.""" | 91 | """Potentiation of two potions.""" | ||
| n | 75 | n | 92 | if not self.is_itself: | |
| 93 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 94 | |||||
| 95 | if self.is_used: | ||||
| 96 | raise TypeError("Potion is depleted.") | ||||
| 97 | |||||
| 76 | effects = {} | 98 | effects = {} | ||
| 77 | intensities = {} | 99 | intensities = {} | ||
| 78 | 100 | ||||
| 79 | for effect_name, effect in self.effects.items(): | 101 | for effect_name, effect in self.effects.items(): | ||
| n | 80 | intensities[effect_name] = round(effect.intensity * number) | n | 102 | intensities[effect_name] = effect.intensity * number |
| 103 | |||||
| 104 | if intensities[effect_name] % 1 <= 0.5: | ||||
| 105 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||||
| 106 | else: | ||||
| 107 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||||
| 108 | |||||
| 81 | effects[effect_name] = effect.func | 109 | effects[effect_name] = effect.func | ||
| n | 82 | n | 110 | ||
| 111 | self.is_itself = False | ||||
| 83 | return Potion(effects, self.duration, intensities) | 112 | return Potion(effects, self.duration, intensities) | ||
| 84 | 113 | ||||
| 85 | def __sub__(self, other): | 114 | def __sub__(self, other): | ||
| 86 | """Purification of two potions.""" | 115 | """Purification of two potions.""" | ||
| n | 87 | n | 116 | if not self.is_itself or not other.is_itself: | |
| 117 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 118 | |||||
| 119 | if self.is_used: | ||||
| 120 | raise TypeError("Potion is depleted.") | ||||
| 121 | |||||
| 88 | for effect in other.effects: | 122 | for effect in other.effects: | ||
| 89 | if effect not in self.effects: | 123 | if effect not in self.effects: | ||
| 90 | raise TypeError("Effect is not in potion.") | 124 | raise TypeError("Effect is not in potion.") | ||
| 91 | 125 | ||||
| n | n | 126 | effects = {} | ||
| 127 | intensities = {} | ||||
| 128 | |||||
| 129 | for effect_name, effect in self.effects.items(): | ||||
| 130 | intensities[effect_name] = effect.intensity | ||||
| 131 | effects[effect_name] = effect.func | ||||
| 132 | |||||
| 92 | for effect in other.effects: | 133 | for effect in other.effects: | ||
| n | 93 | self.effects[effect].intensity -= other.effects[effect].intensity | n | 134 | intensities[effect] -= other.effects[effect].intensity |
| 94 | self.effects.pop(effect) if self.effects[effect].intensity < 0 else None | ||||
| 95 | 135 | ||||
| n | n | 136 | if intensities[effect] <= 0: | ||
| 137 | effects.pop(effect) | ||||
| 138 | intensities.pop(effect) | ||||
| 139 | |||||
| 140 | self.is_itself = False | ||||
| 96 | self.is_itself = False | 141 | other.is_itself = False | ||
| 97 | return self | 142 | return Potion(effects, self.duration, intensities) | ||
| 98 | 143 | ||||
| 99 | def __truediv__(self, number:int): | 144 | def __truediv__(self, number:int): | ||
| 100 | """Dividing two potions.""" | 145 | """Dividing two potions.""" | ||
| n | 101 | n | 146 | if not self.is_itself: | |
| 147 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
| 148 | |||||
| 149 | if self.is_used: | ||||
| 150 | raise TypeError("Potion is depleted.") | ||||
| 151 | |||||
| 102 | effects = {} | 152 | effects = {} | ||
| 103 | intensities = {} | 153 | intensities = {} | ||
| 104 | 154 | ||||
| 105 | for effect_name, effect in self.effects.items(): | 155 | for effect_name, effect in self.effects.items(): | ||
| n | 106 | intensities[effect_name] = round(int(effect.intensity) / number) | n | 156 | intensities[effect_name] = int(effect.intensity) / number |
| 107 | effects[effect_name] = effect.func | 157 | effects[effect_name] = effect.func | ||
| n | 108 | n | |||
| 109 | potion = Potion(effects, self.duration, intensities) | ||||
| 110 | 158 | ||||
| n | 111 | return tuple(potion for _ in range(number)) | n | 159 | if intensities[effect_name] % 1 <= 0.5: |
| 160 | intensities[effect_name] = math.floor(intensities[effect_name]) | ||||
| 161 | else: | ||||
| 162 | intensities[effect_name] = math.ceil(intensities[effect_name]) | ||||
| 163 | |||||
| 164 | self.is_itself = False | ||||
| 165 | return tuple(Potion(effects, self.duration, intensities) for _ in range(number)) | ||||
| 112 | 166 | ||||
| 113 | def __eq__(self, other): | 167 | def __eq__(self, other): | ||
| 114 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | 168 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | ||
| 115 | 169 | ||||
| 116 | def __lt__(self, other): | 170 | def __lt__(self, other): | ||
| 117 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | 171 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | ||
| 118 | 172 | ||||
| 119 | def __gt__(self, other): | 173 | def __gt__(self, other): | ||
| 120 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | 174 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | ||
| 121 | 175 | ||||
| 122 | 176 | ||||
| 123 | class Target: | 177 | class Target: | ||
| 124 | def __init__(self, target): | 178 | def __init__(self, target): | ||
| 125 | self.curr_target = target | 179 | self.curr_target = target | ||
| 126 | self.original = copy.deepcopy(target.__dict__) | 180 | self.original = copy.deepcopy(target.__dict__) | ||
| 127 | 181 | ||||
| 128 | @property | 182 | @property | ||
| 129 | def original_state(self): | 183 | def original_state(self): | ||
| 130 | return copy.deepcopy(self.original) | 184 | return copy.deepcopy(self.original) | ||
| 131 | 185 | ||||
| 132 | def back_to_original(self): | 186 | def back_to_original(self): | ||
| 133 | self.curr_target.__dict__ = self.original_state | 187 | self.curr_target.__dict__ = self.original_state | ||
| 134 | 188 | ||||
| n | n | 189 | def __eq__(self, other): | ||
| 190 | if isinstance(other, Target): | ||||
| 191 | return self.curr_target.__class__.__name__ == other.curr_target.__class__.__name__ | ||||
| 192 | return False | ||||
| 193 | |||||
| 194 | def __hash__(self): | ||||
| 195 | return hash(self.curr_target.__class__.__name__) | ||||
| 135 | 196 | ||||
| 136 | class ГоспожатаПоХимия: | 197 | class ГоспожатаПоХимия: | ||
| 137 | def __init__(self): | 198 | def __init__(self): | ||
| 138 | self.active_potions = {} | 199 | self.active_potions = {} | ||
| 139 | 200 | ||||
| 140 | def apply(self, target_obj, potion): | 201 | def apply(self, target_obj, potion): | ||
| 141 | target = Target(target_obj) | 202 | target = Target(target_obj) | ||
| 142 | if self.active_potions.get(target) is None: | 203 | if self.active_potions.get(target) is None: | ||
| 143 | self.active_potions[target] = [] | 204 | self.active_potions[target] = [] | ||
| 144 | 205 | ||||
| n | 145 | potion.effect(target.curr_target, True) | n | 206 | potion.effect(target.curr_target) |
| 146 | self.active_potions[target].append([potion.duration - 1, potion]) | 207 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 147 | 208 | ||||
| 148 | def tick(self): | 209 | def tick(self): | ||
| 149 | for target in self.active_potions: | 210 | for target in self.active_potions: | ||
| 150 | target.back_to_original() | 211 | target.back_to_original() | ||
| n | n | 212 | to_remove = [] | ||
| 151 | for curr in self.active_potions[target]: | 213 | for curr in self.active_potions[target]: | ||
| 152 | remaining_time, potion = curr | 214 | remaining_time, potion = curr | ||
| 153 | curr[0] -= 1 | 215 | curr[0] -= 1 | ||
| 154 | if remaining_time <= 0: | 216 | if remaining_time <= 0: | ||
| n | 155 | self.active_potions[target].remove(curr) | n | 217 | to_remove.append(curr) |
| 156 | else: | 218 | else: | ||
| 157 | potion.effect(target.curr_target, True) | 219 | potion.effect(target.curr_target, True) | ||
| t | t | 220 | for curr in to_remove: | ||
| 221 | self.active_potions[target].remove(curr) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| 2 | 2 | ||||
| 3 | class Effect: | 3 | class Effect: | ||
| 4 | def __init__(self, name, func, intensity=1): | 4 | def __init__(self, name, func, intensity=1): | ||
| 5 | self.name = name | 5 | self.name = name | ||
| 6 | self.func = func | 6 | self.func = func | ||
| 7 | self.is_used = False | 7 | self.is_used = False | ||
| 8 | self.intensity = intensity | 8 | self.intensity = intensity | ||
| 9 | 9 | ||||
| 10 | @property | 10 | @property | ||
| 11 | def molecular_mass(self): | 11 | def molecular_mass(self): | ||
| 12 | return sum([ord(letter) for letter in self.name]) | 12 | return sum([ord(letter) for letter in self.name]) | ||
| 13 | 13 | ||||
| 14 | def __call__(self, target, is_continuing=False): | 14 | def __call__(self, target, is_continuing=False): | ||
| 15 | if not self.is_used or is_continuing: | 15 | if not self.is_used or is_continuing: | ||
| 16 | for _ in range(self.intensity): | 16 | for _ in range(self.intensity): | ||
| 17 | self.func(target) | 17 | self.func(target) | ||
| 18 | else: | 18 | else: | ||
| 19 | raise TypeError("Effect is depleted.") | 19 | raise TypeError("Effect is depleted.") | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | 21 | ||||
| 22 | 22 | ||||
| 23 | class Potion: | 23 | class Potion: | ||
| 24 | def __init__(self, effects, duration=2, intensities=None): | 24 | def __init__(self, effects, duration=2, intensities=None): | ||
| 25 | self.effects = {} | 25 | self.effects = {} | ||
| 26 | self.is_itself = True | 26 | self.is_itself = True | ||
| 27 | 27 | ||||
| 28 | for effect_name in effects: | 28 | for effect_name in effects: | ||
| 29 | effect_func = effects[effect_name] | 29 | effect_func = effects[effect_name] | ||
| 30 | effects[effect_name].is_called = False | 30 | effects[effect_name].is_called = False | ||
| 31 | 31 | ||||
| 32 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 32 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 33 | 33 | ||||
| 34 | self.duration = duration | 34 | self.duration = duration | ||
| 35 | 35 | ||||
| 36 | def effect(self, target, is_continuing=False): | 36 | def effect(self, target, is_continuing=False): | ||
| 37 | if not is_continuing or not self.is_itself: | 37 | if not is_continuing or not self.is_itself: | ||
| 38 | raise TypeError("Potion is now part of something bigger than itself.") | 38 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 39 | 39 | ||||
| 40 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass)) | 40 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass)) | ||
| 41 | 41 | ||||
| 42 | for effect in self.effects.values(): | 42 | for effect in self.effects.values(): | ||
| 43 | effect(target, True) | 43 | effect(target, True) | ||
| 44 | 44 | ||||
| 45 | def __getattr__(self, effect_name): | 45 | def __getattr__(self, effect_name): | ||
| 46 | if(effect_name not in self.effects): | 46 | if(effect_name not in self.effects): | ||
| t | 47 | raise TypeError ("Effect is not in potion.") | t | 47 | raise TypeError("Effect is not in potion.") |
| 48 | 48 | ||||
| 49 | self.is_itself = False | 49 | self.is_itself = False | ||
| 50 | return self.effects[effect_name] | 50 | return self.effects[effect_name] | ||
| 51 | 51 | ||||
| 52 | def __add__(self, other): | 52 | def __add__(self, other): | ||
| 53 | """Combining two potions.""" | 53 | """Combining two potions.""" | ||
| 54 | 54 | ||||
| 55 | effects = {} | 55 | effects = {} | ||
| 56 | intensities = {} | 56 | intensities = {} | ||
| 57 | 57 | ||||
| 58 | for effect_name, effect in self.effects.items(): | 58 | for effect_name, effect in self.effects.items(): | ||
| 59 | effects[effect_name] = copy.deepcopy(effect) | 59 | effects[effect_name] = copy.deepcopy(effect) | ||
| 60 | intensities[effect_name] = 1 | 60 | intensities[effect_name] = 1 | ||
| 61 | 61 | ||||
| 62 | for effect_name, effect in other.effects.items(): | 62 | for effect_name, effect in other.effects.items(): | ||
| 63 | if effect_name not in effects: | 63 | if effect_name not in effects: | ||
| 64 | effects[effect_name] = copy.deepcopy(effect) | 64 | effects[effect_name] = copy.deepcopy(effect) | ||
| 65 | intensities[effect_name] = 1 | 65 | intensities[effect_name] = 1 | ||
| 66 | else: | 66 | else: | ||
| 67 | intensities[effect_name] += effect.intensity | 67 | intensities[effect_name] += effect.intensity | ||
| 68 | 68 | ||||
| 69 | self.is_itself = False | 69 | self.is_itself = False | ||
| 70 | return Potion(effects, self.duration + other.duration, intensities) | 70 | return Potion(effects, self.duration + other.duration, intensities) | ||
| 71 | 71 | ||||
| 72 | #Потенцииране и Разреждане | 72 | #Потенцииране и Разреждане | ||
| 73 | def __mul__(self, number): | 73 | def __mul__(self, number): | ||
| 74 | """Potentiation of two potions.""" | 74 | """Potentiation of two potions.""" | ||
| 75 | 75 | ||||
| 76 | effects = {} | 76 | effects = {} | ||
| 77 | intensities = {} | 77 | intensities = {} | ||
| 78 | 78 | ||||
| 79 | for effect_name, effect in self.effects.items(): | 79 | for effect_name, effect in self.effects.items(): | ||
| 80 | intensities[effect_name] = round(effect.intensity * number) | 80 | intensities[effect_name] = round(effect.intensity * number) | ||
| 81 | effects[effect_name] = effect.func | 81 | effects[effect_name] = effect.func | ||
| 82 | 82 | ||||
| 83 | return Potion(effects, self.duration, intensities) | 83 | return Potion(effects, self.duration, intensities) | ||
| 84 | 84 | ||||
| 85 | def __sub__(self, other): | 85 | def __sub__(self, other): | ||
| 86 | """Purification of two potions.""" | 86 | """Purification of two potions.""" | ||
| 87 | 87 | ||||
| 88 | for effect in other.effects: | 88 | for effect in other.effects: | ||
| 89 | if effect not in self.effects: | 89 | if effect not in self.effects: | ||
| 90 | raise TypeError("Effect is not in potion.") | 90 | raise TypeError("Effect is not in potion.") | ||
| 91 | 91 | ||||
| 92 | for effect in other.effects: | 92 | for effect in other.effects: | ||
| 93 | self.effects[effect].intensity -= other.effects[effect].intensity | 93 | self.effects[effect].intensity -= other.effects[effect].intensity | ||
| 94 | self.effects.pop(effect) if self.effects[effect].intensity < 0 else None | 94 | self.effects.pop(effect) if self.effects[effect].intensity < 0 else None | ||
| 95 | 95 | ||||
| 96 | self.is_itself = False | 96 | self.is_itself = False | ||
| 97 | return self | 97 | return self | ||
| 98 | 98 | ||||
| 99 | def __truediv__(self, number:int): | 99 | def __truediv__(self, number:int): | ||
| 100 | """Dividing two potions.""" | 100 | """Dividing two potions.""" | ||
| 101 | 101 | ||||
| 102 | effects = {} | 102 | effects = {} | ||
| 103 | intensities = {} | 103 | intensities = {} | ||
| 104 | 104 | ||||
| 105 | for effect_name, effect in self.effects.items(): | 105 | for effect_name, effect in self.effects.items(): | ||
| 106 | intensities[effect_name] = round(int(effect.intensity) / number) | 106 | intensities[effect_name] = round(int(effect.intensity) / number) | ||
| 107 | effects[effect_name] = effect.func | 107 | effects[effect_name] = effect.func | ||
| 108 | 108 | ||||
| 109 | potion = Potion(effects, self.duration, intensities) | 109 | potion = Potion(effects, self.duration, intensities) | ||
| 110 | 110 | ||||
| 111 | return tuple(potion for _ in range(number)) | 111 | return tuple(potion for _ in range(number)) | ||
| 112 | 112 | ||||
| 113 | def __eq__(self, other): | 113 | def __eq__(self, other): | ||
| 114 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | 114 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | ||
| 115 | 115 | ||||
| 116 | def __lt__(self, other): | 116 | def __lt__(self, other): | ||
| 117 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | 117 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | ||
| 118 | 118 | ||||
| 119 | def __gt__(self, other): | 119 | def __gt__(self, other): | ||
| 120 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | 120 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | ||
| 121 | 121 | ||||
| 122 | 122 | ||||
| 123 | class Target: | 123 | class Target: | ||
| 124 | def __init__(self, target): | 124 | def __init__(self, target): | ||
| 125 | self.curr_target = target | 125 | self.curr_target = target | ||
| 126 | self.original = copy.deepcopy(target.__dict__) | 126 | self.original = copy.deepcopy(target.__dict__) | ||
| 127 | 127 | ||||
| 128 | @property | 128 | @property | ||
| 129 | def original_state(self): | 129 | def original_state(self): | ||
| 130 | return copy.deepcopy(self.original) | 130 | return copy.deepcopy(self.original) | ||
| 131 | 131 | ||||
| 132 | def back_to_original(self): | 132 | def back_to_original(self): | ||
| 133 | self.curr_target.__dict__ = self.original_state | 133 | self.curr_target.__dict__ = self.original_state | ||
| 134 | 134 | ||||
| 135 | 135 | ||||
| 136 | class ГоспожатаПоХимия: | 136 | class ГоспожатаПоХимия: | ||
| 137 | def __init__(self): | 137 | def __init__(self): | ||
| 138 | self.active_potions = {} | 138 | self.active_potions = {} | ||
| 139 | 139 | ||||
| 140 | def apply(self, target_obj, potion): | 140 | def apply(self, target_obj, potion): | ||
| 141 | target = Target(target_obj) | 141 | target = Target(target_obj) | ||
| 142 | if self.active_potions.get(target) is None: | 142 | if self.active_potions.get(target) is None: | ||
| 143 | self.active_potions[target] = [] | 143 | self.active_potions[target] = [] | ||
| 144 | 144 | ||||
| 145 | potion.effect(target.curr_target, True) | 145 | potion.effect(target.curr_target, True) | ||
| 146 | self.active_potions[target].append([potion.duration - 1, potion]) | 146 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 147 | 147 | ||||
| 148 | def tick(self): | 148 | def tick(self): | ||
| 149 | for target in self.active_potions: | 149 | for target in self.active_potions: | ||
| 150 | target.back_to_original() | 150 | target.back_to_original() | ||
| 151 | for curr in self.active_potions[target]: | 151 | for curr in self.active_potions[target]: | ||
| 152 | remaining_time, potion = curr | 152 | remaining_time, potion = curr | ||
| 153 | curr[0] -= 1 | 153 | curr[0] -= 1 | ||
| 154 | if remaining_time <= 0: | 154 | if remaining_time <= 0: | ||
| 155 | self.active_potions[target].remove(curr) | 155 | self.active_potions[target].remove(curr) | ||
| 156 | else: | 156 | else: | ||
| 157 | potion.effect(target.curr_target, True) | 157 | potion.effect(target.curr_target, True) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import copy | f | 1 | import copy |
| 2 | 2 | ||||
| 3 | class Effect: | 3 | class Effect: | ||
| 4 | def __init__(self, name, func, intensity=1): | 4 | def __init__(self, name, func, intensity=1): | ||
| 5 | self.name = name | 5 | self.name = name | ||
| 6 | self.func = func | 6 | self.func = func | ||
| 7 | self.is_used = False | 7 | self.is_used = False | ||
| 8 | self.intensity = intensity | 8 | self.intensity = intensity | ||
| 9 | 9 | ||||
| 10 | @property | 10 | @property | ||
| 11 | def molecular_mass(self): | 11 | def molecular_mass(self): | ||
| 12 | return sum([ord(letter) for letter in self.name]) | 12 | return sum([ord(letter) for letter in self.name]) | ||
| 13 | 13 | ||||
| n | 14 | def __call__(self, target, is_continuing = False): | n | 14 | def __call__(self, target, is_continuing=False): |
| 15 | if not self.is_used or is_continuing: | 15 | if not self.is_used or is_continuing: | ||
| 16 | for _ in range(self.intensity): | 16 | for _ in range(self.intensity): | ||
| 17 | self.func(target) | 17 | self.func(target) | ||
| 18 | else: | 18 | else: | ||
| 19 | raise TypeError("Effect is depleted.") | 19 | raise TypeError("Effect is depleted.") | ||
| 20 | self.is_used = True | 20 | self.is_used = True | ||
| 21 | 21 | ||||
| 22 | 22 | ||||
| 23 | class Potion: | 23 | class Potion: | ||
| n | 24 | def __init__(self, effects, duration = 2, intensities = None): | n | 24 | def __init__(self, effects, duration=2, intensities=None): |
| 25 | self.effects = {} | 25 | self.effects = {} | ||
| 26 | self.is_itself = True | 26 | self.is_itself = True | ||
| 27 | 27 | ||||
| n | 28 | for effect_name in effects.keys(): | n | 28 | for effect_name in effects: |
| 29 | effect_func = effects[effect_name] | 29 | effect_func = effects[effect_name] | ||
| 30 | effects[effect_name].is_called = False | 30 | effects[effect_name].is_called = False | ||
| 31 | 31 | ||||
| 32 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | 32 | self.effects[effect_name] = Effect(effect_name, effect_func, 1 if intensities is None else intensities[effect_name]) | ||
| 33 | 33 | ||||
| 34 | self.duration = duration | 34 | self.duration = duration | ||
| 35 | 35 | ||||
| n | 36 | def effect(self, target, is_continuing = False): | n | 36 | def effect(self, target, is_continuing=False): |
| 37 | if(not is_continuing or not self.is_itself): | 37 | if not is_continuing or not self.is_itself: | ||
| 38 | raise TypeError("Potion is now part of something bigger than itself.") | 38 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 39 | 39 | ||||
| n | 40 | dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass)) | n | 40 | self.effects = dict(sorted(self.effects.items(), key=lambda x: x[1].molecular_mass)) |
| 41 | 41 | ||||
| 42 | for effect in self.effects.values(): | 42 | for effect in self.effects.values(): | ||
| 43 | effect(target, True) | 43 | effect(target, True) | ||
| 44 | 44 | ||||
| 45 | def __getattr__(self, effect_name): | 45 | def __getattr__(self, effect_name): | ||
| 46 | if(effect_name not in self.effects): | 46 | if(effect_name not in self.effects): | ||
| 47 | raise TypeError ("Effect is not in potion.") | 47 | raise TypeError ("Effect is not in potion.") | ||
| 48 | 48 | ||||
| 49 | self.is_itself = False | 49 | self.is_itself = False | ||
| 50 | return self.effects[effect_name] | 50 | return self.effects[effect_name] | ||
| 51 | 51 | ||||
| n | 52 | #Комбиниране | n | ||
| 53 | def __add__(self, other): | 52 | def __add__(self, other): | ||
| n | n | 53 | """Combining two potions.""" | ||
| 54 | |||||
| 54 | effects = {} | 55 | effects = {} | ||
| 55 | intensities = {} | 56 | intensities = {} | ||
| 56 | 57 | ||||
| 57 | for effect_name, effect in self.effects.items(): | 58 | for effect_name, effect in self.effects.items(): | ||
| 58 | effects[effect_name] = copy.deepcopy(effect) | 59 | effects[effect_name] = copy.deepcopy(effect) | ||
| 59 | intensities[effect_name] = 1 | 60 | intensities[effect_name] = 1 | ||
| 60 | 61 | ||||
| 61 | for effect_name, effect in other.effects.items(): | 62 | for effect_name, effect in other.effects.items(): | ||
| 62 | if effect_name not in effects: | 63 | if effect_name not in effects: | ||
| 63 | effects[effect_name] = copy.deepcopy(effect) | 64 | effects[effect_name] = copy.deepcopy(effect) | ||
| 64 | intensities[effect_name] = 1 | 65 | intensities[effect_name] = 1 | ||
| 65 | else: | 66 | else: | ||
| 66 | intensities[effect_name] += effect.intensity | 67 | intensities[effect_name] += effect.intensity | ||
| 67 | 68 | ||||
| 68 | self.is_itself = False | 69 | self.is_itself = False | ||
| 69 | return Potion(effects, self.duration + other.duration, intensities) | 70 | return Potion(effects, self.duration + other.duration, intensities) | ||
| 70 | 71 | ||||
| 71 | #Потенцииране и Разреждане | 72 | #Потенцииране и Разреждане | ||
| 72 | def __mul__(self, number): | 73 | def __mul__(self, number): | ||
| n | n | 74 | """Potentiation of two potions.""" | ||
| 75 | |||||
| 73 | effects = {} | 76 | effects = {} | ||
| 74 | intensities = {} | 77 | intensities = {} | ||
| 75 | 78 | ||||
| 76 | for effect_name, effect in self.effects.items(): | 79 | for effect_name, effect in self.effects.items(): | ||
| 77 | intensities[effect_name] = round(effect.intensity * number) | 80 | intensities[effect_name] = round(effect.intensity * number) | ||
| 78 | effects[effect_name] = effect.func | 81 | effects[effect_name] = effect.func | ||
| 79 | 82 | ||||
| 80 | return Potion(effects, self.duration, intensities) | 83 | return Potion(effects, self.duration, intensities) | ||
| 81 | 84 | ||||
| n | 82 | #Пречистване | n | ||
| 83 | def __sub__(self, other): | 85 | def __sub__(self, other): | ||
| n | n | 86 | """Purification of two potions.""" | ||
| 87 | |||||
| 84 | for effect in other.effects: | 88 | for effect in other.effects: | ||
| 85 | if effect not in self.effects: | 89 | if effect not in self.effects: | ||
| n | 86 | raise TypeError ("Effect is not in potion.") | n | 90 | raise TypeError("Effect is not in potion.") |
| 87 | 91 | ||||
| 88 | for effect in other.effects: | 92 | for effect in other.effects: | ||
| 89 | self.effects[effect].intensity -= other.effects[effect].intensity | 93 | self.effects[effect].intensity -= other.effects[effect].intensity | ||
| 90 | self.effects.pop(effect) if self.effects[effect].intensity < 0 else None | 94 | self.effects.pop(effect) if self.effects[effect].intensity < 0 else None | ||
| 91 | 95 | ||||
| 92 | self.is_itself = False | 96 | self.is_itself = False | ||
| 93 | return self | 97 | return self | ||
| 94 | 98 | ||||
| n | 95 | #Разделяне | n | ||
| 96 | def __truediv__(self, number:int): | 99 | def __truediv__(self, number:int): | ||
| n | n | 100 | """Dividing two potions.""" | ||
| 101 | |||||
| 97 | effects = {} | 102 | effects = {} | ||
| 98 | intensities = {} | 103 | intensities = {} | ||
| 99 | 104 | ||||
| 100 | for effect_name, effect in self.effects.items(): | 105 | for effect_name, effect in self.effects.items(): | ||
| 101 | intensities[effect_name] = round(int(effect.intensity) / number) | 106 | intensities[effect_name] = round(int(effect.intensity) / number) | ||
| 102 | effects[effect_name] = effect.func | 107 | effects[effect_name] = effect.func | ||
| 103 | 108 | ||||
| 104 | potion = Potion(effects, self.duration, intensities) | 109 | potion = Potion(effects, self.duration, intensities) | ||
| 105 | 110 | ||||
| n | 106 | return ([potion for _ in range(number)]) | n | 111 | return tuple(potion for _ in range(number)) |
| 107 | 112 | ||||
| 108 | def __eq__(self, other): | 113 | def __eq__(self, other): | ||
| 109 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | 114 | return sum([effect.intensity for effect in self.effects.values()]) == sum([effect.intensity for effect in other.effects.values()]) | ||
| 110 | 115 | ||||
| 111 | def __lt__(self, other): | 116 | def __lt__(self, other): | ||
| 112 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | 117 | return sum([effect.intensity for effect in self.effects.values()]) < sum([effect.intensity for effect in other.effects.values()]) | ||
| 113 | 118 | ||||
| 114 | def __gt__(self, other): | 119 | def __gt__(self, other): | ||
| 115 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | 120 | return sum([effect.intensity for effect in self.effects.values()]) > sum([effect.intensity for effect in other.effects.values()]) | ||
| 116 | 121 | ||||
| n | n | 122 | |||
| 117 | class Target: | 123 | class Target: | ||
| n | 118 | id_counter = 0 | n | ||
| 119 | originals = {} | ||||
| 120 | |||||
| 121 | def __init__(self, target): | 124 | def __init__(self, target): | ||
| n | 122 | self.id = Target.id_counter | n | ||
| 123 | self.curr_target = target | 125 | self.curr_target = target | ||
| n | 124 | if Target.originals.get(self.id) is None: | n | ||
| 125 | Target.originals[self.id] = copy.deepcopy(target.__dict__) | 126 | self.original = copy.deepcopy(target.__dict__) | ||
| 126 | Target.id_counter += 1 | ||||
| 127 | 127 | ||||
| 128 | @property | 128 | @property | ||
| 129 | def original_state(self): | 129 | def original_state(self): | ||
| n | 130 | return copy.deepcopy(Target.originals[self.id]) | n | 130 | return copy.deepcopy(self.original) |
| 131 | 131 | ||||
| 132 | def back_to_original(self): | 132 | def back_to_original(self): | ||
| 133 | self.curr_target.__dict__ = self.original_state | 133 | self.curr_target.__dict__ = self.original_state | ||
| t | t | 134 | |||
| 134 | 135 | ||||
| 135 | class ГоспожатаПоХимия: | 136 | class ГоспожатаПоХимия: | ||
| 136 | def __init__(self): | 137 | def __init__(self): | ||
| 137 | self.active_potions = {} | 138 | self.active_potions = {} | ||
| 138 | 139 | ||||
| 139 | def apply(self, target_obj, potion): | 140 | def apply(self, target_obj, potion): | ||
| 140 | target = Target(target_obj) | 141 | target = Target(target_obj) | ||
| 141 | if self.active_potions.get(target) is None: | 142 | if self.active_potions.get(target) is None: | ||
| 142 | self.active_potions[target] = [] | 143 | self.active_potions[target] = [] | ||
| 143 | 144 | ||||
| 144 | potion.effect(target.curr_target, True) | 145 | potion.effect(target.curr_target, True) | ||
| 145 | self.active_potions[target].append([potion.duration - 1, potion]) | 146 | self.active_potions[target].append([potion.duration - 1, potion]) | ||
| 146 | 147 | ||||
| 147 | def tick(self): | 148 | def tick(self): | ||
| 148 | for target in self.active_potions: | 149 | for target in self.active_potions: | ||
| 149 | target.back_to_original() | 150 | target.back_to_original() | ||
| 150 | for curr in self.active_potions[target]: | 151 | for curr in self.active_potions[target]: | ||
| 151 | remaining_time, potion = curr | 152 | remaining_time, potion = curr | ||
| 152 | curr[0] -= 1 | 153 | curr[0] -= 1 | ||
| 153 | if remaining_time <= 0: | 154 | if remaining_time <= 0: | ||
| 154 | self.active_potions[target].remove(curr) | 155 | self.active_potions[target].remove(curr) | ||
| 155 | else: | 156 | else: | ||
| 156 | potion.effect(target.curr_target, True) | 157 | potion.effect(target.curr_target, True) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||