1import math
2import copy
3
4def once(func):
5 def wrapper(target):
6 if wrapper.called:
7 raise TypeError("Effect is depleted.")
8 wrapper.called = True
9 func(target)
10 wrapper.called = False
11 return wrapper
12
13def calling_function_decorator(function, times):
14 @once
15 def decorator(target):
16 for _ in range(times):
17 function(target)
18 return decorator
19
20class Potion:
21
22 def __hash__(self):
23 hash_value = 0
24 for effect_name, intensity in self.intensity.items():
25 hash_value ^= hash((effect_name, intensity))
26 return hash_value
27
28 def round_intensity(self,to_return,effect_name):
29 to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name])
30
31 def is_depleted(self):
32 is_depleted_var = True
33 for effect_name,effect in self.effects.items():
34 function = getattr(self, effect_name)
35 try:
36 function(None)
37 except TypeError:
38 is_depleted_var = True
39 continue
40 finally:
41 setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
42 return False
43 return is_depleted_var
44
45 @staticmethod
46 def already_used(target):
47 raise TypeError("Potion is now part of something bigger than itself.")
48
49 def __init__(self,effects, duration):
50 self.effects = copy.copy(effects)
51 self.was_used = False
52 self.intensity = {}
53 for effect_name in self.effects:
54 self.intensity[effect_name] = 1
55 for effect_name,effect in effects.items():
56 setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name]))
57 self.effects[effect_name] = effect
58 self.duration = duration
59
60 def __add__(self, other):
61 if self.is_depleted() or other.is_depleted():
62 raise TypeError("Potion is depleted.")
63 if self.was_used == True or other.was_used == True:
64 raise TypeError("Potion is now part of something bigger than itself.")
65 to_return = Potion(self.effects, max(self.duration, other.duration))
66 for effect_name,effect in to_return.effects.items():
67 to_return.intensity[effect_name]=self.intensity[effect_name]
68 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
69 for effect_name,effect in other.effects.items():
70 if effect_name in to_return.effects:
71 to_return.intensity[effect_name] += 1
72 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
73 else:
74 to_return.intensity[effect_name] = other.intensity[effect_name]
75 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
76 to_return.effects[effect_name] = effect
77 for effect_name in self.effects:
78 setattr(self, effect_name, self.already_used)
79 for effect_name in other.effects:
80 setattr(other, effect_name, other.already_used)
81 self.was_used = other.was_used = True
82 return to_return
83
84 def __mul__(self, value):
85 if self.is_depleted():
86 raise TypeError("Potion is depleted.")
87 if self.was_used == True:
88 raise TypeError("Potion is now part of something bigger than itself.")
89 if value >= 0 and value <= 1:
90 to_return = Potion(self.effects, self.duration)
91 for effect_name in to_return.effects:
92 to_return.intensity[effect_name] = self.intensity[effect_name]
93 for effect_name,effect in to_return.effects.items():
94 to_return.intensity[effect_name] *= value
95 self.round_intensity(to_return,effect_name)
96 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
97 # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name])
98 for effect_name in self.effects:
99 setattr(self, effect_name, self.already_used)
100 self.was_used = True
101 return to_return
102 to_return = Potion(self.effects, self.duration)
103 for effect_name in to_return.effects:
104 to_return.intensity[effect_name] = self.intensity[effect_name]
105 for effect_name in to_return.effects:
106 to_return.intensity[effect_name] *= value
107 for effect_name,effect in to_return.effects.items():
108 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
109 for effect_name in self.effects:
110 setattr(self, effect_name, self.already_used)
111 self.was_used = True
112 return to_return
113
114 def __sub__(self, other):
115 if self.is_depleted() or other.is_depleted():
116 raise TypeError("Potion is depleted.")
117 if self.was_used == True or other.was_used == True:
118 raise TypeError("Potion is now part of something bigger than itself.")
119 to_return = Potion(self.effects, self.duration)
120 for effect_name,effect in to_return.effects.items():
121 to_return.intensity[effect_name] = self.intensity[effect_name]
122 setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name]))
123 for effect_name in other.effects:
124 if effect_name not in to_return.effects:
125 raise TypeError("Error")
126 for effect_name, effect in other.effects.items():
127 if to_return.intensity[effect_name] > other.intensity[effect_name]:
128 to_return.intensity[effect_name] -= other.intensity[effect_name]
129 setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name]))
130 else:
131 delattr(to_return, effect_name)
132 del to_return.effects[effect_name]
133 del to_return.intensity[effect_name]
134 for effect_name in self.effects:
135 setattr(self, effect_name, self.already_used)
136 for effect_name in other.effects:
137 setattr(other, effect_name, other.already_used)
138 self.was_used = other.was_used = True
139 return to_return
140
141 def __truediv__(self, value):
142 if self.is_depleted():
143 raise TypeError("Potion is depleted.")
144 if self.was_used == True:
145 raise TypeError("Potion is now part of something bigger than itself.")
146 copy_potion=Potion(self.effects,self.duration)
147 for effect_name in self.intensity:
148 copy_potion.intensity[effect_name] = self.intensity[effect_name]
149 for effect_name,effect in copy_potion.effects.items():
150 copy_potion.intensity[effect_name] /= value
151 self.round_intensity(copy_potion,effect_name)
152 #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name])
153 setattr(copy_potion,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))
154 potion_list=[]
155 for _ in range(value):
156 copy=Potion(copy_potion.effects,copy_potion.duration)
157 for effect_name in copy_potion.intensity:
158 copy.intensity[effect_name] = copy_potion.intensity[effect_name]
159 for effect_name,effect in copy_potion.effects.items():
160 setattr(copy,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name]))
161 potion_list.append(copy)
162 for effect_name in self.effects:
163 setattr(self, effect_name, self.already_used)
164 self.was_used = True
165 return tuple(potion_list)
166
167 def __eq__(self,other):
168 if self.is_depleted() or other.is_depleted():
169 raise TypeError("Potion is depleted.")
170 if self.was_used == True or other.was_used == True:
171 raise TypeError("Potion is now part of something bigger than itself.")
172 for effect_name in self.effects:
173 if effect_name not in other.effects:
174 return False
175 for effect_name in self.effects:
176 if self.intensity[effect_name] != other.intensity[effect_name]:
177 return False
178 return True
179
180 def __gt__(self,other):
181 if self.is_depleted() or other.is_depleted():
182 raise TypeError("Potion is depleted.")
183 if self.was_used == True or other.was_used == True:
184 raise TypeError("Potion is now part of something bigger than itself.")
185 sum_of_self = 0
186 for effect_name in self.intensity:
187 sum_of_self+=self.intensity[effect_name]
188 sum_of_other = 0
189 for effect_name in other.intensity:
190 sum_of_other += other.intensity[effect_name]
191 return sum_of_self > sum_of_other
192
193
194def sorting_potions(potion):
195 name = potion[0]
196 sum_of_potion_name = 0
197 for letter in name:
198 sum_of_potion_name += ord(letter)
199 return sum_of_potion_name
200
201
202class ГоспожатаПоХимия:
203 def __init__(self):
204 self.used_potions = []
205 self.targets_copies = {}
206 self.targets_buffed_copies = {}
207
208 def apply(self, target, potion):
209 if potion.duration == 0:
210 return
211 if potion.is_depleted():
212 raise TypeError("Potion is depleted.")
213 if potion.was_used:
214 raise TypeError("Potion is now part of something bigger than itself.")
215 sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True)
216 potion.effects = dict(sorted_potions)
217 if target not in self.targets_buffed_copies.values():
218 self.targets_copies[potion] = copy.copy(target)
219 else:
220 for potion_loop in self.used_potions:
221 potion_loop.was_used = False
222 if self.targets_buffed_copies[potion_loop] == target:
223 self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop])
224 potion_loop.was_used = True
225 self.used_potions.append(potion)
226 for effect_name in potion.effects:
227 function = getattr(potion, effect_name)
228 try:
229 function(target)
230 except TypeError:
231 continue
232 for potion_iter in self.used_potions:
233 potion_iter.was_used = False
234 self.targets_buffed_copies[potion] = target
235 potion.was_used = True
236 for potion_iter in self.used_potions:
237 potion_iter.was_used = True
238
239 def tick(self):
240 for potion in self.used_potions:
241 potion.duration -= 1
242 if potion.duration == 0:
243 self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion])
244 for potion_inner in self.used_potions:
245 potion_inner.was_used = False
246 potion.was_used = False
247 if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]:
248 potion_inner.was_used = True
249 potion.was_used = True
250 continue
251 potion_inner.was_used = True
252 potion.was_used = True
253 copy = Potion(potion_inner.effects,potion_inner.duration)
254 for effect_name,effect in copy.effects.items():
255 copy.intensity[effect_name] = potion_inner.intensity[effect_name]
256 setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name]))
257 for effect_name in copy.effects:
258 function = getattr(copy, effect_name)
259 function(self.targets_buffed_copies[potion])
...F........F..F.F.F
======================================================================
FAIL: test_equal (test.TestPotionComparison)
Test equality of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 304, in test_equal
self.assertNotEqual(potion1, potion2)
AssertionError: <solution.Potion object at 0x7fa9ee5a8d60> == <solution.Potion object at 0x7fa9ee5a8dc0>
======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
TypeError: Potion is now part of something bigger than itself.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/test.py", line 380, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: "Potion is depleted\." does not match "Potion is now part of something bigger than itself."
======================================================================
FAIL: test_applying_part_of_potion (test.TestГоспожатаПоХимия)
Test applying only a part of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 366, in test_applying_part_of_potion
self.assertEqual(self._target.int_attr, 5) # This should be the original value
AssertionError: 50 != 5
======================================================================
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 458, in test_ticking_multiple_potions
self.assertEqual(self._target.int_attr, 50)
AssertionError: 5 != 50
======================================================================
FAIL: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 446, in test_ticking_mutable
self.assertEqual(self._target.list_attr, [1, 2, 3])
AssertionError: Lists differ: [1, 2, 3, 4] != [1, 2, 3]
First list contains 1 additional elements.
First extra element 3:
4
- [1, 2, 3, 4]
? ---
+ [1, 2, 3]
----------------------------------------------------------------------
Ran 20 tests in 0.003s
FAILED (failures=5)
Георги Кунчев
04.12.2023 11:18Знам, че пишеш на още няколко езика и трудно се сменят стилове ден за ден. Или опитай да следваш интервалите към PEP8, или си свали някакъв линтер да го прави вместо теб.
Много трудно се чете без наличието на интервали около оператори и запетая, особено за човек, който е свиканл да чете Python и очаква да са там. Все едно чета текст, написан на шльокавица - разбирам го, но ме боли да го чета. Няма да отнемам точки, но ако пишеш професионално Питонски код така, няма да мине код ревю.
|
f | 1 | import math | f | 1 | import math |
2 | import copy | 2 | import copy | ||
3 | 3 | ||||
4 | def once(func): | 4 | def once(func): | ||
5 | def wrapper(target): | 5 | def wrapper(target): | ||
6 | if wrapper.called: | 6 | if wrapper.called: | ||
7 | raise TypeError("Effect is depleted.") | 7 | raise TypeError("Effect is depleted.") | ||
8 | wrapper.called = True | 8 | wrapper.called = True | ||
9 | func(target) | 9 | func(target) | ||
10 | wrapper.called = False | 10 | wrapper.called = False | ||
11 | return wrapper | 11 | return wrapper | ||
12 | 12 | ||||
13 | def calling_function_decorator(function, times): | 13 | def calling_function_decorator(function, times): | ||
14 | @once | 14 | @once | ||
15 | def decorator(target): | 15 | def decorator(target): | ||
16 | for _ in range(times): | 16 | for _ in range(times): | ||
17 | function(target) | 17 | function(target) | ||
18 | return decorator | 18 | return decorator | ||
19 | 19 | ||||
20 | class Potion: | 20 | class Potion: | ||
21 | 21 | ||||
n | n | 22 | def __hash__(self): | ||
23 | hash_value = 0 | ||||
24 | for effect_name, intensity in self.intensity.items(): | ||||
25 | hash_value ^= hash((effect_name, intensity)) | ||||
26 | return hash_value | ||||
27 | |||||
22 | def round_intensity(self,to_return,effect_name): | 28 | def round_intensity(self,to_return,effect_name): | ||
23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name]) | 29 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name]) | ||
24 | 30 | ||||
25 | def is_depleted(self): | 31 | def is_depleted(self): | ||
n | 26 | is_depleted = True | n | 32 | is_depleted_var = True |
27 | for effect_name,effect in self.effects.items(): | 33 | for effect_name,effect in self.effects.items(): | ||
28 | function = getattr(self, effect_name) | 34 | function = getattr(self, effect_name) | ||
29 | try: | 35 | try: | ||
30 | function(None) | 36 | function(None) | ||
31 | except TypeError: | 37 | except TypeError: | ||
n | 32 | is_depleted = True | n | 38 | is_depleted_var = True |
33 | except AttributeError: | 39 | continue | ||
34 | is_depleted = False | 40 | finally: | ||
35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 41 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
n | n | 42 | return False | ||
36 | return is_depleted | 43 | return is_depleted_var | ||
37 | 44 | ||||
38 | @staticmethod | 45 | @staticmethod | ||
39 | def already_used(target): | 46 | def already_used(target): | ||
40 | raise TypeError("Potion is now part of something bigger than itself.") | 47 | raise TypeError("Potion is now part of something bigger than itself.") | ||
41 | 48 | ||||
42 | def __init__(self,effects, duration): | 49 | def __init__(self,effects, duration): | ||
43 | self.effects = copy.copy(effects) | 50 | self.effects = copy.copy(effects) | ||
44 | self.was_used = False | 51 | self.was_used = False | ||
45 | self.intensity = {} | 52 | self.intensity = {} | ||
46 | for effect_name in self.effects: | 53 | for effect_name in self.effects: | ||
47 | self.intensity[effect_name] = 1 | 54 | self.intensity[effect_name] = 1 | ||
48 | for effect_name,effect in effects.items(): | 55 | for effect_name,effect in effects.items(): | ||
49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 56 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
50 | self.effects[effect_name] = effect | 57 | self.effects[effect_name] = effect | ||
51 | self.duration = duration | 58 | self.duration = duration | ||
52 | 59 | ||||
53 | def __add__(self, other): | 60 | def __add__(self, other): | ||
54 | if self.is_depleted() or other.is_depleted(): | 61 | if self.is_depleted() or other.is_depleted(): | ||
55 | raise TypeError("Potion is depleted.") | 62 | raise TypeError("Potion is depleted.") | ||
56 | if self.was_used == True or other.was_used == True: | 63 | if self.was_used == True or other.was_used == True: | ||
57 | raise TypeError("Potion is now part of something bigger than itself.") | 64 | raise TypeError("Potion is now part of something bigger than itself.") | ||
58 | to_return = Potion(self.effects, max(self.duration, other.duration)) | 65 | to_return = Potion(self.effects, max(self.duration, other.duration)) | ||
59 | for effect_name,effect in to_return.effects.items(): | 66 | for effect_name,effect in to_return.effects.items(): | ||
60 | to_return.intensity[effect_name]=self.intensity[effect_name] | 67 | to_return.intensity[effect_name]=self.intensity[effect_name] | ||
61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
62 | for effect_name,effect in other.effects.items(): | 69 | for effect_name,effect in other.effects.items(): | ||
63 | if effect_name in to_return.effects: | 70 | if effect_name in to_return.effects: | ||
64 | to_return.intensity[effect_name] += 1 | 71 | to_return.intensity[effect_name] += 1 | ||
65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 72 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
66 | else: | 73 | else: | ||
67 | to_return.intensity[effect_name] = other.intensity[effect_name] | 74 | to_return.intensity[effect_name] = other.intensity[effect_name] | ||
68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 75 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
69 | to_return.effects[effect_name] = effect | 76 | to_return.effects[effect_name] = effect | ||
70 | for effect_name in self.effects: | 77 | for effect_name in self.effects: | ||
71 | setattr(self, effect_name, self.already_used) | 78 | setattr(self, effect_name, self.already_used) | ||
72 | for effect_name in other.effects: | 79 | for effect_name in other.effects: | ||
73 | setattr(other, effect_name, other.already_used) | 80 | setattr(other, effect_name, other.already_used) | ||
74 | self.was_used = other.was_used = True | 81 | self.was_used = other.was_used = True | ||
75 | return to_return | 82 | return to_return | ||
76 | 83 | ||||
77 | def __mul__(self, value): | 84 | def __mul__(self, value): | ||
78 | if self.is_depleted(): | 85 | if self.is_depleted(): | ||
79 | raise TypeError("Potion is depleted.") | 86 | raise TypeError("Potion is depleted.") | ||
80 | if self.was_used == True: | 87 | if self.was_used == True: | ||
81 | raise TypeError("Potion is now part of something bigger than itself.") | 88 | raise TypeError("Potion is now part of something bigger than itself.") | ||
82 | if value >= 0 and value <= 1: | 89 | if value >= 0 and value <= 1: | ||
83 | to_return = Potion(self.effects, self.duration) | 90 | to_return = Potion(self.effects, self.duration) | ||
84 | for effect_name in to_return.effects: | 91 | for effect_name in to_return.effects: | ||
85 | to_return.intensity[effect_name] = self.intensity[effect_name] | 92 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
86 | for effect_name,effect in to_return.effects.items(): | 93 | for effect_name,effect in to_return.effects.items(): | ||
87 | to_return.intensity[effect_name] *= value | 94 | to_return.intensity[effect_name] *= value | ||
88 | self.round_intensity(to_return,effect_name) | 95 | self.round_intensity(to_return,effect_name) | ||
89 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 96 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
90 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | 97 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||
91 | for effect_name in self.effects: | 98 | for effect_name in self.effects: | ||
92 | setattr(self, effect_name, self.already_used) | 99 | setattr(self, effect_name, self.already_used) | ||
93 | self.was_used = True | 100 | self.was_used = True | ||
94 | return to_return | 101 | return to_return | ||
95 | to_return = Potion(self.effects, self.duration) | 102 | to_return = Potion(self.effects, self.duration) | ||
96 | for effect_name in to_return.effects: | 103 | for effect_name in to_return.effects: | ||
97 | to_return.intensity[effect_name] = self.intensity[effect_name] | 104 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
98 | for effect_name in to_return.effects: | 105 | for effect_name in to_return.effects: | ||
99 | to_return.intensity[effect_name] *= value | 106 | to_return.intensity[effect_name] *= value | ||
100 | for effect_name,effect in to_return.effects.items(): | 107 | for effect_name,effect in to_return.effects.items(): | ||
101 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 108 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
102 | for effect_name in self.effects: | 109 | for effect_name in self.effects: | ||
103 | setattr(self, effect_name, self.already_used) | 110 | setattr(self, effect_name, self.already_used) | ||
104 | self.was_used = True | 111 | self.was_used = True | ||
105 | return to_return | 112 | return to_return | ||
106 | 113 | ||||
107 | def __sub__(self, other): | 114 | def __sub__(self, other): | ||
108 | if self.is_depleted() or other.is_depleted(): | 115 | if self.is_depleted() or other.is_depleted(): | ||
109 | raise TypeError("Potion is depleted.") | 116 | raise TypeError("Potion is depleted.") | ||
110 | if self.was_used == True or other.was_used == True: | 117 | if self.was_used == True or other.was_used == True: | ||
111 | raise TypeError("Potion is now part of something bigger than itself.") | 118 | raise TypeError("Potion is now part of something bigger than itself.") | ||
112 | to_return = Potion(self.effects, self.duration) | 119 | to_return = Potion(self.effects, self.duration) | ||
113 | for effect_name,effect in to_return.effects.items(): | 120 | for effect_name,effect in to_return.effects.items(): | ||
114 | to_return.intensity[effect_name] = self.intensity[effect_name] | 121 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
115 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | 122 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | ||
n | 116 | for effect in other.effects.values(): | n | 123 | for effect_name in other.effects: |
117 | if effect not in to_return.effects.values(): | 124 | if effect_name not in to_return.effects: | ||
118 | raise TypeError("Error") | 125 | raise TypeError("Error") | ||
119 | for effect_name, effect in other.effects.items(): | 126 | for effect_name, effect in other.effects.items(): | ||
120 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | 127 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | ||
121 | to_return.intensity[effect_name] -= other.intensity[effect_name] | 128 | to_return.intensity[effect_name] -= other.intensity[effect_name] | ||
122 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 129 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
123 | else: | 130 | else: | ||
124 | delattr(to_return, effect_name) | 131 | delattr(to_return, effect_name) | ||
125 | del to_return.effects[effect_name] | 132 | del to_return.effects[effect_name] | ||
126 | del to_return.intensity[effect_name] | 133 | del to_return.intensity[effect_name] | ||
127 | for effect_name in self.effects: | 134 | for effect_name in self.effects: | ||
128 | setattr(self, effect_name, self.already_used) | 135 | setattr(self, effect_name, self.already_used) | ||
129 | for effect_name in other.effects: | 136 | for effect_name in other.effects: | ||
130 | setattr(other, effect_name, other.already_used) | 137 | setattr(other, effect_name, other.already_used) | ||
131 | self.was_used = other.was_used = True | 138 | self.was_used = other.was_used = True | ||
132 | return to_return | 139 | return to_return | ||
133 | 140 | ||||
134 | def __truediv__(self, value): | 141 | def __truediv__(self, value): | ||
135 | if self.is_depleted(): | 142 | if self.is_depleted(): | ||
136 | raise TypeError("Potion is depleted.") | 143 | raise TypeError("Potion is depleted.") | ||
137 | if self.was_used == True: | 144 | if self.was_used == True: | ||
138 | raise TypeError("Potion is now part of something bigger than itself.") | 145 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 139 | copy=Potion(self.effects,self.duration) | n | 146 | copy_potion=Potion(self.effects,self.duration) |
140 | for effect_name in self.intensity: | 147 | for effect_name in self.intensity: | ||
n | 141 | copy.intensity[effect_name] = self.intensity[effect_name] | n | 148 | copy_potion.intensity[effect_name] = self.intensity[effect_name] |
142 | for effect_name,effect in copy.effects.items(): | 149 | for effect_name,effect in copy_potion.effects.items(): | ||
143 | copy.intensity[effect_name] /= value | 150 | copy_potion.intensity[effect_name] /= value | ||
144 | self.round_intensity(copy,effect_name) | 151 | self.round_intensity(copy_potion,effect_name) | ||
145 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | 152 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | ||
n | 146 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | n | 153 | setattr(copy_potion,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name])) |
147 | potion_list=[] | 154 | potion_list=[] | ||
148 | for _ in range(value): | 155 | for _ in range(value): | ||
n | n | 156 | copy=Potion(copy_potion.effects,copy_potion.duration) | ||
157 | for effect_name in copy_potion.intensity: | ||||
158 | copy.intensity[effect_name] = copy_potion.intensity[effect_name] | ||||
159 | for effect_name,effect in copy_potion.effects.items(): | ||||
160 | setattr(copy,effect_name, calling_function_decorator(effect, copy_potion.intensity[effect_name])) | ||||
149 | potion_list.append(copy) | 161 | potion_list.append(copy) | ||
150 | for effect_name in self.effects: | 162 | for effect_name in self.effects: | ||
151 | setattr(self, effect_name, self.already_used) | 163 | setattr(self, effect_name, self.already_used) | ||
152 | self.was_used = True | 164 | self.was_used = True | ||
153 | return tuple(potion_list) | 165 | return tuple(potion_list) | ||
154 | 166 | ||||
n | 155 | def __bool__(self,other): | n | 167 | def __eq__(self,other): |
156 | if self.is_depleted() or other.is_depleted(): | 168 | if self.is_depleted() or other.is_depleted(): | ||
157 | raise TypeError("Potion is depleted.") | 169 | raise TypeError("Potion is depleted.") | ||
158 | if self.was_used == True or other.was_used == True: | 170 | if self.was_used == True or other.was_used == True: | ||
159 | raise TypeError("Potion is now part of something bigger than itself.") | 171 | raise TypeError("Potion is now part of something bigger than itself.") | ||
160 | for effect_name in self.effects: | 172 | for effect_name in self.effects: | ||
161 | if effect_name not in other.effects: | 173 | if effect_name not in other.effects: | ||
162 | return False | 174 | return False | ||
n | 163 | for effect_name in self.effect: | n | 175 | for effect_name in self.effects: |
164 | if self.intensity[effect_name] != other.intensity[effect_name]: | 176 | if self.intensity[effect_name] != other.intensity[effect_name]: | ||
165 | return False | 177 | return False | ||
166 | return True | 178 | return True | ||
167 | 179 | ||||
168 | def __gt__(self,other): | 180 | def __gt__(self,other): | ||
169 | if self.is_depleted() or other.is_depleted(): | 181 | if self.is_depleted() or other.is_depleted(): | ||
170 | raise TypeError("Potion is depleted.") | 182 | raise TypeError("Potion is depleted.") | ||
171 | if self.was_used == True or other.was_used == True: | 183 | if self.was_used == True or other.was_used == True: | ||
172 | raise TypeError("Potion is now part of something bigger than itself.") | 184 | raise TypeError("Potion is now part of something bigger than itself.") | ||
173 | sum_of_self = 0 | 185 | sum_of_self = 0 | ||
174 | for effect_name in self.intensity: | 186 | for effect_name in self.intensity: | ||
175 | sum_of_self+=self.intensity[effect_name] | 187 | sum_of_self+=self.intensity[effect_name] | ||
176 | sum_of_other = 0 | 188 | sum_of_other = 0 | ||
177 | for effect_name in other.intensity: | 189 | for effect_name in other.intensity: | ||
178 | sum_of_other += other.intensity[effect_name] | 190 | sum_of_other += other.intensity[effect_name] | ||
179 | return sum_of_self > sum_of_other | 191 | return sum_of_self > sum_of_other | ||
n | n | 192 | |||
180 | 193 | ||||
181 | def sorting_potions(potion): | 194 | def sorting_potions(potion): | ||
182 | name = potion[0] | 195 | name = potion[0] | ||
183 | sum_of_potion_name = 0 | 196 | sum_of_potion_name = 0 | ||
184 | for letter in name: | 197 | for letter in name: | ||
185 | sum_of_potion_name += ord(letter) | 198 | sum_of_potion_name += ord(letter) | ||
186 | return sum_of_potion_name | 199 | return sum_of_potion_name | ||
187 | 200 | ||||
188 | 201 | ||||
189 | class ГоспожатаПоХимия: | 202 | class ГоспожатаПоХимия: | ||
190 | def __init__(self): | 203 | def __init__(self): | ||
191 | self.used_potions = [] | 204 | self.used_potions = [] | ||
192 | self.targets_copies = {} | 205 | self.targets_copies = {} | ||
193 | self.targets_buffed_copies = {} | 206 | self.targets_buffed_copies = {} | ||
194 | 207 | ||||
195 | def apply(self, target, potion): | 208 | def apply(self, target, potion): | ||
196 | if potion.duration == 0: | 209 | if potion.duration == 0: | ||
197 | return | 210 | return | ||
198 | if potion.is_depleted(): | 211 | if potion.is_depleted(): | ||
199 | raise TypeError("Potion is depleted.") | 212 | raise TypeError("Potion is depleted.") | ||
n | n | 213 | if potion.was_used: | ||
214 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
200 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | 215 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | ||
201 | potion.effects = dict(sorted_potions) | 216 | potion.effects = dict(sorted_potions) | ||
n | 202 | potion.was_used = True | n | ||
203 | if target not in self.targets_buffed_copies.values(): | 217 | if target not in self.targets_buffed_copies.values(): | ||
204 | self.targets_copies[potion] = copy.copy(target) | 218 | self.targets_copies[potion] = copy.copy(target) | ||
205 | else: | 219 | else: | ||
206 | for potion_loop in self.used_potions: | 220 | for potion_loop in self.used_potions: | ||
n | n | 221 | potion_loop.was_used = False | ||
207 | if self.targets_buffed_copies[potion_loop] == target: | 222 | if self.targets_buffed_copies[potion_loop] == target: | ||
208 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | 223 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | ||
n | n | 224 | potion_loop.was_used = True | ||
209 | self.used_potions.append(potion) | 225 | self.used_potions.append(potion) | ||
210 | for effect_name in potion.effects: | 226 | for effect_name in potion.effects: | ||
211 | function = getattr(potion, effect_name) | 227 | function = getattr(potion, effect_name) | ||
212 | try: | 228 | try: | ||
213 | function(target) | 229 | function(target) | ||
214 | except TypeError: | 230 | except TypeError: | ||
215 | continue | 231 | continue | ||
n | n | 232 | for potion_iter in self.used_potions: | ||
233 | potion_iter.was_used = False | ||||
216 | self.targets_buffed_copies[potion] = target | 234 | self.targets_buffed_copies[potion] = target | ||
n | n | 235 | potion.was_used = True | ||
236 | for potion_iter in self.used_potions: | ||||
237 | potion_iter.was_used = True | ||||
217 | 238 | ||||
218 | def tick(self): | 239 | def tick(self): | ||
219 | for potion in self.used_potions: | 240 | for potion in self.used_potions: | ||
220 | potion.duration -= 1 | 241 | potion.duration -= 1 | ||
221 | if potion.duration == 0: | 242 | if potion.duration == 0: | ||
222 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | 243 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | ||
223 | for potion_inner in self.used_potions: | 244 | for potion_inner in self.used_potions: | ||
n | n | 245 | potion_inner.was_used = False | ||
246 | potion.was_used = False | ||||
224 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | 247 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | ||
n | n | 248 | potion_inner.was_used = True | ||
249 | potion.was_used = True | ||||
225 | continue | 250 | continue | ||
t | t | 251 | potion_inner.was_used = True | ||
252 | potion.was_used = True | ||||
226 | copy = Potion(potion_inner.effects,potion_inner.duration) | 253 | copy = Potion(potion_inner.effects,potion_inner.duration) | ||
227 | for effect_name,effect in copy.effects.items(): | 254 | for effect_name,effect in copy.effects.items(): | ||
228 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | 255 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | ||
229 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | 256 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
230 | for effect_name in copy.effects: | 257 | for effect_name in copy.effects: | ||
231 | function = getattr(copy, effect_name) | 258 | function = getattr(copy, effect_name) | ||
232 | function(self.targets_buffed_copies[potion]) | 259 | function(self.targets_buffed_copies[potion]) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | import copy | 2 | import copy | ||
3 | 3 | ||||
4 | def once(func): | 4 | def once(func): | ||
5 | def wrapper(target): | 5 | def wrapper(target): | ||
6 | if wrapper.called: | 6 | if wrapper.called: | ||
7 | raise TypeError("Effect is depleted.") | 7 | raise TypeError("Effect is depleted.") | ||
8 | wrapper.called = True | 8 | wrapper.called = True | ||
9 | func(target) | 9 | func(target) | ||
10 | wrapper.called = False | 10 | wrapper.called = False | ||
11 | return wrapper | 11 | return wrapper | ||
12 | 12 | ||||
13 | def calling_function_decorator(function, times): | 13 | def calling_function_decorator(function, times): | ||
14 | @once | 14 | @once | ||
15 | def decorator(target): | 15 | def decorator(target): | ||
16 | for _ in range(times): | 16 | for _ in range(times): | ||
17 | function(target) | 17 | function(target) | ||
18 | return decorator | 18 | return decorator | ||
19 | 19 | ||||
20 | class Potion: | 20 | class Potion: | ||
21 | 21 | ||||
22 | def round_intensity(self,to_return,effect_name): | 22 | def round_intensity(self,to_return,effect_name): | ||
n | 23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | n | 23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= int(to_return.intensity[effect_name]) +0.5 else math.ceil(to_return.intensity[effect_name]) |
24 | 24 | ||||
25 | def is_depleted(self): | 25 | def is_depleted(self): | ||
26 | is_depleted = True | 26 | is_depleted = True | ||
27 | for effect_name,effect in self.effects.items(): | 27 | for effect_name,effect in self.effects.items(): | ||
28 | function = getattr(self, effect_name) | 28 | function = getattr(self, effect_name) | ||
29 | try: | 29 | try: | ||
30 | function(None) | 30 | function(None) | ||
31 | except TypeError: | 31 | except TypeError: | ||
32 | is_depleted = True | 32 | is_depleted = True | ||
33 | except AttributeError: | 33 | except AttributeError: | ||
34 | is_depleted = False | 34 | is_depleted = False | ||
35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
36 | return is_depleted | 36 | return is_depleted | ||
37 | 37 | ||||
38 | @staticmethod | 38 | @staticmethod | ||
39 | def already_used(target): | 39 | def already_used(target): | ||
40 | raise TypeError("Potion is now part of something bigger than itself.") | 40 | raise TypeError("Potion is now part of something bigger than itself.") | ||
41 | 41 | ||||
42 | def __init__(self,effects, duration): | 42 | def __init__(self,effects, duration): | ||
43 | self.effects = copy.copy(effects) | 43 | self.effects = copy.copy(effects) | ||
44 | self.was_used = False | 44 | self.was_used = False | ||
45 | self.intensity = {} | 45 | self.intensity = {} | ||
46 | for effect_name in self.effects: | 46 | for effect_name in self.effects: | ||
47 | self.intensity[effect_name] = 1 | 47 | self.intensity[effect_name] = 1 | ||
48 | for effect_name,effect in effects.items(): | 48 | for effect_name,effect in effects.items(): | ||
49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
50 | self.effects[effect_name] = effect | 50 | self.effects[effect_name] = effect | ||
51 | self.duration = duration | 51 | self.duration = duration | ||
52 | 52 | ||||
53 | def __add__(self, other): | 53 | def __add__(self, other): | ||
54 | if self.is_depleted() or other.is_depleted(): | 54 | if self.is_depleted() or other.is_depleted(): | ||
55 | raise TypeError("Potion is depleted.") | 55 | raise TypeError("Potion is depleted.") | ||
56 | if self.was_used == True or other.was_used == True: | 56 | if self.was_used == True or other.was_used == True: | ||
57 | raise TypeError("Potion is now part of something bigger than itself.") | 57 | raise TypeError("Potion is now part of something bigger than itself.") | ||
58 | to_return = Potion(self.effects, max(self.duration, other.duration)) | 58 | to_return = Potion(self.effects, max(self.duration, other.duration)) | ||
59 | for effect_name,effect in to_return.effects.items(): | 59 | for effect_name,effect in to_return.effects.items(): | ||
60 | to_return.intensity[effect_name]=self.intensity[effect_name] | 60 | to_return.intensity[effect_name]=self.intensity[effect_name] | ||
61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
62 | for effect_name,effect in other.effects.items(): | 62 | for effect_name,effect in other.effects.items(): | ||
63 | if effect_name in to_return.effects: | 63 | if effect_name in to_return.effects: | ||
64 | to_return.intensity[effect_name] += 1 | 64 | to_return.intensity[effect_name] += 1 | ||
65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
66 | else: | 66 | else: | ||
n | 67 | to_return.intensity[effect_name] = 1 | n | 67 | to_return.intensity[effect_name] = other.intensity[effect_name] |
68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
69 | to_return.effects[effect_name] = effect | 69 | to_return.effects[effect_name] = effect | ||
70 | for effect_name in self.effects: | 70 | for effect_name in self.effects: | ||
71 | setattr(self, effect_name, self.already_used) | 71 | setattr(self, effect_name, self.already_used) | ||
72 | for effect_name in other.effects: | 72 | for effect_name in other.effects: | ||
73 | setattr(other, effect_name, other.already_used) | 73 | setattr(other, effect_name, other.already_used) | ||
74 | self.was_used = other.was_used = True | 74 | self.was_used = other.was_used = True | ||
75 | return to_return | 75 | return to_return | ||
76 | 76 | ||||
77 | def __mul__(self, value): | 77 | def __mul__(self, value): | ||
78 | if self.is_depleted(): | 78 | if self.is_depleted(): | ||
79 | raise TypeError("Potion is depleted.") | 79 | raise TypeError("Potion is depleted.") | ||
80 | if self.was_used == True: | 80 | if self.was_used == True: | ||
81 | raise TypeError("Potion is now part of something bigger than itself.") | 81 | raise TypeError("Potion is now part of something bigger than itself.") | ||
82 | if value >= 0 and value <= 1: | 82 | if value >= 0 and value <= 1: | ||
83 | to_return = Potion(self.effects, self.duration) | 83 | to_return = Potion(self.effects, self.duration) | ||
84 | for effect_name in to_return.effects: | 84 | for effect_name in to_return.effects: | ||
85 | to_return.intensity[effect_name] = self.intensity[effect_name] | 85 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
n | 86 | for effect_name in to_return.effects: | n | 86 | for effect_name,effect in to_return.effects.items(): |
87 | to_return.intensity[effect_name] *= value | 87 | to_return.intensity[effect_name] *= value | ||
88 | self.round_intensity(to_return,effect_name) | 88 | self.round_intensity(to_return,effect_name) | ||
n | n | 89 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
89 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | 90 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||
90 | for effect_name,effect in to_return.effects.items(): | ||||
91 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||||
92 | for effect_name in self.effects: | 91 | for effect_name in self.effects: | ||
93 | setattr(self, effect_name, self.already_used) | 92 | setattr(self, effect_name, self.already_used) | ||
94 | self.was_used = True | 93 | self.was_used = True | ||
95 | return to_return | 94 | return to_return | ||
96 | to_return = Potion(self.effects, self.duration) | 95 | to_return = Potion(self.effects, self.duration) | ||
97 | for effect_name in to_return.effects: | 96 | for effect_name in to_return.effects: | ||
98 | to_return.intensity[effect_name] = self.intensity[effect_name] | 97 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
99 | for effect_name in to_return.effects: | 98 | for effect_name in to_return.effects: | ||
100 | to_return.intensity[effect_name] *= value | 99 | to_return.intensity[effect_name] *= value | ||
101 | for effect_name,effect in to_return.effects.items(): | 100 | for effect_name,effect in to_return.effects.items(): | ||
102 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 101 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
103 | for effect_name in self.effects: | 102 | for effect_name in self.effects: | ||
104 | setattr(self, effect_name, self.already_used) | 103 | setattr(self, effect_name, self.already_used) | ||
105 | self.was_used = True | 104 | self.was_used = True | ||
106 | return to_return | 105 | return to_return | ||
107 | 106 | ||||
108 | def __sub__(self, other): | 107 | def __sub__(self, other): | ||
109 | if self.is_depleted() or other.is_depleted(): | 108 | if self.is_depleted() or other.is_depleted(): | ||
110 | raise TypeError("Potion is depleted.") | 109 | raise TypeError("Potion is depleted.") | ||
111 | if self.was_used == True or other.was_used == True: | 110 | if self.was_used == True or other.was_used == True: | ||
112 | raise TypeError("Potion is now part of something bigger than itself.") | 111 | raise TypeError("Potion is now part of something bigger than itself.") | ||
113 | to_return = Potion(self.effects, self.duration) | 112 | to_return = Potion(self.effects, self.duration) | ||
114 | for effect_name,effect in to_return.effects.items(): | 113 | for effect_name,effect in to_return.effects.items(): | ||
115 | to_return.intensity[effect_name] = self.intensity[effect_name] | 114 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
116 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | 115 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | ||
117 | for effect in other.effects.values(): | 116 | for effect in other.effects.values(): | ||
118 | if effect not in to_return.effects.values(): | 117 | if effect not in to_return.effects.values(): | ||
119 | raise TypeError("Error") | 118 | raise TypeError("Error") | ||
120 | for effect_name, effect in other.effects.items(): | 119 | for effect_name, effect in other.effects.items(): | ||
121 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | 120 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | ||
122 | to_return.intensity[effect_name] -= other.intensity[effect_name] | 121 | to_return.intensity[effect_name] -= other.intensity[effect_name] | ||
123 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 122 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
124 | else: | 123 | else: | ||
125 | delattr(to_return, effect_name) | 124 | delattr(to_return, effect_name) | ||
126 | del to_return.effects[effect_name] | 125 | del to_return.effects[effect_name] | ||
127 | del to_return.intensity[effect_name] | 126 | del to_return.intensity[effect_name] | ||
128 | for effect_name in self.effects: | 127 | for effect_name in self.effects: | ||
129 | setattr(self, effect_name, self.already_used) | 128 | setattr(self, effect_name, self.already_used) | ||
130 | for effect_name in other.effects: | 129 | for effect_name in other.effects: | ||
131 | setattr(other, effect_name, other.already_used) | 130 | setattr(other, effect_name, other.already_used) | ||
132 | self.was_used = other.was_used = True | 131 | self.was_used = other.was_used = True | ||
133 | return to_return | 132 | return to_return | ||
134 | 133 | ||||
135 | def __truediv__(self, value): | 134 | def __truediv__(self, value): | ||
136 | if self.is_depleted(): | 135 | if self.is_depleted(): | ||
137 | raise TypeError("Potion is depleted.") | 136 | raise TypeError("Potion is depleted.") | ||
138 | if self.was_used == True: | 137 | if self.was_used == True: | ||
139 | raise TypeError("Potion is now part of something bigger than itself.") | 138 | raise TypeError("Potion is now part of something bigger than itself.") | ||
140 | copy=Potion(self.effects,self.duration) | 139 | copy=Potion(self.effects,self.duration) | ||
141 | for effect_name in self.intensity: | 140 | for effect_name in self.intensity: | ||
142 | copy.intensity[effect_name] = self.intensity[effect_name] | 141 | copy.intensity[effect_name] = self.intensity[effect_name] | ||
143 | for effect_name,effect in copy.effects.items(): | 142 | for effect_name,effect in copy.effects.items(): | ||
144 | copy.intensity[effect_name] /= value | 143 | copy.intensity[effect_name] /= value | ||
145 | self.round_intensity(copy,effect_name) | 144 | self.round_intensity(copy,effect_name) | ||
146 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | 145 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | ||
147 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | 146 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
148 | potion_list=[] | 147 | potion_list=[] | ||
149 | for _ in range(value): | 148 | for _ in range(value): | ||
150 | potion_list.append(copy) | 149 | potion_list.append(copy) | ||
151 | for effect_name in self.effects: | 150 | for effect_name in self.effects: | ||
152 | setattr(self, effect_name, self.already_used) | 151 | setattr(self, effect_name, self.already_used) | ||
153 | self.was_used = True | 152 | self.was_used = True | ||
154 | return tuple(potion_list) | 153 | return tuple(potion_list) | ||
155 | 154 | ||||
156 | def __bool__(self,other): | 155 | def __bool__(self,other): | ||
157 | if self.is_depleted() or other.is_depleted(): | 156 | if self.is_depleted() or other.is_depleted(): | ||
158 | raise TypeError("Potion is depleted.") | 157 | raise TypeError("Potion is depleted.") | ||
159 | if self.was_used == True or other.was_used == True: | 158 | if self.was_used == True or other.was_used == True: | ||
160 | raise TypeError("Potion is now part of something bigger than itself.") | 159 | raise TypeError("Potion is now part of something bigger than itself.") | ||
161 | for effect_name in self.effects: | 160 | for effect_name in self.effects: | ||
162 | if effect_name not in other.effects: | 161 | if effect_name not in other.effects: | ||
163 | return False | 162 | return False | ||
164 | for effect_name in self.effect: | 163 | for effect_name in self.effect: | ||
165 | if self.intensity[effect_name] != other.intensity[effect_name]: | 164 | if self.intensity[effect_name] != other.intensity[effect_name]: | ||
166 | return False | 165 | return False | ||
167 | return True | 166 | return True | ||
168 | 167 | ||||
169 | def __gt__(self,other): | 168 | def __gt__(self,other): | ||
170 | if self.is_depleted() or other.is_depleted(): | 169 | if self.is_depleted() or other.is_depleted(): | ||
171 | raise TypeError("Potion is depleted.") | 170 | raise TypeError("Potion is depleted.") | ||
172 | if self.was_used == True or other.was_used == True: | 171 | if self.was_used == True or other.was_used == True: | ||
173 | raise TypeError("Potion is now part of something bigger than itself.") | 172 | raise TypeError("Potion is now part of something bigger than itself.") | ||
174 | sum_of_self = 0 | 173 | sum_of_self = 0 | ||
175 | for effect_name in self.intensity: | 174 | for effect_name in self.intensity: | ||
176 | sum_of_self+=self.intensity[effect_name] | 175 | sum_of_self+=self.intensity[effect_name] | ||
177 | sum_of_other = 0 | 176 | sum_of_other = 0 | ||
178 | for effect_name in other.intensity: | 177 | for effect_name in other.intensity: | ||
179 | sum_of_other += other.intensity[effect_name] | 178 | sum_of_other += other.intensity[effect_name] | ||
180 | return sum_of_self > sum_of_other | 179 | return sum_of_self > sum_of_other | ||
181 | 180 | ||||
182 | def sorting_potions(potion): | 181 | def sorting_potions(potion): | ||
183 | name = potion[0] | 182 | name = potion[0] | ||
184 | sum_of_potion_name = 0 | 183 | sum_of_potion_name = 0 | ||
185 | for letter in name: | 184 | for letter in name: | ||
186 | sum_of_potion_name += ord(letter) | 185 | sum_of_potion_name += ord(letter) | ||
187 | return sum_of_potion_name | 186 | return sum_of_potion_name | ||
188 | 187 | ||||
189 | 188 | ||||
190 | class ГоспожатаПоХимия: | 189 | class ГоспожатаПоХимия: | ||
191 | def __init__(self): | 190 | def __init__(self): | ||
192 | self.used_potions = [] | 191 | self.used_potions = [] | ||
193 | self.targets_copies = {} | 192 | self.targets_copies = {} | ||
194 | self.targets_buffed_copies = {} | 193 | self.targets_buffed_copies = {} | ||
195 | 194 | ||||
196 | def apply(self, target, potion): | 195 | def apply(self, target, potion): | ||
t | t | 196 | if potion.duration == 0: | ||
197 | return | ||||
197 | if potion.is_depleted(): | 198 | if potion.is_depleted(): | ||
198 | raise TypeError("Potion is depleted.") | 199 | raise TypeError("Potion is depleted.") | ||
199 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | 200 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | ||
200 | potion.effects = dict(sorted_potions) | 201 | potion.effects = dict(sorted_potions) | ||
201 | potion.was_used = True | 202 | potion.was_used = True | ||
202 | if target not in self.targets_buffed_copies.values(): | 203 | if target not in self.targets_buffed_copies.values(): | ||
203 | self.targets_copies[potion] = copy.copy(target) | 204 | self.targets_copies[potion] = copy.copy(target) | ||
204 | else: | 205 | else: | ||
205 | for potion_loop in self.used_potions: | 206 | for potion_loop in self.used_potions: | ||
206 | if self.targets_buffed_copies[potion_loop] == target: | 207 | if self.targets_buffed_copies[potion_loop] == target: | ||
207 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | 208 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | ||
208 | self.used_potions.append(potion) | 209 | self.used_potions.append(potion) | ||
209 | for effect_name in potion.effects: | 210 | for effect_name in potion.effects: | ||
210 | function = getattr(potion, effect_name) | 211 | function = getattr(potion, effect_name) | ||
211 | try: | 212 | try: | ||
212 | function(target) | 213 | function(target) | ||
213 | except TypeError: | 214 | except TypeError: | ||
214 | continue | 215 | continue | ||
215 | self.targets_buffed_copies[potion] = target | 216 | self.targets_buffed_copies[potion] = target | ||
216 | 217 | ||||
217 | def tick(self): | 218 | def tick(self): | ||
218 | for potion in self.used_potions: | 219 | for potion in self.used_potions: | ||
219 | potion.duration -= 1 | 220 | potion.duration -= 1 | ||
220 | if potion.duration == 0: | 221 | if potion.duration == 0: | ||
221 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | 222 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | ||
222 | for potion_inner in self.used_potions: | 223 | for potion_inner in self.used_potions: | ||
223 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | 224 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | ||
224 | continue | 225 | continue | ||
225 | copy = Potion(potion_inner.effects,potion_inner.duration) | 226 | copy = Potion(potion_inner.effects,potion_inner.duration) | ||
226 | for effect_name,effect in copy.effects.items(): | 227 | for effect_name,effect in copy.effects.items(): | ||
227 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | 228 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | ||
228 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | 229 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
229 | for effect_name in copy.effects: | 230 | for effect_name in copy.effects: | ||
230 | function = getattr(copy, effect_name) | 231 | function = getattr(copy, effect_name) | ||
231 | function(self.targets_buffed_copies[potion]) | 232 | function(self.targets_buffed_copies[potion]) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | import copy | 2 | import copy | ||
3 | 3 | ||||
4 | def once(func): | 4 | def once(func): | ||
5 | def wrapper(target): | 5 | def wrapper(target): | ||
6 | if wrapper.called: | 6 | if wrapper.called: | ||
7 | raise TypeError("Effect is depleted.") | 7 | raise TypeError("Effect is depleted.") | ||
8 | wrapper.called = True | 8 | wrapper.called = True | ||
9 | func(target) | 9 | func(target) | ||
10 | wrapper.called = False | 10 | wrapper.called = False | ||
11 | return wrapper | 11 | return wrapper | ||
12 | 12 | ||||
13 | def calling_function_decorator(function, times): | 13 | def calling_function_decorator(function, times): | ||
14 | @once | 14 | @once | ||
15 | def decorator(target): | 15 | def decorator(target): | ||
16 | for _ in range(times): | 16 | for _ in range(times): | ||
17 | function(target) | 17 | function(target) | ||
18 | return decorator | 18 | return decorator | ||
19 | 19 | ||||
20 | class Potion: | 20 | class Potion: | ||
21 | 21 | ||||
22 | def round_intensity(self,to_return,effect_name): | 22 | def round_intensity(self,to_return,effect_name): | ||
23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | 23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||
24 | 24 | ||||
25 | def is_depleted(self): | 25 | def is_depleted(self): | ||
26 | is_depleted = True | 26 | is_depleted = True | ||
27 | for effect_name,effect in self.effects.items(): | 27 | for effect_name,effect in self.effects.items(): | ||
28 | function = getattr(self, effect_name) | 28 | function = getattr(self, effect_name) | ||
29 | try: | 29 | try: | ||
30 | function(None) | 30 | function(None) | ||
31 | except TypeError: | 31 | except TypeError: | ||
32 | is_depleted = True | 32 | is_depleted = True | ||
33 | except AttributeError: | 33 | except AttributeError: | ||
34 | is_depleted = False | 34 | is_depleted = False | ||
35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
36 | return is_depleted | 36 | return is_depleted | ||
37 | 37 | ||||
38 | @staticmethod | 38 | @staticmethod | ||
39 | def already_used(target): | 39 | def already_used(target): | ||
40 | raise TypeError("Potion is now part of something bigger than itself.") | 40 | raise TypeError("Potion is now part of something bigger than itself.") | ||
41 | 41 | ||||
42 | def __init__(self,effects, duration): | 42 | def __init__(self,effects, duration): | ||
43 | self.effects = copy.copy(effects) | 43 | self.effects = copy.copy(effects) | ||
44 | self.was_used = False | 44 | self.was_used = False | ||
45 | self.intensity = {} | 45 | self.intensity = {} | ||
46 | for effect_name in self.effects: | 46 | for effect_name in self.effects: | ||
47 | self.intensity[effect_name] = 1 | 47 | self.intensity[effect_name] = 1 | ||
48 | for effect_name,effect in effects.items(): | 48 | for effect_name,effect in effects.items(): | ||
49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | 49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
50 | self.effects[effect_name] = effect | 50 | self.effects[effect_name] = effect | ||
51 | self.duration = duration | 51 | self.duration = duration | ||
52 | 52 | ||||
53 | def __add__(self, other): | 53 | def __add__(self, other): | ||
n | 54 | if self.is_depleted(): | n | 54 | if self.is_depleted() or other.is_depleted(): |
55 | raise TypeError("Potion is depleted.") | 55 | raise TypeError("Potion is depleted.") | ||
56 | if self.was_used == True or other.was_used == True: | 56 | if self.was_used == True or other.was_used == True: | ||
57 | raise TypeError("Potion is now part of something bigger than itself.") | 57 | raise TypeError("Potion is now part of something bigger than itself.") | ||
58 | to_return = Potion(self.effects, max(self.duration, other.duration)) | 58 | to_return = Potion(self.effects, max(self.duration, other.duration)) | ||
59 | for effect_name,effect in to_return.effects.items(): | 59 | for effect_name,effect in to_return.effects.items(): | ||
60 | to_return.intensity[effect_name]=self.intensity[effect_name] | 60 | to_return.intensity[effect_name]=self.intensity[effect_name] | ||
61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
62 | for effect_name,effect in other.effects.items(): | 62 | for effect_name,effect in other.effects.items(): | ||
63 | if effect_name in to_return.effects: | 63 | if effect_name in to_return.effects: | ||
64 | to_return.intensity[effect_name] += 1 | 64 | to_return.intensity[effect_name] += 1 | ||
65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
66 | else: | 66 | else: | ||
67 | to_return.intensity[effect_name] = 1 | 67 | to_return.intensity[effect_name] = 1 | ||
68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
69 | to_return.effects[effect_name] = effect | 69 | to_return.effects[effect_name] = effect | ||
70 | for effect_name in self.effects: | 70 | for effect_name in self.effects: | ||
71 | setattr(self, effect_name, self.already_used) | 71 | setattr(self, effect_name, self.already_used) | ||
72 | for effect_name in other.effects: | 72 | for effect_name in other.effects: | ||
73 | setattr(other, effect_name, other.already_used) | 73 | setattr(other, effect_name, other.already_used) | ||
74 | self.was_used = other.was_used = True | 74 | self.was_used = other.was_used = True | ||
75 | return to_return | 75 | return to_return | ||
76 | 76 | ||||
77 | def __mul__(self, value): | 77 | def __mul__(self, value): | ||
78 | if self.is_depleted(): | 78 | if self.is_depleted(): | ||
79 | raise TypeError("Potion is depleted.") | 79 | raise TypeError("Potion is depleted.") | ||
80 | if self.was_used == True: | 80 | if self.was_used == True: | ||
81 | raise TypeError("Potion is now part of something bigger than itself.") | 81 | raise TypeError("Potion is now part of something bigger than itself.") | ||
82 | if value >= 0 and value <= 1: | 82 | if value >= 0 and value <= 1: | ||
83 | to_return = Potion(self.effects, self.duration) | 83 | to_return = Potion(self.effects, self.duration) | ||
84 | for effect_name in to_return.effects: | 84 | for effect_name in to_return.effects: | ||
85 | to_return.intensity[effect_name] = self.intensity[effect_name] | 85 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
86 | for effect_name in to_return.effects: | 86 | for effect_name in to_return.effects: | ||
87 | to_return.intensity[effect_name] *= value | 87 | to_return.intensity[effect_name] *= value | ||
88 | self.round_intensity(to_return,effect_name) | 88 | self.round_intensity(to_return,effect_name) | ||
89 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | 89 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||
90 | for effect_name,effect in to_return.effects.items(): | 90 | for effect_name,effect in to_return.effects.items(): | ||
91 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 91 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
92 | for effect_name in self.effects: | 92 | for effect_name in self.effects: | ||
93 | setattr(self, effect_name, self.already_used) | 93 | setattr(self, effect_name, self.already_used) | ||
94 | self.was_used = True | 94 | self.was_used = True | ||
95 | return to_return | 95 | return to_return | ||
96 | to_return = Potion(self.effects, self.duration) | 96 | to_return = Potion(self.effects, self.duration) | ||
97 | for effect_name in to_return.effects: | 97 | for effect_name in to_return.effects: | ||
98 | to_return.intensity[effect_name] = self.intensity[effect_name] | 98 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
99 | for effect_name in to_return.effects: | 99 | for effect_name in to_return.effects: | ||
100 | to_return.intensity[effect_name] *= value | 100 | to_return.intensity[effect_name] *= value | ||
101 | for effect_name,effect in to_return.effects.items(): | 101 | for effect_name,effect in to_return.effects.items(): | ||
102 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 102 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
103 | for effect_name in self.effects: | 103 | for effect_name in self.effects: | ||
104 | setattr(self, effect_name, self.already_used) | 104 | setattr(self, effect_name, self.already_used) | ||
105 | self.was_used = True | 105 | self.was_used = True | ||
106 | return to_return | 106 | return to_return | ||
107 | 107 | ||||
108 | def __sub__(self, other): | 108 | def __sub__(self, other): | ||
n | 109 | if self.is_depleted(): | n | 109 | if self.is_depleted() or other.is_depleted(): |
110 | raise TypeError("Potion is depleted.") | 110 | raise TypeError("Potion is depleted.") | ||
111 | if self.was_used == True or other.was_used == True: | 111 | if self.was_used == True or other.was_used == True: | ||
112 | raise TypeError("Potion is now part of something bigger than itself.") | 112 | raise TypeError("Potion is now part of something bigger than itself.") | ||
113 | to_return = Potion(self.effects, self.duration) | 113 | to_return = Potion(self.effects, self.duration) | ||
114 | for effect_name,effect in to_return.effects.items(): | 114 | for effect_name,effect in to_return.effects.items(): | ||
115 | to_return.intensity[effect_name] = self.intensity[effect_name] | 115 | to_return.intensity[effect_name] = self.intensity[effect_name] | ||
116 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | 116 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | ||
117 | for effect in other.effects.values(): | 117 | for effect in other.effects.values(): | ||
118 | if effect not in to_return.effects.values(): | 118 | if effect not in to_return.effects.values(): | ||
119 | raise TypeError("Error") | 119 | raise TypeError("Error") | ||
120 | for effect_name, effect in other.effects.items(): | 120 | for effect_name, effect in other.effects.items(): | ||
121 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | 121 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | ||
122 | to_return.intensity[effect_name] -= other.intensity[effect_name] | 122 | to_return.intensity[effect_name] -= other.intensity[effect_name] | ||
123 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | 123 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
124 | else: | 124 | else: | ||
125 | delattr(to_return, effect_name) | 125 | delattr(to_return, effect_name) | ||
126 | del to_return.effects[effect_name] | 126 | del to_return.effects[effect_name] | ||
127 | del to_return.intensity[effect_name] | 127 | del to_return.intensity[effect_name] | ||
128 | for effect_name in self.effects: | 128 | for effect_name in self.effects: | ||
129 | setattr(self, effect_name, self.already_used) | 129 | setattr(self, effect_name, self.already_used) | ||
130 | for effect_name in other.effects: | 130 | for effect_name in other.effects: | ||
131 | setattr(other, effect_name, other.already_used) | 131 | setattr(other, effect_name, other.already_used) | ||
132 | self.was_used = other.was_used = True | 132 | self.was_used = other.was_used = True | ||
133 | return to_return | 133 | return to_return | ||
134 | 134 | ||||
135 | def __truediv__(self, value): | 135 | def __truediv__(self, value): | ||
136 | if self.is_depleted(): | 136 | if self.is_depleted(): | ||
137 | raise TypeError("Potion is depleted.") | 137 | raise TypeError("Potion is depleted.") | ||
138 | if self.was_used == True: | 138 | if self.was_used == True: | ||
139 | raise TypeError("Potion is now part of something bigger than itself.") | 139 | raise TypeError("Potion is now part of something bigger than itself.") | ||
140 | copy=Potion(self.effects,self.duration) | 140 | copy=Potion(self.effects,self.duration) | ||
141 | for effect_name in self.intensity: | 141 | for effect_name in self.intensity: | ||
142 | copy.intensity[effect_name] = self.intensity[effect_name] | 142 | copy.intensity[effect_name] = self.intensity[effect_name] | ||
143 | for effect_name,effect in copy.effects.items(): | 143 | for effect_name,effect in copy.effects.items(): | ||
144 | copy.intensity[effect_name] /= value | 144 | copy.intensity[effect_name] /= value | ||
145 | self.round_intensity(copy,effect_name) | 145 | self.round_intensity(copy,effect_name) | ||
146 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | 146 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | ||
147 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | 147 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
148 | potion_list=[] | 148 | potion_list=[] | ||
149 | for _ in range(value): | 149 | for _ in range(value): | ||
150 | potion_list.append(copy) | 150 | potion_list.append(copy) | ||
151 | for effect_name in self.effects: | 151 | for effect_name in self.effects: | ||
152 | setattr(self, effect_name, self.already_used) | 152 | setattr(self, effect_name, self.already_used) | ||
153 | self.was_used = True | 153 | self.was_used = True | ||
154 | return tuple(potion_list) | 154 | return tuple(potion_list) | ||
155 | 155 | ||||
156 | def __bool__(self,other): | 156 | def __bool__(self,other): | ||
n | 157 | n | 157 | if self.is_depleted() or other.is_depleted(): | |
158 | raise TypeError("Potion is depleted.") | ||||
159 | if self.was_used == True or other.was_used == True: | ||||
160 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
158 | for effect_name in self.effects: | 161 | for effect_name in self.effects: | ||
159 | if effect_name not in other.effects: | 162 | if effect_name not in other.effects: | ||
160 | return False | 163 | return False | ||
161 | for effect_name in self.effect: | 164 | for effect_name in self.effect: | ||
162 | if self.intensity[effect_name] != other.intensity[effect_name]: | 165 | if self.intensity[effect_name] != other.intensity[effect_name]: | ||
163 | return False | 166 | return False | ||
164 | return True | 167 | return True | ||
165 | 168 | ||||
166 | def __gt__(self,other): | 169 | def __gt__(self,other): | ||
t | t | 170 | if self.is_depleted() or other.is_depleted(): | ||
171 | raise TypeError("Potion is depleted.") | ||||
172 | if self.was_used == True or other.was_used == True: | ||||
173 | raise TypeError("Potion is now part of something bigger than itself.") | ||||
167 | sum_of_self = 0 | 174 | sum_of_self = 0 | ||
168 | for effect_name in self.intensity: | 175 | for effect_name in self.intensity: | ||
169 | sum_of_self+=self.intensity[effect_name] | 176 | sum_of_self+=self.intensity[effect_name] | ||
170 | sum_of_other = 0 | 177 | sum_of_other = 0 | ||
171 | for effect_name in other.intensity: | 178 | for effect_name in other.intensity: | ||
172 | sum_of_other += other.intensity[effect_name] | 179 | sum_of_other += other.intensity[effect_name] | ||
173 | return sum_of_self > sum_of_other | 180 | return sum_of_self > sum_of_other | ||
174 | 181 | ||||
175 | def sorting_potions(potion): | 182 | def sorting_potions(potion): | ||
176 | name = potion[0] | 183 | name = potion[0] | ||
177 | sum_of_potion_name = 0 | 184 | sum_of_potion_name = 0 | ||
178 | for letter in name: | 185 | for letter in name: | ||
179 | sum_of_potion_name += ord(letter) | 186 | sum_of_potion_name += ord(letter) | ||
180 | return sum_of_potion_name | 187 | return sum_of_potion_name | ||
181 | 188 | ||||
182 | 189 | ||||
183 | class ГоспожатаПоХимия: | 190 | class ГоспожатаПоХимия: | ||
184 | def __init__(self): | 191 | def __init__(self): | ||
185 | self.used_potions = [] | 192 | self.used_potions = [] | ||
186 | self.targets_copies = {} | 193 | self.targets_copies = {} | ||
187 | self.targets_buffed_copies = {} | 194 | self.targets_buffed_copies = {} | ||
188 | 195 | ||||
189 | def apply(self, target, potion): | 196 | def apply(self, target, potion): | ||
190 | if potion.is_depleted(): | 197 | if potion.is_depleted(): | ||
191 | raise TypeError("Potion is depleted.") | 198 | raise TypeError("Potion is depleted.") | ||
192 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | 199 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) | ||
193 | potion.effects = dict(sorted_potions) | 200 | potion.effects = dict(sorted_potions) | ||
194 | potion.was_used = True | 201 | potion.was_used = True | ||
195 | if target not in self.targets_buffed_copies.values(): | 202 | if target not in self.targets_buffed_copies.values(): | ||
196 | self.targets_copies[potion] = copy.copy(target) | 203 | self.targets_copies[potion] = copy.copy(target) | ||
197 | else: | 204 | else: | ||
198 | for potion_loop in self.used_potions: | 205 | for potion_loop in self.used_potions: | ||
199 | if self.targets_buffed_copies[potion_loop] == target: | 206 | if self.targets_buffed_copies[potion_loop] == target: | ||
200 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | 207 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | ||
201 | self.used_potions.append(potion) | 208 | self.used_potions.append(potion) | ||
202 | for effect_name in potion.effects: | 209 | for effect_name in potion.effects: | ||
203 | function = getattr(potion, effect_name) | 210 | function = getattr(potion, effect_name) | ||
204 | try: | 211 | try: | ||
205 | function(target) | 212 | function(target) | ||
206 | except TypeError: | 213 | except TypeError: | ||
207 | continue | 214 | continue | ||
208 | self.targets_buffed_copies[potion] = target | 215 | self.targets_buffed_copies[potion] = target | ||
209 | 216 | ||||
210 | def tick(self): | 217 | def tick(self): | ||
211 | for potion in self.used_potions: | 218 | for potion in self.used_potions: | ||
212 | potion.duration -= 1 | 219 | potion.duration -= 1 | ||
213 | if potion.duration == 0: | 220 | if potion.duration == 0: | ||
214 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | 221 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | ||
215 | for potion_inner in self.used_potions: | 222 | for potion_inner in self.used_potions: | ||
216 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | 223 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | ||
217 | continue | 224 | continue | ||
218 | copy = Potion(potion_inner.effects,potion_inner.duration) | 225 | copy = Potion(potion_inner.effects,potion_inner.duration) | ||
219 | for effect_name,effect in copy.effects.items(): | 226 | for effect_name,effect in copy.effects.items(): | ||
220 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | 227 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | ||
221 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | 228 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
222 | for effect_name in copy.effects: | 229 | for effect_name in copy.effects: | ||
223 | function = getattr(copy, effect_name) | 230 | function = getattr(copy, effect_name) | ||
224 | function(self.targets_buffed_copies[potion]) | 231 | function(self.targets_buffed_copies[potion]) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | import copy | 2 | import copy | ||
3 | 3 | ||||
4 | def once(func): | 4 | def once(func): | ||
5 | def wrapper(target): | 5 | def wrapper(target): | ||
6 | if wrapper.called: | 6 | if wrapper.called: | ||
7 | raise TypeError("Effect is depleted.") | 7 | raise TypeError("Effect is depleted.") | ||
8 | wrapper.called = True | 8 | wrapper.called = True | ||
9 | func(target) | 9 | func(target) | ||
10 | wrapper.called = False | 10 | wrapper.called = False | ||
11 | return wrapper | 11 | return wrapper | ||
12 | 12 | ||||
n | 13 | n | |||
14 | def calling_function_decorator(function,times): | 13 | def calling_function_decorator(function, times): | ||
15 | @once | 14 | @once | ||
16 | def decorator(target): | 15 | def decorator(target): | ||
17 | for _ in range(times): | 16 | for _ in range(times): | ||
18 | function(target) | 17 | function(target) | ||
19 | return decorator | 18 | return decorator | ||
20 | 19 | ||||
21 | class Potion: | 20 | class Potion: | ||
22 | 21 | ||||
n | n | 22 | def round_intensity(self,to_return,effect_name): | ||
23 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||||
24 | |||||
23 | def is_depleted(self): | 25 | def is_depleted(self): | ||
n | 24 | is_depleted=True | n | 26 | is_depleted = True |
25 | for effect_name,effect in self.effects.items(): | 27 | for effect_name,effect in self.effects.items(): | ||
n | 26 | function=getattr(self,effect_name) | n | 28 | function = getattr(self, effect_name) |
27 | try: | 29 | try: | ||
28 | function(None) | 30 | function(None) | ||
29 | except TypeError: | 31 | except TypeError: | ||
n | 30 | is_depleted=True | n | 32 | is_depleted = True |
31 | except AttributeError: | 33 | except AttributeError: | ||
n | 32 | is_depleted=False | n | 34 | is_depleted = False |
33 | setattr(self,effect_name,calling_function_decorator(effect,self.intensity[effect_name])) | 35 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) | ||
34 | return is_depleted | 36 | return is_depleted | ||
n | 35 | n | 37 | ||
36 | @staticmethod | 38 | @staticmethod | ||
37 | def already_used(target): | 39 | def already_used(target): | ||
38 | raise TypeError("Potion is now part of something bigger than itself.") | 40 | raise TypeError("Potion is now part of something bigger than itself.") | ||
39 | 41 | ||||
n | 40 | def __init__(self,effects,duration): | n | 42 | def __init__(self,effects, duration): |
41 | self.effects=effects | 43 | self.effects = copy.copy(effects) | ||
42 | self.was_used=False | 44 | self.was_used = False | ||
43 | self.intensity={} | 45 | self.intensity = {} | ||
44 | for effect_name in self.effects: | 46 | for effect_name in self.effects: | ||
n | 45 | self.intensity[effect_name]=1 | n | 47 | self.intensity[effect_name] = 1 |
46 | for effect_name,effect in effects.items(): | 48 | for effect_name,effect in effects.items(): | ||
n | 47 | setattr(self,effect_name,calling_function_decorator(effect,self.intensity[effect_name])) | n | 49 | setattr(self, effect_name, calling_function_decorator(effect, self.intensity[effect_name])) |
48 | self.effects[effect_name]=effect | 50 | self.effects[effect_name] = effect | ||
49 | self.duration=duration | 51 | self.duration = duration | ||
50 | |||||
51 | |||||
52 | 52 | ||||
53 | def __add__(self, other): | 53 | def __add__(self, other): | ||
54 | if self.is_depleted(): | 54 | if self.is_depleted(): | ||
55 | raise TypeError("Potion is depleted.") | 55 | raise TypeError("Potion is depleted.") | ||
56 | if self.was_used == True or other.was_used == True: | 56 | if self.was_used == True or other.was_used == True: | ||
57 | raise TypeError("Potion is now part of something bigger than itself.") | 57 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 58 | to_return = Potion(self.effects,max(self.duration,other.duration)) | n | 58 | to_return = Potion(self.effects, max(self.duration, other.duration)) |
59 | for effect_name,effect in to_return.effects.items(): | 59 | for effect_name,effect in to_return.effects.items(): | ||
60 | to_return.intensity[effect_name]=self.intensity[effect_name] | 60 | to_return.intensity[effect_name]=self.intensity[effect_name] | ||
n | 61 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | n | 61 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) |
62 | for effect_name,effect in other.effects.items(): | 62 | for effect_name,effect in other.effects.items(): | ||
63 | if effect_name in to_return.effects: | 63 | if effect_name in to_return.effects: | ||
n | 64 | to_return.intensity[effect_name]+=1 | n | 64 | to_return.intensity[effect_name] += 1 |
65 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | 65 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
66 | else: | 66 | else: | ||
n | 67 | to_return.intensity[effect_name]=1 | n | 67 | to_return.intensity[effect_name] = 1 |
68 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | 68 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) | ||
69 | to_return.effects[effect_name]=effect | 69 | to_return.effects[effect_name] = effect | ||
70 | for effect_name in self.effects: | 70 | for effect_name in self.effects: | ||
n | 71 | setattr(self,effect_name,self.already_used) | n | 71 | setattr(self, effect_name, self.already_used) |
72 | for effect_name in other.effects: | 72 | for effect_name in other.effects: | ||
n | 73 | setattr(other,effect_name,other.already_used) | n | 73 | setattr(other, effect_name, other.already_used) |
74 | self.was_used=other.was_used=True | 74 | self.was_used = other.was_used = True | ||
75 | return to_return | 75 | return to_return | ||
76 | 76 | ||||
77 | def __mul__(self, value): | 77 | def __mul__(self, value): | ||
78 | if self.is_depleted(): | 78 | if self.is_depleted(): | ||
79 | raise TypeError("Potion is depleted.") | 79 | raise TypeError("Potion is depleted.") | ||
80 | if self.was_used == True: | 80 | if self.was_used == True: | ||
81 | raise TypeError("Potion is now part of something bigger than itself.") | 81 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 82 | if value>= 0 and value <= 1: | n | 82 | if value >= 0 and value <= 1: |
83 | to_return = Potion(self.effects,self.duration) | 83 | to_return = Potion(self.effects, self.duration) | ||
84 | for effect_name in to_return.effects: | 84 | for effect_name in to_return.effects: | ||
n | 85 | to_return.intensity[effect_name]=self.intensity[effect_name] | n | 85 | to_return.intensity[effect_name] = self.intensity[effect_name] |
86 | for effect_name in to_return.effects: | 86 | for effect_name in to_return.effects: | ||
87 | to_return.intensity[effect_name] *= value | 87 | to_return.intensity[effect_name] *= value | ||
n | n | 88 | self.round_intensity(to_return,effect_name) | ||
88 | to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name]<=0.5 else math.ceil(to_return.intensity[effect_name]) | 89 | # to_return.intensity[effect_name] = math.floor(to_return.intensity[effect_name]) if to_return.intensity[effect_name] <= 0.5 else math.ceil(to_return.intensity[effect_name]) | ||
89 | for effect_name,effect in to_return.effects.items(): | 90 | for effect_name,effect in to_return.effects.items(): | ||
n | 90 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | n | 91 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) |
91 | for effect_name in self.effects: | 92 | for effect_name in self.effects: | ||
n | 92 | setattr(self,effect_name,self.already_used) | n | 93 | setattr(self, effect_name, self.already_used) |
93 | self.was_used=True | 94 | self.was_used = True | ||
94 | return to_return | 95 | return to_return | ||
n | 95 | n | |||
96 | to_return = Potion(self.effects,self.duration) | 96 | to_return = Potion(self.effects, self.duration) | ||
97 | for effect_name in to_return.effects: | 97 | for effect_name in to_return.effects: | ||
n | 98 | to_return.intensity[effect_name]=self.intensity[effect_name] | n | 98 | to_return.intensity[effect_name] = self.intensity[effect_name] |
99 | for effect_name in to_return.effects: | 99 | for effect_name in to_return.effects: | ||
100 | to_return.intensity[effect_name] *= value | 100 | to_return.intensity[effect_name] *= value | ||
101 | for effect_name,effect in to_return.effects.items(): | 101 | for effect_name,effect in to_return.effects.items(): | ||
n | 102 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | n | 102 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) |
103 | for effect_name in self.effects: | 103 | for effect_name in self.effects: | ||
n | 104 | setattr(self,effect_name,self.already_used) | n | 104 | setattr(self, effect_name, self.already_used) |
105 | self.was_used=True | 105 | self.was_used = True | ||
106 | return to_return | 106 | return to_return | ||
107 | 107 | ||||
108 | def __sub__(self, other): | 108 | def __sub__(self, other): | ||
109 | if self.is_depleted(): | 109 | if self.is_depleted(): | ||
110 | raise TypeError("Potion is depleted.") | 110 | raise TypeError("Potion is depleted.") | ||
111 | if self.was_used == True or other.was_used == True: | 111 | if self.was_used == True or other.was_used == True: | ||
112 | raise TypeError("Potion is now part of something bigger than itself.") | 112 | raise TypeError("Potion is now part of something bigger than itself.") | ||
n | 113 | to_return = Potion(self.effects,self.duration) | n | 113 | to_return = Potion(self.effects, self.duration) |
114 | for effect_name,effect in to_return.effects.items(): | 114 | for effect_name,effect in to_return.effects.items(): | ||
n | 115 | to_return.intensity[effect_name]=self.intensity[effect_name] | n | 115 | to_return.intensity[effect_name] = self.intensity[effect_name] |
116 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | 116 | setattr(to_return, effect_name, calling_function_decorator(effect,to_return.intensity[effect_name])) | ||
117 | for effect in other.effects.values(): | 117 | for effect in other.effects.values(): | ||
118 | if effect not in to_return.effects.values(): | 118 | if effect not in to_return.effects.values(): | ||
119 | raise TypeError("Error") | 119 | raise TypeError("Error") | ||
120 | for effect_name, effect in other.effects.items(): | 120 | for effect_name, effect in other.effects.items(): | ||
121 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | 121 | if to_return.intensity[effect_name] > other.intensity[effect_name]: | ||
122 | to_return.intensity[effect_name] -= other.intensity[effect_name] | 122 | to_return.intensity[effect_name] -= other.intensity[effect_name] | ||
n | 123 | setattr(to_return,effect_name,calling_function_decorator(effect,to_return.intensity[effect_name])) | n | 123 | setattr(to_return, effect_name, calling_function_decorator(effect, to_return.intensity[effect_name])) |
124 | else: | 124 | else: | ||
125 | delattr(to_return, effect_name) | 125 | delattr(to_return, effect_name) | ||
126 | del to_return.effects[effect_name] | 126 | del to_return.effects[effect_name] | ||
127 | del to_return.intensity[effect_name] | 127 | del to_return.intensity[effect_name] | ||
128 | for effect_name in self.effects: | 128 | for effect_name in self.effects: | ||
n | 129 | setattr(self,effect_name,self.already_used) | n | 129 | setattr(self, effect_name, self.already_used) |
130 | for effect_name in other.effects: | 130 | for effect_name in other.effects: | ||
n | 131 | setattr(other,effect_name,other.already_used) | n | 131 | setattr(other, effect_name, other.already_used) |
132 | self.was_used=other.was_used=True | 132 | self.was_used = other.was_used = True | ||
133 | return to_return | 133 | return to_return | ||
134 | 134 | ||||
135 | def __truediv__(self, value): | 135 | def __truediv__(self, value): | ||
136 | if self.is_depleted(): | 136 | if self.is_depleted(): | ||
137 | raise TypeError("Potion is depleted.") | 137 | raise TypeError("Potion is depleted.") | ||
138 | if self.was_used == True: | 138 | if self.was_used == True: | ||
139 | raise TypeError("Potion is now part of something bigger than itself.") | 139 | raise TypeError("Potion is now part of something bigger than itself.") | ||
140 | copy=Potion(self.effects,self.duration) | 140 | copy=Potion(self.effects,self.duration) | ||
141 | for effect_name in self.intensity: | 141 | for effect_name in self.intensity: | ||
n | 142 | copy.intensity[effect_name]=self.intensity[effect_name] | n | 142 | copy.intensity[effect_name] = self.intensity[effect_name] |
143 | for effect_name,effect in copy.effects.items(): | 143 | for effect_name,effect in copy.effects.items(): | ||
n | 144 | copy.intensity[effect_name] //= value | n | 144 | copy.intensity[effect_name] /= value |
145 | self.round_intensity(copy,effect_name) | ||||
146 | #copy.intensity[effect_name] = math.floor(copy.intensity[effect_name]) if copy.intensity[effect_name] <= 0.5 else math.ceil(copy.intensity[effect_name]) | ||||
145 | setattr(copy,effect_name,calling_function_decorator(effect,copy.intensity[effect_name])) | 147 | setattr(copy,effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||
146 | potion_list=[] | 148 | potion_list=[] | ||
147 | for _ in range(value): | 149 | for _ in range(value): | ||
148 | potion_list.append(copy) | 150 | potion_list.append(copy) | ||
149 | for effect_name in self.effects: | 151 | for effect_name in self.effects: | ||
n | 150 | setattr(self,effect_name,self.already_used) | n | 152 | setattr(self, effect_name, self.already_used) |
151 | self.was_used=True | 153 | self.was_used = True | ||
152 | return tuple(potion_list) | 154 | return tuple(potion_list) | ||
n | 153 | n | 155 | ||
154 | |||||
155 | def __bool__(self,other): | 156 | def __bool__(self,other): | ||
156 | 157 | ||||
157 | for effect_name in self.effects: | 158 | for effect_name in self.effects: | ||
158 | if effect_name not in other.effects: | 159 | if effect_name not in other.effects: | ||
159 | return False | 160 | return False | ||
160 | for effect_name in self.effect: | 161 | for effect_name in self.effect: | ||
161 | if self.intensity[effect_name] != other.intensity[effect_name]: | 162 | if self.intensity[effect_name] != other.intensity[effect_name]: | ||
162 | return False | 163 | return False | ||
163 | return True | 164 | return True | ||
164 | 165 | ||||
165 | def __gt__(self,other): | 166 | def __gt__(self,other): | ||
n | 166 | sum_of_self=0 | n | 167 | sum_of_self = 0 |
167 | for effect_name in self.intensity: | 168 | for effect_name in self.intensity: | ||
168 | sum_of_self+=self.intensity[effect_name] | 169 | sum_of_self+=self.intensity[effect_name] | ||
n | 169 | sum_of_other=0 | n | 170 | sum_of_other = 0 |
170 | for effect_name in other.intensity: | 171 | for effect_name in other.intensity: | ||
n | 171 | sum_of_other+=other.intensity[effect_name] | n | 172 | sum_of_other += other.intensity[effect_name] |
172 | return sum_of_self > sum_of_other | 173 | return sum_of_self > sum_of_other | ||
173 | 174 | ||||
174 | def sorting_potions(potion): | 175 | def sorting_potions(potion): | ||
n | 175 | name= potion[0] | n | 176 | name = potion[0] |
176 | sum_of_potion_name=0 | 177 | sum_of_potion_name = 0 | ||
177 | for letter in name: | 178 | for letter in name: | ||
n | 178 | sum_of_potion_name+=ord(letter) | n | 179 | sum_of_potion_name += ord(letter) |
179 | return sum_of_potion_name | 180 | return sum_of_potion_name | ||
n | n | 181 | |||
180 | 182 | ||||
181 | class ГоспожатаПоХимия: | 183 | class ГоспожатаПоХимия: | ||
182 | def __init__(self): | 184 | def __init__(self): | ||
n | 183 | self.used_potions=[] | n | 185 | self.used_potions = [] |
184 | self.targets_copies={} | 186 | self.targets_copies = {} | ||
185 | self.targets_buffed_copies={} | 187 | self.targets_buffed_copies = {} | ||
186 | 188 | ||||
n | 187 | def apply(self,target, potion): | n | 189 | def apply(self, target, potion): |
188 | if potion.is_depleted(): | 190 | if potion.is_depleted(): | ||
189 | raise TypeError("Potion is depleted.") | 191 | raise TypeError("Potion is depleted.") | ||
n | 190 | sorted_potions = sorted(potion.effects.items(),key=sorting_potions,reverse=True) | n | 192 | sorted_potions = sorted(potion.effects.items(), key=sorting_potions, reverse=True) |
191 | potion.effects=dict(sorted_potions) | 193 | potion.effects = dict(sorted_potions) | ||
192 | if potion in self.used_potions: | ||||
193 | raise TypeError("Potion is depleted.") | ||||
194 | potion.was_used= True | 194 | potion.was_used = True | ||
195 | if target not in self.targets_buffed_copies.values(): | ||||
195 | self.targets_copies[potion]=copy.copy(target) | 196 | self.targets_copies[potion] = copy.copy(target) | ||
197 | else: | ||||
198 | for potion_loop in self.used_potions: | ||||
199 | if self.targets_buffed_copies[potion_loop] == target: | ||||
200 | self.targets_copies[potion] = copy.copy(self.targets_copies[potion_loop]) | ||||
201 | self.used_potions.append(potion) | ||||
196 | for effect_name in potion.effects: | 202 | for effect_name in potion.effects: | ||
n | 197 | function=getattr(potion,effect_name) | n | 203 | function = getattr(potion, effect_name) |
198 | try: | 204 | try: | ||
199 | function(target) | 205 | function(target) | ||
200 | except TypeError: | 206 | except TypeError: | ||
201 | continue | 207 | continue | ||
n | 202 | self.targets_buffed_copies[potion]=target | n | 208 | self.targets_buffed_copies[potion] = target |
203 | self.used_potions.append(potion) | ||||
204 | 209 | ||||
205 | def tick(self): | 210 | def tick(self): | ||
206 | for potion in self.used_potions: | 211 | for potion in self.used_potions: | ||
t | 207 | potion.duration-=1 | t | 212 | potion.duration -= 1 |
208 | if potion.duration<=0: | 213 | if potion.duration == 0: | ||
209 | self.targets_buffed_copies[potion].__dict__=vars(self.targets_copies[potion]) | 214 | self.targets_buffed_copies[potion].__dict__ = vars(self.targets_copies[potion]) | ||
215 | for potion_inner in self.used_potions: | ||||
216 | if potion_inner == potion or potion_inner.duration <= 0 or self.targets_buffed_copies[potion] != self.targets_buffed_copies[potion_inner]: | ||||
217 | continue | ||||
218 | copy = Potion(potion_inner.effects,potion_inner.duration) | ||||
219 | for effect_name,effect in copy.effects.items(): | ||||
220 | copy.intensity[effect_name] = potion_inner.intensity[effect_name] | ||||
221 | setattr(copy, effect_name, calling_function_decorator(effect, copy.intensity[effect_name])) | ||||
222 | for effect_name in copy.effects: | ||||
223 | function = getattr(copy, effect_name) | ||||
224 | function(self.targets_buffed_copies[potion]) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|