1import math
2
3
4class Potion:
5 def __init__(self, effects, duration):
6 '''Тук effects_used съдържа имената на методите и интензитета на
7 всеки метод. effects_applicable съдържа boolean стойности за всеки метод
8 дали съответният метод е използваем. Накрая, used_in_reaction се използва,
9 за да се следи дали поушънката е използвана в реакция(в това влиза да е
10 apply-вана) или не.'''
11
12 self.effects = dict(effects)
13 self.duration = duration
14 self._create_effect_methods()
15 self.effects_used = {k: 1 for k in self.effects}
16 self.effects_applicable = {k: True for k in self.effects}
17 self.used_in_reaction = False
18
19 def _create_effect_methods(self):
20 for effect_name, effect_function in self.effects.items():
21 setattr(self, effect_name,
22 self._create_effect_wrapper(effect_name, effect_function))
23
24 def _create_effect_wrapper(self, effect_name, effect_func):
25 def wrapper(target):
26 if (all(value == False for value in
27 self.effects_applicable.values())):
28 raise TypeError('Potion is depleted')
29 elif not self.effects_applicable[effect_name]:
30 raise TypeError('Effect is depleted.')
31 else:
32 for intensity in range(self.effects_used[effect_name]):
33 effect_func(target)
34 self.effects_used[effect_name] -= 1
35 self.effects_applicable[effect_name] = False
36 return wrapper
37
38 def __add__(self, other):
39 if not ((all(value == False for value in self.effects_applicable.values()))
40 or
41 (all(value == False for value in other.effects_applicable.values()))):
42
43 new_pot_effects = self.effects.copy()
44 new_pot_effects_used = self.effects_used.copy()
45
46 for effect_name, effect_function in other.effects.items():
47 try:
48 new_pot_effects_used[effect_name] += other.effects_used[effect_name]
49 except KeyError:
50 new_pot_effects[effect_name] = effect_function
51 new_pot_effects_used[effect_name] = other.effects_used[effect_name]
52
53 new_pot_durat = 0
54 if self.duration >= other.duration:
55 new_pot_durat = self.duration
56 else:
57 new_pot_durat = other.duration
58 new_potion = Potion(new_pot_effects, new_pot_durat)
59 new_potion.effects_used = new_pot_effects_used
60
61 for k, v in self.effects.items():
62 delattr(self, k)
63 self.effects.clear()
64 for k, v in other.effects.items():
65 delattr(other, k)
66 for k, v in self.effects_used.items():
67 self.effects_used[k] = 0
68 self.used_in_reaction = True
69 other.used_in_reaction = True
70
71 else:
72 raise TypeError('Potion is depleted.')
73 return new_potion
74
75 def __mul__(self, num):
76 if not all(value == False for value in self.effects_applicable.values()):
77 new_potion = Potion(self.effects.copy(), self.duration)
78 new_potion.effects_used = self.effects_used.copy()
79 new_potion.effects_applicable = self.effects_applicable.copy()
80
81 for k, v in new_potion.effects_used.items():
82
83 new_potion.effects_used[k] *= num
84 shorter_length = new_potion.effects_used[k]
85 if shorter_length <= math.floor(shorter_length) + 1.5:
86 new_potion.effects_used[k] = math.floor(shorter_length)
87 else:
88 new_potion.effects_used[k] = math.ceil(shorter_length)
89
90 for k, v in self.effects.items():
91 delattr(self, k)
92 for k, v in self.effects_used.items():
93 self.effects_used[k] = 0
94 self.used_in_reaction = True
95 for k, v in self.effects_applicable.items():
96 self.effects_applicable[k] = False
97 else:
98 raise TypeError('Potion is depleted.')
99
100
101 return new_potion
102
103 def __sub__(self, other):
104 if not ((all(value == False for value in self.effects_applicable.values()))
105 or
106 (all(value == False for value in other.effects_applicable.values()))):
107
108 new_potion = Potion(self.effects.copy(), self.duration)
109 new_potion.effects_used = self.effects_used.copy()
110
111 self.used_in_reaction = True
112 other.used_in_reaction = True
113
114 for k, v in other.effects.items():
115 if k not in self.effects:
116 raise TypeError('ne izdyrjam poveche na tozi jivot')
117 else:
118 intens = new_potion.effects_used[k] - other.effects_used[k]
119 if intens <= 0:
120 new_potion.effects.pop(k)
121 delattr(new_potion, k)
122 new_potion.effects_used.pop(k)
123 else:
124 new_potion.effects_used[k] -= intens
125
126 for k, v in self.effects.items():
127 delattr(self, k)
128 self.effects.clear()
129 for k, v in self.effects_used.items():
130 self.effects_used[k] = 0
131
132 for k, v in other.effects.items():
133 delattr(other, k)
134 other.effects.clear()
135 other.effects_used.clear()
136 else:
137 raise TypeError('Potion is depleted.')
138
139 return new_potion
140
141 def __truediv__(self, number):
142 if not all(value == False for value in self.effects_applicable.values()):
143 divided_potions = []
144
145 new_pot = Potion(self.effects.copy(), self.duration)
146 new_pot.effects_used = self.effects_used.copy()
147 self.used_in_reaction = True
148
149 for k, v in new_pot.effects_used.items():
150 new_pot.effects_used[k] /= number
151 shorter_length = new_pot.effects_used[k]
152 if shorter_length <= math.floor(shorter_length) + 0.5:
153 new_pot.effects_used[k] = math.floor(shorter_length)
154 else:
155 new_pot.effects_used[k] = math.ceil(shorter_length)
156
157 for _ in range(number):
158 divided_potions.append(new_pot)
159
160 for k, v in self.effects.items():
161 delattr(self, k)
162 self.effects.clear()
163 self.effects_used.clear()
164 for k, v in self.effects_applicable.items():
165 self.effects_applicable[k] = False
166 else:
167 raise TypeError('Potion is depleted.')
168
169 return tuple(divided_potions)
170
171 def __getattr__(self, attr):
172 if self.used_in_reaction:
173 raise TypeError('Potion is now part of something bigger than itself.')
174
175 def __eq__(self, other):
176 sum_self_intens = 0
177 sum_other_intens = 0
178
179 for k, v in self.effects_used.items():
180 if k not in other.effects_used:
181 return False
182 sum_self_intens += self.effects_used[k]
183 sum_other_intens += other.effects_used[k]
184 if sum_self_intens != sum_other_intens:
185 return False
186 return True
187
188 def __lt__(self, other):
189 sum_self_intens = 0
190 sum_other_intens = 0
191 for k, v in self.effects_used.items():
192 sum_self_intens += self.effects_used[k]
193 sum_other_intens += other.effects_used[k]
194 return sum_self_intens < sum_other_intens
195
196 def __gt__(self, other):
197 sum_self_intens = 0
198 sum_other_intens = 0
199 for k, v in self.effects_used.items():
200 sum_self_intens += self.effects_used[k]
201 sum_other_intens += other.effects_used[k]
202 return sum_self_intens > sum_other_intens
203
204
205class ГоспожатаПоХимия:
206
207 def __init__(self):
208 self.is_pot_depleted = False
209 self.pot_duration = 0
210 self.target_dic = {}
211 self.object = None
212 self.objects = []
213
214 def apply(self, target, potion):
215 if potion not in self.objects:
216 self.target_dic = target.__dict__.copy()
217 new_dict = {}
218 for k, v in potion.effects.items():
219 ascii_sum = sum(ord(char) for char in k)
220 new_dict[ascii_sum] = v
221 sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True))
222 for k, v in sorted_effects.items():
223 v(target)
224
225 for k, v in potion.effects_applicable.items():
226 potion.effects_applicable[k] = False
227
228 self.is_pot_depleted = True
229 self.pot_duration = potion.duration
230 self.object = target
231 self.objects.append(potion)
232 potion.used_in_reaction = True
233
234 else:
235 raise TypeError('Potion is depleted.')
236
237 def tick(self):
238 if self.is_pot_depleted:
239 self.pot_duration -= 1
240 if self.pot_duration == 0:
241 self.object.__dict__ = self.target_dic
.F.FE...F.EEF..FFEFF
======================================================================
ERROR: test_superbness (test.TestPotionComparison)
Test superbness of potions.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 323, in test_superbness
self.assertLess(potion1, potion2)
File "/usr/lib/python3.10/unittest/case.py", line 1230, in assertLess
if not a < b:
File "/tmp/solution.py", line 193, in __lt__
sum_other_intens += other.effects_used[k]
KeyError: 'int_attr_fun'
======================================================================
ERROR: test_purification (test.TestPotionOperations)
Test purification of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 169, in test_purification
potion.int_attr_fun(self._target)
TypeError: 'NoneType' object is not callable
======================================================================
ERROR: test_separation (test.TestPotionOperations)
Test separation of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 218, in test_separation
potion2.int_attr_fun(self._target)
File "/tmp/solution.py", line 28, in wrapper
raise TypeError('Potion is depleted')
TypeError: Potion is depleted
======================================================================
ERROR: test_ticking_multiple_potions (test.TestГоспожатаПоХимия)
Test ticking after applying multiple potions which affect the same attribute.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 455, in test_ticking_multiple_potions
self._dimitrichka.apply(self._target, potion2)
File "/tmp/solution.py", line 235, in apply
raise TypeError('Potion is depleted.')
TypeError: Potion is depleted.
======================================================================
FAIL: test_depletion (test.TestBasicPotion)
Test depletion of a potion effect.
----------------------------------------------------------------------
TypeError: Potion is depleted
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/test.py", line 78, in test_depletion
with self.assertRaisesRegex(TypeError, 'Effect is depleted\.'):
AssertionError: "Effect is depleted\." does not match "Potion is depleted"
======================================================================
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 0x7fd30c1ee260> == <solution.Potion object at 0x7fd30c1ecaf0>
======================================================================
FAIL: test_dilution (test.TestPotionOperations)
Test dilution of a potion.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 127, in test_dilution
self.assertEqual(self._target.int_attr, 50)
AssertionError: 5 != 50
======================================================================
FAIL: test_applying_depleted_potion (test.TestГоспожатаПоХимия)
Test applying a depleted potion or a potion that was used in a reaction.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 391, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is now part of something bigger than itself\.'):
AssertionError: TypeError not raised
======================================================================
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_immutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with immutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 425, in test_ticking_immutable
self.assertEqual(self._target.int_attr, 500)
AssertionError: 50 != 500
======================================================================
FAIL: test_ticking_multiple_targets (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 487, in test_ticking_multiple_targets
self.assertEqual(target1.int_attr, 500)
AssertionError: 50 != 500
======================================================================
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=8, errors=4)
Георги Кунчев
05.12.2023 16:501 - не е нужно, но го следвай за следващ код;
2 - трябва двяка двойка ефекти да е с равен интензитет. Ако сумата от интензитетите е равна, но разпределена различно, трябва да връщащ `False`
|
Стелиан Витанов
05.12.2023 16:15Имам два въпроса: 1) Имам няколко реда, които надвишават допустимия лимит. Трябва ли да ги оправя? 2) Когато сравняваме две отвари дали са '==', пише, че са такива, ако съдържат едни и същи ефекти с един и същ интензитет. Това значи ли, че ще е True, ако в две отвари сборът на всички интензитети е равен, както и самите ефекти са еднакви, но интензитетите са разпределени по различен начин между ефектите?
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | 3 | ||||
4 | class Potion: | 4 | class Potion: | ||
5 | def __init__(self, effects, duration): | 5 | def __init__(self, effects, duration): | ||
6 | '''Тук effects_used съдържа имената на методите и интензитета на | 6 | '''Тук effects_used съдържа имената на методите и интензитета на | ||
7 | всеки метод. effects_applicable съдържа boolean стойности за всеки метод | 7 | всеки метод. effects_applicable съдържа boolean стойности за всеки метод | ||
8 | дали съответният метод е използваем. Накрая, used_in_reaction се използва, | 8 | дали съответният метод е използваем. Накрая, used_in_reaction се използва, | ||
9 | за да се следи дали поушънката е използвана в реакция(в това влиза да е | 9 | за да се следи дали поушънката е използвана в реакция(в това влиза да е | ||
10 | apply-вана) или не.''' | 10 | apply-вана) или не.''' | ||
11 | 11 | ||||
12 | self.effects = dict(effects) | 12 | self.effects = dict(effects) | ||
13 | self.duration = duration | 13 | self.duration = duration | ||
14 | self._create_effect_methods() | 14 | self._create_effect_methods() | ||
15 | self.effects_used = {k: 1 for k in self.effects} | 15 | self.effects_used = {k: 1 for k in self.effects} | ||
16 | self.effects_applicable = {k: True for k in self.effects} | 16 | self.effects_applicable = {k: True for k in self.effects} | ||
17 | self.used_in_reaction = False | 17 | self.used_in_reaction = False | ||
18 | 18 | ||||
19 | def _create_effect_methods(self): | 19 | def _create_effect_methods(self): | ||
20 | for effect_name, effect_function in self.effects.items(): | 20 | for effect_name, effect_function in self.effects.items(): | ||
21 | setattr(self, effect_name, | 21 | setattr(self, effect_name, | ||
22 | self._create_effect_wrapper(effect_name, effect_function)) | 22 | self._create_effect_wrapper(effect_name, effect_function)) | ||
23 | 23 | ||||
24 | def _create_effect_wrapper(self, effect_name, effect_func): | 24 | def _create_effect_wrapper(self, effect_name, effect_func): | ||
25 | def wrapper(target): | 25 | def wrapper(target): | ||
26 | if (all(value == False for value in | 26 | if (all(value == False for value in | ||
27 | self.effects_applicable.values())): | 27 | self.effects_applicable.values())): | ||
28 | raise TypeError('Potion is depleted') | 28 | raise TypeError('Potion is depleted') | ||
29 | elif not self.effects_applicable[effect_name]: | 29 | elif not self.effects_applicable[effect_name]: | ||
30 | raise TypeError('Effect is depleted.') | 30 | raise TypeError('Effect is depleted.') | ||
31 | else: | 31 | else: | ||
32 | for intensity in range(self.effects_used[effect_name]): | 32 | for intensity in range(self.effects_used[effect_name]): | ||
33 | effect_func(target) | 33 | effect_func(target) | ||
n | 34 | self.effects_used[effect_name] -= 1 | n | 34 | self.effects_used[effect_name] -= 1 |
35 | self.effects_applicable[effect_name] = False | 35 | self.effects_applicable[effect_name] = False | ||
36 | return wrapper | 36 | return wrapper | ||
37 | 37 | ||||
38 | def __add__(self, other): | 38 | def __add__(self, other): | ||
39 | if not ((all(value == False for value in self.effects_applicable.values())) | 39 | if not ((all(value == False for value in self.effects_applicable.values())) | ||
40 | or | 40 | or | ||
41 | (all(value == False for value in other.effects_applicable.values()))): | 41 | (all(value == False for value in other.effects_applicable.values()))): | ||
42 | 42 | ||||
43 | new_pot_effects = self.effects.copy() | 43 | new_pot_effects = self.effects.copy() | ||
44 | new_pot_effects_used = self.effects_used.copy() | 44 | new_pot_effects_used = self.effects_used.copy() | ||
45 | 45 | ||||
46 | for effect_name, effect_function in other.effects.items(): | 46 | for effect_name, effect_function in other.effects.items(): | ||
47 | try: | 47 | try: | ||
48 | new_pot_effects_used[effect_name] += other.effects_used[effect_name] | 48 | new_pot_effects_used[effect_name] += other.effects_used[effect_name] | ||
49 | except KeyError: | 49 | except KeyError: | ||
50 | new_pot_effects[effect_name] = effect_function | 50 | new_pot_effects[effect_name] = effect_function | ||
51 | new_pot_effects_used[effect_name] = other.effects_used[effect_name] | 51 | new_pot_effects_used[effect_name] = other.effects_used[effect_name] | ||
52 | 52 | ||||
53 | new_pot_durat = 0 | 53 | new_pot_durat = 0 | ||
54 | if self.duration >= other.duration: | 54 | if self.duration >= other.duration: | ||
55 | new_pot_durat = self.duration | 55 | new_pot_durat = self.duration | ||
56 | else: | 56 | else: | ||
57 | new_pot_durat = other.duration | 57 | new_pot_durat = other.duration | ||
58 | new_potion = Potion(new_pot_effects, new_pot_durat) | 58 | new_potion = Potion(new_pot_effects, new_pot_durat) | ||
59 | new_potion.effects_used = new_pot_effects_used | 59 | new_potion.effects_used = new_pot_effects_used | ||
60 | 60 | ||||
61 | for k, v in self.effects.items(): | 61 | for k, v in self.effects.items(): | ||
62 | delattr(self, k) | 62 | delattr(self, k) | ||
63 | self.effects.clear() | 63 | self.effects.clear() | ||
64 | for k, v in other.effects.items(): | 64 | for k, v in other.effects.items(): | ||
65 | delattr(other, k) | 65 | delattr(other, k) | ||
66 | for k, v in self.effects_used.items(): | 66 | for k, v in self.effects_used.items(): | ||
67 | self.effects_used[k] = 0 | 67 | self.effects_used[k] = 0 | ||
68 | self.used_in_reaction = True | 68 | self.used_in_reaction = True | ||
69 | other.used_in_reaction = True | 69 | other.used_in_reaction = True | ||
70 | 70 | ||||
71 | else: | 71 | else: | ||
72 | raise TypeError('Potion is depleted.') | 72 | raise TypeError('Potion is depleted.') | ||
73 | return new_potion | 73 | return new_potion | ||
74 | 74 | ||||
75 | def __mul__(self, num): | 75 | def __mul__(self, num): | ||
76 | if not all(value == False for value in self.effects_applicable.values()): | 76 | if not all(value == False for value in self.effects_applicable.values()): | ||
77 | new_potion = Potion(self.effects.copy(), self.duration) | 77 | new_potion = Potion(self.effects.copy(), self.duration) | ||
78 | new_potion.effects_used = self.effects_used.copy() | 78 | new_potion.effects_used = self.effects_used.copy() | ||
79 | new_potion.effects_applicable = self.effects_applicable.copy() | 79 | new_potion.effects_applicable = self.effects_applicable.copy() | ||
80 | 80 | ||||
81 | for k, v in new_potion.effects_used.items(): | 81 | for k, v in new_potion.effects_used.items(): | ||
82 | 82 | ||||
83 | new_potion.effects_used[k] *= num | 83 | new_potion.effects_used[k] *= num | ||
84 | shorter_length = new_potion.effects_used[k] | 84 | shorter_length = new_potion.effects_used[k] | ||
85 | if shorter_length <= math.floor(shorter_length) + 1.5: | 85 | if shorter_length <= math.floor(shorter_length) + 1.5: | ||
86 | new_potion.effects_used[k] = math.floor(shorter_length) | 86 | new_potion.effects_used[k] = math.floor(shorter_length) | ||
87 | else: | 87 | else: | ||
88 | new_potion.effects_used[k] = math.ceil(shorter_length) | 88 | new_potion.effects_used[k] = math.ceil(shorter_length) | ||
89 | 89 | ||||
90 | for k, v in self.effects.items(): | 90 | for k, v in self.effects.items(): | ||
91 | delattr(self, k) | 91 | delattr(self, k) | ||
92 | for k, v in self.effects_used.items(): | 92 | for k, v in self.effects_used.items(): | ||
93 | self.effects_used[k] = 0 | 93 | self.effects_used[k] = 0 | ||
94 | self.used_in_reaction = True | 94 | self.used_in_reaction = True | ||
95 | for k, v in self.effects_applicable.items(): | 95 | for k, v in self.effects_applicable.items(): | ||
96 | self.effects_applicable[k] = False | 96 | self.effects_applicable[k] = False | ||
97 | else: | 97 | else: | ||
98 | raise TypeError('Potion is depleted.') | 98 | raise TypeError('Potion is depleted.') | ||
99 | 99 | ||||
100 | 100 | ||||
101 | return new_potion | 101 | return new_potion | ||
102 | 102 | ||||
103 | def __sub__(self, other): | 103 | def __sub__(self, other): | ||
104 | if not ((all(value == False for value in self.effects_applicable.values())) | 104 | if not ((all(value == False for value in self.effects_applicable.values())) | ||
105 | or | 105 | or | ||
106 | (all(value == False for value in other.effects_applicable.values()))): | 106 | (all(value == False for value in other.effects_applicable.values()))): | ||
107 | 107 | ||||
108 | new_potion = Potion(self.effects.copy(), self.duration) | 108 | new_potion = Potion(self.effects.copy(), self.duration) | ||
109 | new_potion.effects_used = self.effects_used.copy() | 109 | new_potion.effects_used = self.effects_used.copy() | ||
110 | 110 | ||||
111 | self.used_in_reaction = True | 111 | self.used_in_reaction = True | ||
112 | other.used_in_reaction = True | 112 | other.used_in_reaction = True | ||
113 | 113 | ||||
114 | for k, v in other.effects.items(): | 114 | for k, v in other.effects.items(): | ||
115 | if k not in self.effects: | 115 | if k not in self.effects: | ||
116 | raise TypeError('ne izdyrjam poveche na tozi jivot') | 116 | raise TypeError('ne izdyrjam poveche na tozi jivot') | ||
117 | else: | 117 | else: | ||
118 | intens = new_potion.effects_used[k] - other.effects_used[k] | 118 | intens = new_potion.effects_used[k] - other.effects_used[k] | ||
119 | if intens <= 0: | 119 | if intens <= 0: | ||
120 | new_potion.effects.pop(k) | 120 | new_potion.effects.pop(k) | ||
121 | delattr(new_potion, k) | 121 | delattr(new_potion, k) | ||
122 | new_potion.effects_used.pop(k) | 122 | new_potion.effects_used.pop(k) | ||
123 | else: | 123 | else: | ||
124 | new_potion.effects_used[k] -= intens | 124 | new_potion.effects_used[k] -= intens | ||
125 | 125 | ||||
126 | for k, v in self.effects.items(): | 126 | for k, v in self.effects.items(): | ||
127 | delattr(self, k) | 127 | delattr(self, k) | ||
128 | self.effects.clear() | 128 | self.effects.clear() | ||
129 | for k, v in self.effects_used.items(): | 129 | for k, v in self.effects_used.items(): | ||
130 | self.effects_used[k] = 0 | 130 | self.effects_used[k] = 0 | ||
131 | 131 | ||||
132 | for k, v in other.effects.items(): | 132 | for k, v in other.effects.items(): | ||
133 | delattr(other, k) | 133 | delattr(other, k) | ||
134 | other.effects.clear() | 134 | other.effects.clear() | ||
135 | other.effects_used.clear() | 135 | other.effects_used.clear() | ||
136 | else: | 136 | else: | ||
137 | raise TypeError('Potion is depleted.') | 137 | raise TypeError('Potion is depleted.') | ||
138 | 138 | ||||
139 | return new_potion | 139 | return new_potion | ||
140 | 140 | ||||
141 | def __truediv__(self, number): | 141 | def __truediv__(self, number): | ||
142 | if not all(value == False for value in self.effects_applicable.values()): | 142 | if not all(value == False for value in self.effects_applicable.values()): | ||
143 | divided_potions = [] | 143 | divided_potions = [] | ||
144 | 144 | ||||
145 | new_pot = Potion(self.effects.copy(), self.duration) | 145 | new_pot = Potion(self.effects.copy(), self.duration) | ||
146 | new_pot.effects_used = self.effects_used.copy() | 146 | new_pot.effects_used = self.effects_used.copy() | ||
147 | self.used_in_reaction = True | 147 | self.used_in_reaction = True | ||
148 | 148 | ||||
149 | for k, v in new_pot.effects_used.items(): | 149 | for k, v in new_pot.effects_used.items(): | ||
150 | new_pot.effects_used[k] /= number | 150 | new_pot.effects_used[k] /= number | ||
151 | shorter_length = new_pot.effects_used[k] | 151 | shorter_length = new_pot.effects_used[k] | ||
152 | if shorter_length <= math.floor(shorter_length) + 0.5: | 152 | if shorter_length <= math.floor(shorter_length) + 0.5: | ||
153 | new_pot.effects_used[k] = math.floor(shorter_length) | 153 | new_pot.effects_used[k] = math.floor(shorter_length) | ||
154 | else: | 154 | else: | ||
155 | new_pot.effects_used[k] = math.ceil(shorter_length) | 155 | new_pot.effects_used[k] = math.ceil(shorter_length) | ||
156 | 156 | ||||
157 | for _ in range(number): | 157 | for _ in range(number): | ||
158 | divided_potions.append(new_pot) | 158 | divided_potions.append(new_pot) | ||
159 | 159 | ||||
160 | for k, v in self.effects.items(): | 160 | for k, v in self.effects.items(): | ||
161 | delattr(self, k) | 161 | delattr(self, k) | ||
162 | self.effects.clear() | 162 | self.effects.clear() | ||
163 | self.effects_used.clear() | 163 | self.effects_used.clear() | ||
164 | for k, v in self.effects_applicable.items(): | 164 | for k, v in self.effects_applicable.items(): | ||
165 | self.effects_applicable[k] = False | 165 | self.effects_applicable[k] = False | ||
166 | else: | 166 | else: | ||
167 | raise TypeError('Potion is depleted.') | 167 | raise TypeError('Potion is depleted.') | ||
168 | 168 | ||||
169 | return tuple(divided_potions) | 169 | return tuple(divided_potions) | ||
170 | 170 | ||||
171 | def __getattr__(self, attr): | 171 | def __getattr__(self, attr): | ||
172 | if self.used_in_reaction: | 172 | if self.used_in_reaction: | ||
173 | raise TypeError('Potion is now part of something bigger than itself.') | 173 | raise TypeError('Potion is now part of something bigger than itself.') | ||
174 | 174 | ||||
175 | def __eq__(self, other): | 175 | def __eq__(self, other): | ||
176 | sum_self_intens = 0 | 176 | sum_self_intens = 0 | ||
177 | sum_other_intens = 0 | 177 | sum_other_intens = 0 | ||
178 | 178 | ||||
179 | for k, v in self.effects_used.items(): | 179 | for k, v in self.effects_used.items(): | ||
180 | if k not in other.effects_used: | 180 | if k not in other.effects_used: | ||
181 | return False | 181 | return False | ||
182 | sum_self_intens += self.effects_used[k] | 182 | sum_self_intens += self.effects_used[k] | ||
183 | sum_other_intens += other.effects_used[k] | 183 | sum_other_intens += other.effects_used[k] | ||
t | 184 | t | |||
185 | return sum_self_intens == sum_other_intens | 184 | if sum_self_intens != sum_other_intens: | ||
185 | return False | ||||
186 | return True | ||||
186 | 187 | ||||
187 | def __lt__(self, other): | 188 | def __lt__(self, other): | ||
188 | sum_self_intens = 0 | 189 | sum_self_intens = 0 | ||
189 | sum_other_intens = 0 | 190 | sum_other_intens = 0 | ||
190 | for k, v in self.effects_used.items(): | 191 | for k, v in self.effects_used.items(): | ||
191 | sum_self_intens += self.effects_used[k] | 192 | sum_self_intens += self.effects_used[k] | ||
192 | sum_other_intens += other.effects_used[k] | 193 | sum_other_intens += other.effects_used[k] | ||
193 | return sum_self_intens < sum_other_intens | 194 | return sum_self_intens < sum_other_intens | ||
194 | 195 | ||||
195 | def __gt__(self, other): | 196 | def __gt__(self, other): | ||
196 | sum_self_intens = 0 | 197 | sum_self_intens = 0 | ||
197 | sum_other_intens = 0 | 198 | sum_other_intens = 0 | ||
198 | for k, v in self.effects_used.items(): | 199 | for k, v in self.effects_used.items(): | ||
199 | sum_self_intens += self.effects_used[k] | 200 | sum_self_intens += self.effects_used[k] | ||
200 | sum_other_intens += other.effects_used[k] | 201 | sum_other_intens += other.effects_used[k] | ||
201 | return sum_self_intens > sum_other_intens | 202 | return sum_self_intens > sum_other_intens | ||
202 | 203 | ||||
203 | 204 | ||||
204 | class ГоспожатаПоХимия: | 205 | class ГоспожатаПоХимия: | ||
205 | 206 | ||||
206 | def __init__(self): | 207 | def __init__(self): | ||
207 | self.is_pot_depleted = False | 208 | self.is_pot_depleted = False | ||
208 | self.pot_duration = 0 | 209 | self.pot_duration = 0 | ||
209 | self.target_dic = {} | 210 | self.target_dic = {} | ||
210 | self.object = None | 211 | self.object = None | ||
211 | self.objects = [] | 212 | self.objects = [] | ||
212 | 213 | ||||
213 | def apply(self, target, potion): | 214 | def apply(self, target, potion): | ||
214 | if potion not in self.objects: | 215 | if potion not in self.objects: | ||
215 | self.target_dic = target.__dict__.copy() | 216 | self.target_dic = target.__dict__.copy() | ||
216 | new_dict = {} | 217 | new_dict = {} | ||
217 | for k, v in potion.effects.items(): | 218 | for k, v in potion.effects.items(): | ||
218 | ascii_sum = sum(ord(char) for char in k) | 219 | ascii_sum = sum(ord(char) for char in k) | ||
219 | new_dict[ascii_sum] = v | 220 | new_dict[ascii_sum] = v | ||
220 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | 221 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | ||
221 | for k, v in sorted_effects.items(): | 222 | for k, v in sorted_effects.items(): | ||
222 | v(target) | 223 | v(target) | ||
223 | 224 | ||||
224 | for k, v in potion.effects_applicable.items(): | 225 | for k, v in potion.effects_applicable.items(): | ||
225 | potion.effects_applicable[k] = False | 226 | potion.effects_applicable[k] = False | ||
226 | 227 | ||||
227 | self.is_pot_depleted = True | 228 | self.is_pot_depleted = True | ||
228 | self.pot_duration = potion.duration | 229 | self.pot_duration = potion.duration | ||
229 | self.object = target | 230 | self.object = target | ||
230 | self.objects.append(potion) | 231 | self.objects.append(potion) | ||
231 | potion.used_in_reaction = True | 232 | potion.used_in_reaction = True | ||
232 | 233 | ||||
233 | else: | 234 | else: | ||
234 | raise TypeError('Potion is depleted.') | 235 | raise TypeError('Potion is depleted.') | ||
235 | 236 | ||||
236 | def tick(self): | 237 | def tick(self): | ||
237 | if self.is_pot_depleted: | 238 | if self.is_pot_depleted: | ||
238 | self.pot_duration -= 1 | 239 | self.pot_duration -= 1 | ||
239 | if self.pot_duration == 0: | 240 | if self.pot_duration == 0: | ||
240 | self.object.__dict__ = self.target_dic | 241 | self.object.__dict__ = self.target_dic |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | 3 | ||||
4 | class Potion: | 4 | class Potion: | ||
5 | def __init__(self, effects, duration): | 5 | def __init__(self, effects, duration): | ||
n | n | 6 | '''Тук effects_used съдържа имената на методите и интензитета на | ||
7 | всеки метод. effects_applicable съдържа boolean стойности за всеки метод | ||||
8 | дали съответният метод е използваем. Накрая, used_in_reaction се използва, | ||||
9 | за да се следи дали поушънката е използвана в реакция(в това влиза да е | ||||
10 | apply-вана) или не.''' | ||||
11 | |||||
6 | self.effects = dict(effects) | 12 | self.effects = dict(effects) | ||
7 | self.duration = duration | 13 | self.duration = duration | ||
8 | self._create_effect_methods() | 14 | self._create_effect_methods() | ||
n | 9 | self.effects_used = {k:2 for k in self.effects} | n | 15 | self.effects_used = {k: 1 for k in self.effects} |
10 | self.effects_applicable = {k:True for k in self.effects} | 16 | self.effects_applicable = {k: True for k in self.effects} | ||
11 | self.used_in_reaction = False | 17 | self.used_in_reaction = False | ||
12 | 18 | ||||
13 | def _create_effect_methods(self): | 19 | def _create_effect_methods(self): | ||
14 | for effect_name, effect_function in self.effects.items(): | 20 | for effect_name, effect_function in self.effects.items(): | ||
15 | setattr(self, effect_name, | 21 | setattr(self, effect_name, | ||
16 | self._create_effect_wrapper(effect_name, effect_function)) | 22 | self._create_effect_wrapper(effect_name, effect_function)) | ||
17 | 23 | ||||
18 | def _create_effect_wrapper(self, effect_name, effect_func): | 24 | def _create_effect_wrapper(self, effect_name, effect_func): | ||
19 | def wrapper(target): | 25 | def wrapper(target): | ||
20 | if (all(value == False for value in | 26 | if (all(value == False for value in | ||
21 | self.effects_applicable.values())): | 27 | self.effects_applicable.values())): | ||
22 | raise TypeError('Potion is depleted') | 28 | raise TypeError('Potion is depleted') | ||
23 | elif not self.effects_applicable[effect_name]: | 29 | elif not self.effects_applicable[effect_name]: | ||
24 | raise TypeError('Effect is depleted.') | 30 | raise TypeError('Effect is depleted.') | ||
25 | else: | 31 | else: | ||
26 | for intensity in range(self.effects_used[effect_name]): | 32 | for intensity in range(self.effects_used[effect_name]): | ||
27 | effect_func(target) | 33 | effect_func(target) | ||
n | 28 | self.effects_used[effect_name] -= 2 | n | 34 | self.effects_used[effect_name] -= 1 |
29 | self.effects_applicable[effect_name] = False | 35 | self.effects_applicable[effect_name] = False | ||
30 | return wrapper | 36 | return wrapper | ||
31 | 37 | ||||
32 | def __add__(self, other): | 38 | def __add__(self, other): | ||
n | 33 | if not self.used_in_reaction and not other.used_in_reaction: | n | 39 | if not ((all(value == False for value in self.effects_applicable.values())) |
40 | or | ||||
41 | (all(value == False for value in other.effects_applicable.values()))): | ||||
42 | |||||
34 | new_pot_effects = self.effects.copy() | 43 | new_pot_effects = self.effects.copy() | ||
35 | new_pot_effects_used = self.effects_used.copy() | 44 | new_pot_effects_used = self.effects_used.copy() | ||
n | 36 | self.used_in_reaction = True | n | 45 | |
37 | other.used_in_reaction = True | ||||
38 | for effect_name, effect_function in other.effects.items(): | 46 | for effect_name, effect_function in other.effects.items(): | ||
39 | try: | 47 | try: | ||
n | 40 | new_pot_effects_used[effect_name] += 2 | n | 48 | new_pot_effects_used[effect_name] += other.effects_used[effect_name] |
41 | except KeyError: | 49 | except KeyError: | ||
42 | new_pot_effects[effect_name] = effect_function | 50 | new_pot_effects[effect_name] = effect_function | ||
n | n | 51 | new_pot_effects_used[effect_name] = other.effects_used[effect_name] | ||
52 | |||||
43 | new_pot_durat = 1 | 53 | new_pot_durat = 0 | ||
44 | if self.duration >= other.duration: | 54 | if self.duration >= other.duration: | ||
45 | new_pot_durat = self.duration | 55 | new_pot_durat = self.duration | ||
46 | else: | 56 | else: | ||
47 | new_pot_durat = other.duration | 57 | new_pot_durat = other.duration | ||
48 | new_potion = Potion(new_pot_effects, new_pot_durat) | 58 | new_potion = Potion(new_pot_effects, new_pot_durat) | ||
49 | new_potion.effects_used = new_pot_effects_used | 59 | new_potion.effects_used = new_pot_effects_used | ||
50 | 60 | ||||
51 | for k, v in self.effects.items(): | 61 | for k, v in self.effects.items(): | ||
52 | delattr(self, k) | 62 | delattr(self, k) | ||
53 | self.effects.clear() | 63 | self.effects.clear() | ||
n | n | 64 | for k, v in other.effects.items(): | ||
65 | delattr(other, k) | ||||
54 | for k, v in self.effects_used.items(): | 66 | for k, v in self.effects_used.items(): | ||
n | 55 | self.effects_used[k] = 1 | n | 67 | self.effects_used[k] = 0 |
68 | self.used_in_reaction = True | ||||
69 | other.used_in_reaction = True | ||||
70 | |||||
56 | else: | 71 | else: | ||
57 | raise TypeError('Potion is depleted.') | 72 | raise TypeError('Potion is depleted.') | ||
58 | return new_potion | 73 | return new_potion | ||
59 | 74 | ||||
60 | def __mul__(self, num): | 75 | def __mul__(self, num): | ||
n | 61 | if not self.used_in_reaction: | n | 76 | if not all(value == False for value in self.effects_applicable.values()): |
62 | new_potion = Potion(self.effects.copy(), self.duration) | 77 | new_potion = Potion(self.effects.copy(), self.duration) | ||
63 | new_potion.effects_used = self.effects_used.copy() | 78 | new_potion.effects_used = self.effects_used.copy() | ||
64 | new_potion.effects_applicable = self.effects_applicable.copy() | 79 | new_potion.effects_applicable = self.effects_applicable.copy() | ||
n | 65 | self.used_in_reaction = True | n | 80 | |
66 | for k, v in self.effects_applicable.items(): | ||||
67 | self.effects_applicable[k] = False | ||||
68 | |||||
69 | for k, v in new_potion.effects_used.items(): | 81 | for k, v in new_potion.effects_used.items(): | ||
70 | 82 | ||||
71 | new_potion.effects_used[k] *= num | 83 | new_potion.effects_used[k] *= num | ||
72 | shorter_length = new_potion.effects_used[k] | 84 | shorter_length = new_potion.effects_used[k] | ||
73 | if shorter_length <= math.floor(shorter_length) + 1.5: | 85 | if shorter_length <= math.floor(shorter_length) + 1.5: | ||
74 | new_potion.effects_used[k] = math.floor(shorter_length) | 86 | new_potion.effects_used[k] = math.floor(shorter_length) | ||
75 | else: | 87 | else: | ||
76 | new_potion.effects_used[k] = math.ceil(shorter_length) | 88 | new_potion.effects_used[k] = math.ceil(shorter_length) | ||
77 | 89 | ||||
n | 78 | n | |||
79 | # for k, v in self.effects.items(): | 90 | for k, v in self.effects.items(): | ||
80 | # delattr(self, k) | 91 | delattr(self, k) | ||
81 | |||||
82 | for k, v in self.effects_used.items(): | 92 | for k, v in self.effects_used.items(): | ||
n | 83 | self.effects_used[k] = 1 | n | 93 | self.effects_used[k] = 0 |
94 | self.used_in_reaction = True | ||||
95 | for k, v in self.effects_applicable.items(): | ||||
96 | self.effects_applicable[k] = False | ||||
84 | else: | 97 | else: | ||
n | 85 | raise TypeError('Potion is now part of something bigger.') | n | 98 | raise TypeError('Potion is depleted.') |
86 | 99 | ||||
87 | 100 | ||||
88 | return new_potion | 101 | return new_potion | ||
89 | 102 | ||||
90 | def __sub__(self, other): | 103 | def __sub__(self, other): | ||
n | n | 104 | if not ((all(value == False for value in self.effects_applicable.values())) | ||
105 | or | ||||
106 | (all(value == False for value in other.effects_applicable.values()))): | ||||
107 | |||||
91 | new_potion = Potion(self.effects.copy(), self.duration) | 108 | new_potion = Potion(self.effects.copy(), self.duration) | ||
92 | new_potion.effects_used = self.effects_used.copy() | 109 | new_potion.effects_used = self.effects_used.copy() | ||
110 | |||||
111 | self.used_in_reaction = True | ||||
112 | other.used_in_reaction = True | ||||
113 | |||||
114 | for k, v in other.effects.items(): | ||||
115 | if k not in self.effects: | ||||
116 | raise TypeError('ne izdyrjam poveche na tozi jivot') | ||||
117 | else: | ||||
118 | intens = new_potion.effects_used[k] - other.effects_used[k] | ||||
119 | if intens <= 0: | ||||
120 | new_potion.effects.pop(k) | ||||
121 | delattr(new_potion, k) | ||||
122 | new_potion.effects_used.pop(k) | ||||
123 | else: | ||||
124 | new_potion.effects_used[k] -= intens | ||||
125 | |||||
126 | for k, v in self.effects.items(): | ||||
127 | delattr(self, k) | ||||
128 | self.effects.clear() | ||||
129 | for k, v in self.effects_used.items(): | ||||
130 | self.effects_used[k] = 0 | ||||
131 | |||||
132 | for k, v in other.effects.items(): | ||||
133 | delattr(other, k) | ||||
134 | other.effects.clear() | ||||
135 | other.effects_used.clear() | ||||
136 | else: | ||||
137 | raise TypeError('Potion is depleted.') | ||||
138 | |||||
139 | return new_potion | ||||
140 | |||||
141 | def __truediv__(self, number): | ||||
142 | if not all(value == False for value in self.effects_applicable.values()): | ||||
143 | divided_potions = [] | ||||
144 | |||||
145 | new_pot = Potion(self.effects.copy(), self.duration) | ||||
146 | new_pot.effects_used = self.effects_used.copy() | ||||
147 | self.used_in_reaction = True | ||||
148 | |||||
149 | for k, v in new_pot.effects_used.items(): | ||||
150 | new_pot.effects_used[k] /= number | ||||
151 | shorter_length = new_pot.effects_used[k] | ||||
152 | if shorter_length <= math.floor(shorter_length) + 0.5: | ||||
153 | new_pot.effects_used[k] = math.floor(shorter_length) | ||||
154 | else: | ||||
155 | new_pot.effects_used[k] = math.ceil(shorter_length) | ||||
156 | |||||
157 | for _ in range(number): | ||||
158 | divided_potions.append(new_pot) | ||||
159 | |||||
160 | for k, v in self.effects.items(): | ||||
161 | delattr(self, k) | ||||
162 | self.effects.clear() | ||||
163 | self.effects_used.clear() | ||||
164 | for k, v in self.effects_applicable.items(): | ||||
165 | self.effects_applicable[k] = False | ||||
166 | else: | ||||
167 | raise TypeError('Potion is depleted.') | ||||
93 | 168 | ||||
n | 94 | self.used_in_reaction = True | n | ||
95 | other.used_in_reaction = True | ||||
96 | |||||
97 | for k, v in other.effects.items(): | ||||
98 | if k not in self.effects: | ||||
99 | raise TypeError('ne izdyrjam poveche na tozi jivot') | ||||
100 | else: | ||||
101 | intens = new_potion.effects_used[k] - other.effects_used[k] | ||||
102 | if intens < 1: | ||||
103 | new_potion.effects.pop(k) | ||||
104 | delattr(new_potion, new_potion.k) | ||||
105 | new_potion.effects_used.pop(k) | ||||
106 | else: | ||||
107 | new_potion.effects_used[k] -= intens | ||||
108 | |||||
109 | for k, v in self.effects.items(): | ||||
110 | delattr(self, k) | ||||
111 | self.effects.clear() | ||||
112 | for k, v in self.effects_used.items(): | ||||
113 | self.effects_used[k] = 1 | ||||
114 | |||||
115 | for k, v in other.effects.items(): | ||||
116 | delattr(other, k) | ||||
117 | other.effects.clear() | ||||
118 | other.effects_used.clear() | ||||
119 | |||||
120 | return new_potion | ||||
121 | |||||
122 | def __truediv__(self, number): | ||||
123 | divided_potions = [] | ||||
124 | |||||
125 | new_pot = Potion(self.effects.copy(), self.duration) | ||||
126 | new_pot.effects_used = self.effects_used.copy() | ||||
127 | self.used_in_reaction = True | ||||
128 | |||||
129 | for k, v in new_pot.effects_used.items(): | ||||
130 | new_pot.effects_used[k] /= number | ||||
131 | shorter_length = new_pot.effects_used[k] | ||||
132 | if shorter_length <= math.floor(shorter_length) + 0.5: | ||||
133 | new_pot.effects_used[k] = math.floor(shorter_length) | ||||
134 | else: | ||||
135 | new_pot.effects_used[k] = math.ceil(shorter_length) | ||||
136 | |||||
137 | for _ in range(number): | ||||
138 | divided_potions.append(new_pot) | ||||
139 | |||||
140 | for k, v in self.effects.items(): | ||||
141 | delattr(self, k) | ||||
142 | self.effects.clear() | ||||
143 | self.effects_used.clear() | ||||
144 | |||||
145 | return divided_potions | 169 | return tuple(divided_potions) | ||
146 | 170 | ||||
147 | def __getattr__(self, attr): | 171 | def __getattr__(self, attr): | ||
148 | if self.used_in_reaction: | 172 | if self.used_in_reaction: | ||
n | 149 | raise TypeError( | n | ||
150 | 'Potion is now part of something bigger than itself.' | 173 | raise TypeError('Potion is now part of something bigger than itself.') | ||
151 | ) | ||||
152 | 174 | ||||
153 | def __eq__(self, other): | 175 | def __eq__(self, other): | ||
154 | sum_self_intens = 0 | 176 | sum_self_intens = 0 | ||
155 | sum_other_intens = 0 | 177 | sum_other_intens = 0 | ||
156 | 178 | ||||
157 | for k, v in self.effects_used.items(): | 179 | for k, v in self.effects_used.items(): | ||
158 | if k not in other.effects_used: | 180 | if k not in other.effects_used: | ||
159 | return False | 181 | return False | ||
160 | sum_self_intens += self.effects_used[k] | 182 | sum_self_intens += self.effects_used[k] | ||
161 | sum_other_intens += other.effects_used[k] | 183 | sum_other_intens += other.effects_used[k] | ||
162 | 184 | ||||
n | 163 | if sum_self_intens == sum_other_intens: | n | 185 | return sum_self_intens == sum_other_intens |
164 | return True | ||||
165 | return False | ||||
166 | 186 | ||||
167 | def __lt__(self, other): | 187 | def __lt__(self, other): | ||
168 | sum_self_intens = 0 | 188 | sum_self_intens = 0 | ||
169 | sum_other_intens = 0 | 189 | sum_other_intens = 0 | ||
170 | for k, v in self.effects_used.items(): | 190 | for k, v in self.effects_used.items(): | ||
171 | sum_self_intens += self.effects_used[k] | 191 | sum_self_intens += self.effects_used[k] | ||
172 | sum_other_intens += other.effects_used[k] | 192 | sum_other_intens += other.effects_used[k] | ||
n | 173 | if sum_self_intens < sum_other_intens: | n | 193 | return sum_self_intens < sum_other_intens |
174 | return True | 194 | |||
175 | else: | ||||
176 | return False | ||||
177 | |||||
178 | def __gt__(self, other): | 195 | def __gt__(self, other): | ||
179 | sum_self_intens = 0 | 196 | sum_self_intens = 0 | ||
180 | sum_other_intens = 0 | 197 | sum_other_intens = 0 | ||
181 | for k, v in self.effects_used.items(): | 198 | for k, v in self.effects_used.items(): | ||
182 | sum_self_intens += self.effects_used[k] | 199 | sum_self_intens += self.effects_used[k] | ||
183 | sum_other_intens += other.effects_used[k] | 200 | sum_other_intens += other.effects_used[k] | ||
n | 184 | if sum_self_intens > sum_other_intens: | n | 201 | return sum_self_intens > sum_other_intens |
185 | return True | ||||
186 | else: | ||||
187 | return False | ||||
188 | 202 | ||||
189 | 203 | ||||
190 | class ГоспожатаПоХимия: | 204 | class ГоспожатаПоХимия: | ||
191 | 205 | ||||
n | n | 206 | def __init__(self): | ||
192 | is_pot_depleted = False | 207 | self.is_pot_depleted = False | ||
193 | pot_duration = 0 | 208 | self.pot_duration = 0 | ||
194 | target_dic = {} | 209 | self.target_dic = {} | ||
195 | object = None | 210 | self.object = None | ||
196 | objects = [] | 211 | self.objects = [] | ||
197 | 212 | ||||
198 | def apply(self, target, potion): | 213 | def apply(self, target, potion): | ||
n | 199 | if potion not in ГоспожатаПоХимия.objects: | n | 214 | if potion not in self.objects: |
200 | ГоспожатаПоХимия.target_dic = target.__dict__.copy() | 215 | self.target_dic = target.__dict__.copy() | ||
201 | new_dict = {} | 216 | new_dict = {} | ||
202 | for k, v in potion.effects.items(): | 217 | for k, v in potion.effects.items(): | ||
203 | ascii_sum = sum(ord(char) for char in k) | 218 | ascii_sum = sum(ord(char) for char in k) | ||
204 | new_dict[ascii_sum] = v | 219 | new_dict[ascii_sum] = v | ||
205 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | 220 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | ||
206 | for k, v in sorted_effects.items(): | 221 | for k, v in sorted_effects.items(): | ||
207 | v(target) | 222 | v(target) | ||
n | n | 223 | |||
224 | for k, v in potion.effects_applicable.items(): | ||||
208 | potion.effects_applicable[k] = False | 225 | potion.effects_applicable[k] = False | ||
n | n | 226 | |||
209 | ГоспожатаПоХимия.is_pot_depleted = True | 227 | self.is_pot_depleted = True | ||
210 | ГоспожатаПоХимия.pot_duration = potion.duration | 228 | self.pot_duration = potion.duration | ||
211 | ГоспожатаПоХимия.object = target | 229 | self.object = target | ||
212 | ГоспожатаПоХимия.objects.append(potion) | 230 | self.objects.append(potion) | ||
213 | potion.used_in_reaction = True | 231 | potion.used_in_reaction = True | ||
214 | 232 | ||||
215 | else: | 233 | else: | ||
216 | raise TypeError('Potion is depleted.') | 234 | raise TypeError('Potion is depleted.') | ||
217 | 235 | ||||
218 | def tick(self): | 236 | def tick(self): | ||
t | 219 | if ГоспожатаПоХимия.is_pot_depleted: | t | 237 | if self.is_pot_depleted: |
220 | ГоспожатаПоХимия.pot_duration -= 1 | 238 | self.pot_duration -= 1 | ||
221 | if ГоспожатаПоХимия.pot_duration == 0: | 239 | if self.pot_duration == 0: | ||
222 | ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic | 240 | self.object.__dict__ = self.target_dic |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
t | 1 | from entities import Entity | t | ||
2 | import math | 1 | import math | ||
3 | 2 | ||||
4 | 3 | ||||
5 | class Potion: | 4 | class Potion: | ||
6 | def __init__(self, effects, duration): | 5 | def __init__(self, effects, duration): | ||
7 | self.effects = dict(effects) | 6 | self.effects = dict(effects) | ||
8 | self.duration = duration | 7 | self.duration = duration | ||
9 | self._create_effect_methods() | 8 | self._create_effect_methods() | ||
10 | self.effects_used = {k:2 for k in self.effects} | 9 | self.effects_used = {k:2 for k in self.effects} | ||
11 | self.effects_applicable = {k:True for k in self.effects} | 10 | self.effects_applicable = {k:True for k in self.effects} | ||
12 | self.used_in_reaction = False | 11 | self.used_in_reaction = False | ||
13 | 12 | ||||
14 | def _create_effect_methods(self): | 13 | def _create_effect_methods(self): | ||
15 | for effect_name, effect_function in self.effects.items(): | 14 | for effect_name, effect_function in self.effects.items(): | ||
16 | setattr(self, effect_name, | 15 | setattr(self, effect_name, | ||
17 | self._create_effect_wrapper(effect_name, effect_function)) | 16 | self._create_effect_wrapper(effect_name, effect_function)) | ||
18 | 17 | ||||
19 | def _create_effect_wrapper(self, effect_name, effect_func): | 18 | def _create_effect_wrapper(self, effect_name, effect_func): | ||
20 | def wrapper(target): | 19 | def wrapper(target): | ||
21 | if (all(value == False for value in | 20 | if (all(value == False for value in | ||
22 | self.effects_applicable.values())): | 21 | self.effects_applicable.values())): | ||
23 | raise TypeError('Potion is depleted') | 22 | raise TypeError('Potion is depleted') | ||
24 | elif not self.effects_applicable[effect_name]: | 23 | elif not self.effects_applicable[effect_name]: | ||
25 | raise TypeError('Effect is depleted.') | 24 | raise TypeError('Effect is depleted.') | ||
26 | else: | 25 | else: | ||
27 | for intensity in range(self.effects_used[effect_name]): | 26 | for intensity in range(self.effects_used[effect_name]): | ||
28 | effect_func(target) | 27 | effect_func(target) | ||
29 | self.effects_used[effect_name] -= 2 | 28 | self.effects_used[effect_name] -= 2 | ||
30 | self.effects_applicable[effect_name] = False | 29 | self.effects_applicable[effect_name] = False | ||
31 | return wrapper | 30 | return wrapper | ||
32 | 31 | ||||
33 | def __add__(self, other): | 32 | def __add__(self, other): | ||
34 | if not self.used_in_reaction and not other.used_in_reaction: | 33 | if not self.used_in_reaction and not other.used_in_reaction: | ||
35 | new_pot_effects = self.effects.copy() | 34 | new_pot_effects = self.effects.copy() | ||
36 | new_pot_effects_used = self.effects_used.copy() | 35 | new_pot_effects_used = self.effects_used.copy() | ||
37 | self.used_in_reaction = True | 36 | self.used_in_reaction = True | ||
38 | other.used_in_reaction = True | 37 | other.used_in_reaction = True | ||
39 | for effect_name, effect_function in other.effects.items(): | 38 | for effect_name, effect_function in other.effects.items(): | ||
40 | try: | 39 | try: | ||
41 | new_pot_effects_used[effect_name] += 2 | 40 | new_pot_effects_used[effect_name] += 2 | ||
42 | except KeyError: | 41 | except KeyError: | ||
43 | new_pot_effects[effect_name] = effect_function | 42 | new_pot_effects[effect_name] = effect_function | ||
44 | new_pot_durat = 1 | 43 | new_pot_durat = 1 | ||
45 | if self.duration >= other.duration: | 44 | if self.duration >= other.duration: | ||
46 | new_pot_durat = self.duration | 45 | new_pot_durat = self.duration | ||
47 | else: | 46 | else: | ||
48 | new_pot_durat = other.duration | 47 | new_pot_durat = other.duration | ||
49 | new_potion = Potion(new_pot_effects, new_pot_durat) | 48 | new_potion = Potion(new_pot_effects, new_pot_durat) | ||
50 | new_potion.effects_used = new_pot_effects_used | 49 | new_potion.effects_used = new_pot_effects_used | ||
51 | 50 | ||||
52 | for k, v in self.effects.items(): | 51 | for k, v in self.effects.items(): | ||
53 | delattr(self, k) | 52 | delattr(self, k) | ||
54 | self.effects.clear() | 53 | self.effects.clear() | ||
55 | for k, v in self.effects_used.items(): | 54 | for k, v in self.effects_used.items(): | ||
56 | self.effects_used[k] = 1 | 55 | self.effects_used[k] = 1 | ||
57 | else: | 56 | else: | ||
58 | raise TypeError('Potion is depleted.') | 57 | raise TypeError('Potion is depleted.') | ||
59 | return new_potion | 58 | return new_potion | ||
60 | 59 | ||||
61 | def __mul__(self, num): | 60 | def __mul__(self, num): | ||
62 | if not self.used_in_reaction: | 61 | if not self.used_in_reaction: | ||
63 | new_potion = Potion(self.effects.copy(), self.duration) | 62 | new_potion = Potion(self.effects.copy(), self.duration) | ||
64 | new_potion.effects_used = self.effects_used.copy() | 63 | new_potion.effects_used = self.effects_used.copy() | ||
65 | new_potion.effects_applicable = self.effects_applicable.copy() | 64 | new_potion.effects_applicable = self.effects_applicable.copy() | ||
66 | self.used_in_reaction = True | 65 | self.used_in_reaction = True | ||
67 | for k, v in self.effects_applicable.items(): | 66 | for k, v in self.effects_applicable.items(): | ||
68 | self.effects_applicable[k] = False | 67 | self.effects_applicable[k] = False | ||
69 | 68 | ||||
70 | for k, v in new_potion.effects_used.items(): | 69 | for k, v in new_potion.effects_used.items(): | ||
71 | 70 | ||||
72 | new_potion.effects_used[k] *= num | 71 | new_potion.effects_used[k] *= num | ||
73 | shorter_length = new_potion.effects_used[k] | 72 | shorter_length = new_potion.effects_used[k] | ||
74 | if shorter_length <= math.floor(shorter_length) + 1.5: | 73 | if shorter_length <= math.floor(shorter_length) + 1.5: | ||
75 | new_potion.effects_used[k] = math.floor(shorter_length) | 74 | new_potion.effects_used[k] = math.floor(shorter_length) | ||
76 | else: | 75 | else: | ||
77 | new_potion.effects_used[k] = math.ceil(shorter_length) | 76 | new_potion.effects_used[k] = math.ceil(shorter_length) | ||
78 | 77 | ||||
79 | 78 | ||||
80 | # for k, v in self.effects.items(): | 79 | # for k, v in self.effects.items(): | ||
81 | # delattr(self, k) | 80 | # delattr(self, k) | ||
82 | 81 | ||||
83 | for k, v in self.effects_used.items(): | 82 | for k, v in self.effects_used.items(): | ||
84 | self.effects_used[k] = 1 | 83 | self.effects_used[k] = 1 | ||
85 | else: | 84 | else: | ||
86 | raise TypeError('Potion is now part of something bigger.') | 85 | raise TypeError('Potion is now part of something bigger.') | ||
87 | 86 | ||||
88 | 87 | ||||
89 | return new_potion | 88 | return new_potion | ||
90 | 89 | ||||
91 | def __sub__(self, other): | 90 | def __sub__(self, other): | ||
92 | new_potion = Potion(self.effects.copy(), self.duration) | 91 | new_potion = Potion(self.effects.copy(), self.duration) | ||
93 | new_potion.effects_used = self.effects_used.copy() | 92 | new_potion.effects_used = self.effects_used.copy() | ||
94 | 93 | ||||
95 | self.used_in_reaction = True | 94 | self.used_in_reaction = True | ||
96 | other.used_in_reaction = True | 95 | other.used_in_reaction = True | ||
97 | 96 | ||||
98 | for k, v in other.effects.items(): | 97 | for k, v in other.effects.items(): | ||
99 | if k not in self.effects: | 98 | if k not in self.effects: | ||
100 | raise TypeError('ne izdyrjam poveche na tozi jivot') | 99 | raise TypeError('ne izdyrjam poveche na tozi jivot') | ||
101 | else: | 100 | else: | ||
102 | intens = new_potion.effects_used[k] - other.effects_used[k] | 101 | intens = new_potion.effects_used[k] - other.effects_used[k] | ||
103 | if intens < 1: | 102 | if intens < 1: | ||
104 | new_potion.effects.pop(k) | 103 | new_potion.effects.pop(k) | ||
105 | delattr(new_potion, new_potion.k) | 104 | delattr(new_potion, new_potion.k) | ||
106 | new_potion.effects_used.pop(k) | 105 | new_potion.effects_used.pop(k) | ||
107 | else: | 106 | else: | ||
108 | new_potion.effects_used[k] -= intens | 107 | new_potion.effects_used[k] -= intens | ||
109 | 108 | ||||
110 | for k, v in self.effects.items(): | 109 | for k, v in self.effects.items(): | ||
111 | delattr(self, k) | 110 | delattr(self, k) | ||
112 | self.effects.clear() | 111 | self.effects.clear() | ||
113 | for k, v in self.effects_used.items(): | 112 | for k, v in self.effects_used.items(): | ||
114 | self.effects_used[k] = 1 | 113 | self.effects_used[k] = 1 | ||
115 | 114 | ||||
116 | for k, v in other.effects.items(): | 115 | for k, v in other.effects.items(): | ||
117 | delattr(other, k) | 116 | delattr(other, k) | ||
118 | other.effects.clear() | 117 | other.effects.clear() | ||
119 | other.effects_used.clear() | 118 | other.effects_used.clear() | ||
120 | 119 | ||||
121 | return new_potion | 120 | return new_potion | ||
122 | 121 | ||||
123 | def __truediv__(self, number): | 122 | def __truediv__(self, number): | ||
124 | divided_potions = [] | 123 | divided_potions = [] | ||
125 | 124 | ||||
126 | new_pot = Potion(self.effects.copy(), self.duration) | 125 | new_pot = Potion(self.effects.copy(), self.duration) | ||
127 | new_pot.effects_used = self.effects_used.copy() | 126 | new_pot.effects_used = self.effects_used.copy() | ||
128 | self.used_in_reaction = True | 127 | self.used_in_reaction = True | ||
129 | 128 | ||||
130 | for k, v in new_pot.effects_used.items(): | 129 | for k, v in new_pot.effects_used.items(): | ||
131 | new_pot.effects_used[k] /= number | 130 | new_pot.effects_used[k] /= number | ||
132 | shorter_length = new_pot.effects_used[k] | 131 | shorter_length = new_pot.effects_used[k] | ||
133 | if shorter_length <= math.floor(shorter_length) + 0.5: | 132 | if shorter_length <= math.floor(shorter_length) + 0.5: | ||
134 | new_pot.effects_used[k] = math.floor(shorter_length) | 133 | new_pot.effects_used[k] = math.floor(shorter_length) | ||
135 | else: | 134 | else: | ||
136 | new_pot.effects_used[k] = math.ceil(shorter_length) | 135 | new_pot.effects_used[k] = math.ceil(shorter_length) | ||
137 | 136 | ||||
138 | for _ in range(number): | 137 | for _ in range(number): | ||
139 | divided_potions.append(new_pot) | 138 | divided_potions.append(new_pot) | ||
140 | 139 | ||||
141 | for k, v in self.effects.items(): | 140 | for k, v in self.effects.items(): | ||
142 | delattr(self, k) | 141 | delattr(self, k) | ||
143 | self.effects.clear() | 142 | self.effects.clear() | ||
144 | self.effects_used.clear() | 143 | self.effects_used.clear() | ||
145 | 144 | ||||
146 | return divided_potions | 145 | return divided_potions | ||
147 | 146 | ||||
148 | def __getattr__(self, attr): | 147 | def __getattr__(self, attr): | ||
149 | if self.used_in_reaction: | 148 | if self.used_in_reaction: | ||
150 | raise TypeError( | 149 | raise TypeError( | ||
151 | 'Potion is now part of something bigger than itself.' | 150 | 'Potion is now part of something bigger than itself.' | ||
152 | ) | 151 | ) | ||
153 | 152 | ||||
154 | def __eq__(self, other): | 153 | def __eq__(self, other): | ||
155 | sum_self_intens = 0 | 154 | sum_self_intens = 0 | ||
156 | sum_other_intens = 0 | 155 | sum_other_intens = 0 | ||
157 | 156 | ||||
158 | for k, v in self.effects_used.items(): | 157 | for k, v in self.effects_used.items(): | ||
159 | if k not in other.effects_used: | 158 | if k not in other.effects_used: | ||
160 | return False | 159 | return False | ||
161 | sum_self_intens += self.effects_used[k] | 160 | sum_self_intens += self.effects_used[k] | ||
162 | sum_other_intens += other.effects_used[k] | 161 | sum_other_intens += other.effects_used[k] | ||
163 | 162 | ||||
164 | if sum_self_intens == sum_other_intens: | 163 | if sum_self_intens == sum_other_intens: | ||
165 | return True | 164 | return True | ||
166 | return False | 165 | return False | ||
167 | 166 | ||||
168 | def __lt__(self, other): | 167 | def __lt__(self, other): | ||
169 | sum_self_intens = 0 | 168 | sum_self_intens = 0 | ||
170 | sum_other_intens = 0 | 169 | sum_other_intens = 0 | ||
171 | for k, v in self.effects_used.items(): | 170 | for k, v in self.effects_used.items(): | ||
172 | sum_self_intens += self.effects_used[k] | 171 | sum_self_intens += self.effects_used[k] | ||
173 | sum_other_intens += other.effects_used[k] | 172 | sum_other_intens += other.effects_used[k] | ||
174 | if sum_self_intens < sum_other_intens: | 173 | if sum_self_intens < sum_other_intens: | ||
175 | return True | 174 | return True | ||
176 | else: | 175 | else: | ||
177 | return False | 176 | return False | ||
178 | 177 | ||||
179 | def __gt__(self, other): | 178 | def __gt__(self, other): | ||
180 | sum_self_intens = 0 | 179 | sum_self_intens = 0 | ||
181 | sum_other_intens = 0 | 180 | sum_other_intens = 0 | ||
182 | for k, v in self.effects_used.items(): | 181 | for k, v in self.effects_used.items(): | ||
183 | sum_self_intens += self.effects_used[k] | 182 | sum_self_intens += self.effects_used[k] | ||
184 | sum_other_intens += other.effects_used[k] | 183 | sum_other_intens += other.effects_used[k] | ||
185 | if sum_self_intens > sum_other_intens: | 184 | if sum_self_intens > sum_other_intens: | ||
186 | return True | 185 | return True | ||
187 | else: | 186 | else: | ||
188 | return False | 187 | return False | ||
189 | 188 | ||||
190 | 189 | ||||
191 | class ГоспожатаПоХимия: | 190 | class ГоспожатаПоХимия: | ||
192 | 191 | ||||
193 | is_pot_depleted = False | 192 | is_pot_depleted = False | ||
194 | pot_duration = 0 | 193 | pot_duration = 0 | ||
195 | target_dic = {} | 194 | target_dic = {} | ||
196 | object = None | 195 | object = None | ||
197 | objects = [] | 196 | objects = [] | ||
198 | 197 | ||||
199 | def apply(self, target, potion): | 198 | def apply(self, target, potion): | ||
200 | if potion not in ГоспожатаПоХимия.objects: | 199 | if potion not in ГоспожатаПоХимия.objects: | ||
201 | ГоспожатаПоХимия.target_dic = target.__dict__.copy() | 200 | ГоспожатаПоХимия.target_dic = target.__dict__.copy() | ||
202 | new_dict = {} | 201 | new_dict = {} | ||
203 | for k, v in potion.effects.items(): | 202 | for k, v in potion.effects.items(): | ||
204 | ascii_sum = sum(ord(char) for char in k) | 203 | ascii_sum = sum(ord(char) for char in k) | ||
205 | new_dict[ascii_sum] = v | 204 | new_dict[ascii_sum] = v | ||
206 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | 205 | sorted_effects = dict(sorted(new_dict.items(), key=lambda x: x[0], reverse=True)) | ||
207 | for k, v in sorted_effects.items(): | 206 | for k, v in sorted_effects.items(): | ||
208 | v(target) | 207 | v(target) | ||
209 | potion.effects_applicable[k] = False | 208 | potion.effects_applicable[k] = False | ||
210 | ГоспожатаПоХимия.is_pot_depleted = True | 209 | ГоспожатаПоХимия.is_pot_depleted = True | ||
211 | ГоспожатаПоХимия.pot_duration = potion.duration | 210 | ГоспожатаПоХимия.pot_duration = potion.duration | ||
212 | ГоспожатаПоХимия.object = target | 211 | ГоспожатаПоХимия.object = target | ||
213 | ГоспожатаПоХимия.objects.append(potion) | 212 | ГоспожатаПоХимия.objects.append(potion) | ||
214 | potion.used_in_reaction = True | 213 | potion.used_in_reaction = True | ||
215 | 214 | ||||
216 | else: | 215 | else: | ||
217 | raise TypeError('Potion is depleted.') | 216 | raise TypeError('Potion is depleted.') | ||
218 | 217 | ||||
219 | def tick(self): | 218 | def tick(self): | ||
220 | if ГоспожатаПоХимия.is_pot_depleted: | 219 | if ГоспожатаПоХимия.is_pot_depleted: | ||
221 | ГоспожатаПоХимия.pot_duration -= 1 | 220 | ГоспожатаПоХимия.pot_duration -= 1 | ||
222 | if ГоспожатаПоХимия.pot_duration == 0: | 221 | if ГоспожатаПоХимия.pot_duration == 0: | ||
223 | ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic | 222 | ГоспожатаПоХимия.object.__dict__ = ГоспожатаПоХимия.target_dic |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|