1from queue import PriorityQueue
2
3
4def ascii_sum(sub):
5 sum = 0
6 for ele in sub:
7 sum += ord(ele)
8 return sum
9
10class Potion:
11 def __init__(self, effects, duration):
12 self.effects = dict(effects)
13 self.duration = duration
14 self.intensity = {func_name: 1 for func_name in effects.keys()}
15 self.used = False
16 self.applied = False
17
18 def __getattr__(self, func_name):
19 if self.used is True:
20 raise TypeError("Potion is now part of something bigger than itself.")
21 if self.applied is True:
22 raise TypeError("Potion is depleted.")
23 if func_name in self.effects.keys():
24 if self.intensity[func_name] != -1:
25 func = self.effects[func_name]
26 func_intensity = self.intensity[func_name]
27 def result_func(target):
28 for _ in range(0, func_intensity):
29 func(target)
30 self.intensity[func_name] = -1
31 for key in self.intensity.keys():
32 if self.intensity[key] != -1:
33 break
34 else:
35 self.applied = True
36 return result_func
37 else:
38 raise TypeError("Effect is depleted.")
39 else:
40 raise AttributeError
41
42 def __add__(self, other):
43 if self.used is True or other.used is True:
44 raise TypeError("Potion is now part of something bigger than itself.")
45 if self.applied is True:
46 raise TypeError("Potion is depleted.")
47 new_intensity = {key: val for key, val in self.intensity.items() if val > -1}
48 new_effects = {key: val for key, val in self.effects.items() if key in new_intensity.keys()}
49 for func in other.effects.keys():
50 if func not in self.effects.keys() and other.intensity[func] > -1:
51 new_effects[func] = other.effects[func]
52 new_intensity[func] = other.intensity[func]
53 elif other.intensity[func] > -1:
54 new_intensity[func] += other.intensity[func]
55 new_duration = max(self.duration, other.duration)
56 result = Potion(new_effects, new_duration)
57 result.intensity = new_intensity
58 self.used = True
59 other.used = True
60 return result
61
62
63 def __sub__(self, other):
64 if self.used is True or other.used is True:
65 raise TypeError("Potion is now part of something bigger than itself.")
66 if self.applied is True:
67 raise TypeError("Potion is depleted.")
68 for key in other.effects.keys():
69 if key not in self.effects.keys():
70 raise TypeError("Can't substract")
71 new_intensity = dict(self.intensity)
72 for key in other.effects.keys():
73 new_intensity[key] -= other.intensity[key]
74 if new_intensity[key] <= 0:
75 new_intensity.pop(key)
76 new_effects = {}
77 for key in new_intensity.keys():
78 new_effects[key] = self.effects[key]
79 result = Potion(new_effects, self.duration)
80 result.intensity = new_intensity
81 self.used = True
82 other.used = True
83 return result
84
85 def __mul__(self, other):
86 if self.used is True:
87 raise TypeError("Potion is now part of something bigger than itself.")
88 if self.applied is True:
89 raise TypeError("Potion is depleted.")
90 new_intensity = {}
91 for key in self.intensity.keys():
92 new_intensity[key] = self.intensity[key] * other
93 if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]:
94 new_intensity[key] = round(new_intensity[key] - 0.1)
95 else:
96 new_intensity[key] = round(new_intensity[key])
97 result = Potion(self.effects, self.duration)
98 result.intensity = new_intensity
99 self.used = True
100 return result
101
102 def __truediv__(self, other):
103 if self.used is True:
104 raise TypeError("Potion is now part of something bigger than itself.")
105 if self.applied is True:
106 raise TypeError("Potion is depleted.")
107 new_intensity = {}
108 for key in self.intensity.keys():
109 new_intensity[key] = self.intensity[key] / other
110 if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]:
111 new_intensity[key] = round(new_intensity[key] - 0.1)
112 else:
113 new_intensity[key] = round(new_intensity[key])
114 result = Potion(self.effects, self.duration)
115 result.intensity = new_intensity
116 self.used = True
117 return tuple([result] * other)
118
119 def __eq__(self, other):
120 if self.used is True or other.used is True:
121 raise TypeError("Potion is now part of something bigger than itself.")
122 if self.applied is True:
123 raise TypeError("Potion is depleted.")
124 return self.effects == other.effects and self.intensity == other.intensity
125
126 def __lt__(self, other):
127 if self.used is True or other.used is True:
128 raise TypeError("Potion is now part of something bigger than itself.")
129 if self.applied is True:
130 raise TypeError("Potion is depleted.")
131 if sum(self.intensity.values()) < sum(other.intensity.values()):
132 return True
133 else:
134 return False
135
136 def apply_potion(self, target):
137 effect_queue = PriorityQueue()
138 if self.used is True:
139 raise TypeError("Potion is now part of something bigger than itself.")
140 if self.applied is True:
141 raise TypeError("Potion is depleted.")
142 for key in self.effects.keys():
143 effect_queue.put(tuple([ascii_sum(key) * -1, key]))
144 while effect_queue.empty() is False:
145 elem = effect_queue.get()
146 func = self.__getattr__(elem[1])
147 func(target)
148 self.applied = True
149
150 def copy(self):
151 result = Potion(self.effects, self.duration)
152 result.intensity = dict(self.intensity)
153 return result
154
155
156class ГоспожатаПоХимия:
157
158 def __init__(self):
159 self.time = 0
160 self.potions = {}
161 self.base_dict = {}
162 self.targets = {}
163
164
165 def apply(self, target, potion):
166 if potion.used is True:
167 raise TypeError("Potion is now part of something bigger than itself.")
168 if potion.applied is True:
169 raise TypeError("Potion is depleted.")
170
171 for key in potion.intensity.keys():
172 if potion.intensity[key] == -1:
173 potion.intensity[key] = 0
174
175 if id(target) not in self.targets.keys():
176 self.targets[id(target)] = target
177 self.base_dict[id(target)] = dict(target.__dict__)
178 self.potions[id(target)]= []
179
180 if potion.duration > 0:
181 potion_copy = potion.copy()
182 self.potions[id(target)].append(([potion, self.time + potion.duration]))
183 potion_copy.apply_potion(target)
184
185
186 def tick(self):
187 self.time += 1
188 for key, value in self.potions.items():
189 flag = False
190 for potion in value:
191 if potion[1] <= self.time:
192 value.remove(potion)
193 flag = True
194 if flag == True:
195 self.targets[key].__dict__ = dict(self.base_dict[key])
196 for potion in value:
197 potion_copy = potion[0].copy()
198 potion_copy.apply_potion(self.targets[key])
.F........EEF......F
======================================================================
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)
File "/tmp/solution.py", line 22, in __getattr__
raise TypeError("Potion is depleted.")
TypeError: Potion is depleted.
======================================================================
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 22, in __getattr__
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_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 380, in test_applying_depleted_potion
with self.assertRaisesRegex(TypeError, 'Potion is depleted\.'):
AssertionError: TypeError not raised
======================================================================
FAIL: test_ticking_mutable (test.TestГоспожатаПоХимия)
Test ticking after applying a potion with mutable attributes.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 446, in test_ticking_mutable
self.assertEqual(self._target.list_attr, [1, 2, 3])
AssertionError: Lists differ: [1, 2, 3, 4] != [1, 2, 3]
First list contains 1 additional elements.
First extra element 3:
4
- [1, 2, 3, 4]
? ---
+ [1, 2, 3]
----------------------------------------------------------------------
Ran 20 tests in 0.002s
FAILED (failures=3, errors=2)
| f | 1 | from queue import PriorityQueue | f | 1 | from queue import PriorityQueue |
| 2 | 2 | ||||
| 3 | 3 | ||||
| 4 | def ascii_sum(sub): | 4 | def ascii_sum(sub): | ||
| 5 | sum = 0 | 5 | sum = 0 | ||
| 6 | for ele in sub: | 6 | for ele in sub: | ||
| 7 | sum += ord(ele) | 7 | sum += ord(ele) | ||
| 8 | return sum | 8 | return sum | ||
| 9 | 9 | ||||
| 10 | class Potion: | 10 | class Potion: | ||
| 11 | def __init__(self, effects, duration): | 11 | def __init__(self, effects, duration): | ||
| 12 | self.effects = dict(effects) | 12 | self.effects = dict(effects) | ||
| 13 | self.duration = duration | 13 | self.duration = duration | ||
| 14 | self.intensity = {func_name: 1 for func_name in effects.keys()} | 14 | self.intensity = {func_name: 1 for func_name in effects.keys()} | ||
| 15 | self.used = False | 15 | self.used = False | ||
| 16 | self.applied = False | 16 | self.applied = False | ||
| 17 | 17 | ||||
| 18 | def __getattr__(self, func_name): | 18 | def __getattr__(self, func_name): | ||
| 19 | if self.used is True: | 19 | if self.used is True: | ||
| 20 | raise TypeError("Potion is now part of something bigger than itself.") | 20 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 21 | if self.applied is True: | 21 | if self.applied is True: | ||
| 22 | raise TypeError("Potion is depleted.") | 22 | raise TypeError("Potion is depleted.") | ||
| 23 | if func_name in self.effects.keys(): | 23 | if func_name in self.effects.keys(): | ||
| 24 | if self.intensity[func_name] != -1: | 24 | if self.intensity[func_name] != -1: | ||
| 25 | func = self.effects[func_name] | 25 | func = self.effects[func_name] | ||
| 26 | func_intensity = self.intensity[func_name] | 26 | func_intensity = self.intensity[func_name] | ||
| 27 | def result_func(target): | 27 | def result_func(target): | ||
| 28 | for _ in range(0, func_intensity): | 28 | for _ in range(0, func_intensity): | ||
| 29 | func(target) | 29 | func(target) | ||
| 30 | self.intensity[func_name] = -1 | 30 | self.intensity[func_name] = -1 | ||
| 31 | for key in self.intensity.keys(): | 31 | for key in self.intensity.keys(): | ||
| 32 | if self.intensity[key] != -1: | 32 | if self.intensity[key] != -1: | ||
| 33 | break | 33 | break | ||
| 34 | else: | 34 | else: | ||
| 35 | self.applied = True | 35 | self.applied = True | ||
| 36 | return result_func | 36 | return result_func | ||
| 37 | else: | 37 | else: | ||
| 38 | raise TypeError("Effect is depleted.") | 38 | raise TypeError("Effect is depleted.") | ||
| 39 | else: | 39 | else: | ||
| 40 | raise AttributeError | 40 | raise AttributeError | ||
| 41 | 41 | ||||
| 42 | def __add__(self, other): | 42 | def __add__(self, other): | ||
| 43 | if self.used is True or other.used is True: | 43 | if self.used is True or other.used is True: | ||
| 44 | raise TypeError("Potion is now part of something bigger than itself.") | 44 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 45 | if self.applied is True: | 45 | if self.applied is True: | ||
| 46 | raise TypeError("Potion is depleted.") | 46 | raise TypeError("Potion is depleted.") | ||
| 47 | new_intensity = {key: val for key, val in self.intensity.items() if val > -1} | 47 | new_intensity = {key: val for key, val in self.intensity.items() if val > -1} | ||
| 48 | new_effects = {key: val for key, val in self.effects.items() if key in new_intensity.keys()} | 48 | new_effects = {key: val for key, val in self.effects.items() if key in new_intensity.keys()} | ||
| 49 | for func in other.effects.keys(): | 49 | for func in other.effects.keys(): | ||
| 50 | if func not in self.effects.keys() and other.intensity[func] > -1: | 50 | if func not in self.effects.keys() and other.intensity[func] > -1: | ||
| 51 | new_effects[func] = other.effects[func] | 51 | new_effects[func] = other.effects[func] | ||
| 52 | new_intensity[func] = other.intensity[func] | 52 | new_intensity[func] = other.intensity[func] | ||
| 53 | elif other.intensity[func] > -1: | 53 | elif other.intensity[func] > -1: | ||
| 54 | new_intensity[func] += other.intensity[func] | 54 | new_intensity[func] += other.intensity[func] | ||
| 55 | new_duration = max(self.duration, other.duration) | 55 | new_duration = max(self.duration, other.duration) | ||
| 56 | result = Potion(new_effects, new_duration) | 56 | result = Potion(new_effects, new_duration) | ||
| 57 | result.intensity = new_intensity | 57 | result.intensity = new_intensity | ||
| 58 | self.used = True | 58 | self.used = True | ||
| 59 | other.used = True | 59 | other.used = True | ||
| 60 | return result | 60 | return result | ||
| 61 | 61 | ||||
| 62 | 62 | ||||
| 63 | def __sub__(self, other): | 63 | def __sub__(self, other): | ||
| 64 | if self.used is True or other.used is True: | 64 | if self.used is True or other.used is True: | ||
| 65 | raise TypeError("Potion is now part of something bigger than itself.") | 65 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 66 | if self.applied is True: | 66 | if self.applied is True: | ||
| 67 | raise TypeError("Potion is depleted.") | 67 | raise TypeError("Potion is depleted.") | ||
| 68 | for key in other.effects.keys(): | 68 | for key in other.effects.keys(): | ||
| 69 | if key not in self.effects.keys(): | 69 | if key not in self.effects.keys(): | ||
| 70 | raise TypeError("Can't substract") | 70 | raise TypeError("Can't substract") | ||
| 71 | new_intensity = dict(self.intensity) | 71 | new_intensity = dict(self.intensity) | ||
| 72 | for key in other.effects.keys(): | 72 | for key in other.effects.keys(): | ||
| 73 | new_intensity[key] -= other.intensity[key] | 73 | new_intensity[key] -= other.intensity[key] | ||
| 74 | if new_intensity[key] <= 0: | 74 | if new_intensity[key] <= 0: | ||
| 75 | new_intensity.pop(key) | 75 | new_intensity.pop(key) | ||
| 76 | new_effects = {} | 76 | new_effects = {} | ||
| 77 | for key in new_intensity.keys(): | 77 | for key in new_intensity.keys(): | ||
| 78 | new_effects[key] = self.effects[key] | 78 | new_effects[key] = self.effects[key] | ||
| 79 | result = Potion(new_effects, self.duration) | 79 | result = Potion(new_effects, self.duration) | ||
| 80 | result.intensity = new_intensity | 80 | result.intensity = new_intensity | ||
| 81 | self.used = True | 81 | self.used = True | ||
| 82 | other.used = True | 82 | other.used = True | ||
| 83 | return result | 83 | return result | ||
| 84 | 84 | ||||
| 85 | def __mul__(self, other): | 85 | def __mul__(self, other): | ||
| 86 | if self.used is True: | 86 | if self.used is True: | ||
| 87 | raise TypeError("Potion is now part of something bigger than itself.") | 87 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 88 | if self.applied is True: | 88 | if self.applied is True: | ||
| 89 | raise TypeError("Potion is depleted.") | 89 | raise TypeError("Potion is depleted.") | ||
| 90 | new_intensity = {} | 90 | new_intensity = {} | ||
| 91 | for key in self.intensity.keys(): | 91 | for key in self.intensity.keys(): | ||
| 92 | new_intensity[key] = self.intensity[key] * other | 92 | new_intensity[key] = self.intensity[key] * other | ||
| 93 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | 93 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | ||
| 94 | new_intensity[key] = round(new_intensity[key] - 0.1) | 94 | new_intensity[key] = round(new_intensity[key] - 0.1) | ||
| 95 | else: | 95 | else: | ||
| 96 | new_intensity[key] = round(new_intensity[key]) | 96 | new_intensity[key] = round(new_intensity[key]) | ||
| 97 | result = Potion(self.effects, self.duration) | 97 | result = Potion(self.effects, self.duration) | ||
| 98 | result.intensity = new_intensity | 98 | result.intensity = new_intensity | ||
| 99 | self.used = True | 99 | self.used = True | ||
| 100 | return result | 100 | return result | ||
| 101 | 101 | ||||
| 102 | def __truediv__(self, other): | 102 | def __truediv__(self, other): | ||
| 103 | if self.used is True: | 103 | if self.used is True: | ||
| 104 | raise TypeError("Potion is now part of something bigger than itself.") | 104 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 105 | if self.applied is True: | 105 | if self.applied is True: | ||
| 106 | raise TypeError("Potion is depleted.") | 106 | raise TypeError("Potion is depleted.") | ||
| 107 | new_intensity = {} | 107 | new_intensity = {} | ||
| 108 | for key in self.intensity.keys(): | 108 | for key in self.intensity.keys(): | ||
| 109 | new_intensity[key] = self.intensity[key] / other | 109 | new_intensity[key] = self.intensity[key] / other | ||
| 110 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | 110 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | ||
| 111 | new_intensity[key] = round(new_intensity[key] - 0.1) | 111 | new_intensity[key] = round(new_intensity[key] - 0.1) | ||
| 112 | else: | 112 | else: | ||
| 113 | new_intensity[key] = round(new_intensity[key]) | 113 | new_intensity[key] = round(new_intensity[key]) | ||
| 114 | result = Potion(self.effects, self.duration) | 114 | result = Potion(self.effects, self.duration) | ||
| 115 | result.intensity = new_intensity | 115 | result.intensity = new_intensity | ||
| 116 | self.used = True | 116 | self.used = True | ||
| 117 | return tuple([result] * other) | 117 | return tuple([result] * other) | ||
| 118 | 118 | ||||
| 119 | def __eq__(self, other): | 119 | def __eq__(self, other): | ||
| 120 | if self.used is True or other.used is True: | 120 | if self.used is True or other.used is True: | ||
| 121 | raise TypeError("Potion is now part of something bigger than itself.") | 121 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 122 | if self.applied is True: | 122 | if self.applied is True: | ||
| 123 | raise TypeError("Potion is depleted.") | 123 | raise TypeError("Potion is depleted.") | ||
| 124 | return self.effects == other.effects and self.intensity == other.intensity | 124 | return self.effects == other.effects and self.intensity == other.intensity | ||
| 125 | 125 | ||||
| 126 | def __lt__(self, other): | 126 | def __lt__(self, other): | ||
| 127 | if self.used is True or other.used is True: | 127 | if self.used is True or other.used is True: | ||
| 128 | raise TypeError("Potion is now part of something bigger than itself.") | 128 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 129 | if self.applied is True: | 129 | if self.applied is True: | ||
| 130 | raise TypeError("Potion is depleted.") | 130 | raise TypeError("Potion is depleted.") | ||
| 131 | if sum(self.intensity.values()) < sum(other.intensity.values()): | 131 | if sum(self.intensity.values()) < sum(other.intensity.values()): | ||
| 132 | return True | 132 | return True | ||
| 133 | else: | 133 | else: | ||
| 134 | return False | 134 | return False | ||
| 135 | 135 | ||||
| 136 | def apply_potion(self, target): | 136 | def apply_potion(self, target): | ||
| 137 | effect_queue = PriorityQueue() | 137 | effect_queue = PriorityQueue() | ||
| 138 | if self.used is True: | 138 | if self.used is 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 | if self.applied is True: | 140 | if self.applied is True: | ||
| 141 | raise TypeError("Potion is depleted.") | 141 | raise TypeError("Potion is depleted.") | ||
| 142 | for key in self.effects.keys(): | 142 | for key in self.effects.keys(): | ||
| 143 | effect_queue.put(tuple([ascii_sum(key) * -1, key])) | 143 | effect_queue.put(tuple([ascii_sum(key) * -1, key])) | ||
| 144 | while effect_queue.empty() is False: | 144 | while effect_queue.empty() is False: | ||
| 145 | elem = effect_queue.get() | 145 | elem = effect_queue.get() | ||
| 146 | func = self.__getattr__(elem[1]) | 146 | func = self.__getattr__(elem[1]) | ||
| 147 | func(target) | 147 | func(target) | ||
| 148 | self.applied = True | 148 | self.applied = True | ||
| 149 | 149 | ||||
| 150 | def copy(self): | 150 | def copy(self): | ||
| 151 | result = Potion(self.effects, self.duration) | 151 | result = Potion(self.effects, self.duration) | ||
| 152 | result.intensity = dict(self.intensity) | 152 | result.intensity = dict(self.intensity) | ||
| 153 | return result | 153 | return result | ||
| 154 | 154 | ||||
| 155 | 155 | ||||
| 156 | class ГоспожатаПоХимия: | 156 | class ГоспожатаПоХимия: | ||
| 157 | 157 | ||||
| 158 | def __init__(self): | 158 | def __init__(self): | ||
| 159 | self.time = 0 | 159 | self.time = 0 | ||
| 160 | self.potions = {} | 160 | self.potions = {} | ||
| 161 | self.base_dict = {} | 161 | self.base_dict = {} | ||
| 162 | self.targets = {} | 162 | self.targets = {} | ||
| 163 | 163 | ||||
| 164 | 164 | ||||
| 165 | def apply(self, target, potion): | 165 | def apply(self, target, potion): | ||
| 166 | if potion.used is True: | 166 | if potion.used is True: | ||
| 167 | raise TypeError("Potion is now part of something bigger than itself.") | 167 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 168 | if potion.applied is True: | 168 | if potion.applied is True: | ||
| 169 | raise TypeError("Potion is depleted.") | 169 | raise TypeError("Potion is depleted.") | ||
| 170 | 170 | ||||
| 171 | for key in potion.intensity.keys(): | 171 | for key in potion.intensity.keys(): | ||
| 172 | if potion.intensity[key] == -1: | 172 | if potion.intensity[key] == -1: | ||
| 173 | potion.intensity[key] = 0 | 173 | potion.intensity[key] = 0 | ||
| 174 | 174 | ||||
| 175 | if id(target) not in self.targets.keys(): | 175 | if id(target) not in self.targets.keys(): | ||
| 176 | self.targets[id(target)] = target | 176 | self.targets[id(target)] = target | ||
| 177 | self.base_dict[id(target)] = dict(target.__dict__) | 177 | self.base_dict[id(target)] = dict(target.__dict__) | ||
| 178 | self.potions[id(target)]= [] | 178 | self.potions[id(target)]= [] | ||
| 179 | 179 | ||||
| 180 | if potion.duration > 0: | 180 | if potion.duration > 0: | ||
| 181 | potion_copy = potion.copy() | 181 | potion_copy = potion.copy() | ||
| 182 | self.potions[id(target)].append(([potion, self.time + potion.duration])) | 182 | self.potions[id(target)].append(([potion, self.time + potion.duration])) | ||
| 183 | potion_copy.apply_potion(target) | 183 | potion_copy.apply_potion(target) | ||
| 184 | 184 | ||||
| 185 | 185 | ||||
| 186 | def tick(self): | 186 | def tick(self): | ||
| 187 | self.time += 1 | 187 | self.time += 1 | ||
| 188 | for key, value in self.potions.items(): | 188 | for key, value in self.potions.items(): | ||
| 189 | flag = False | 189 | flag = False | ||
| 190 | for potion in value: | 190 | for potion in value: | ||
| 191 | if potion[1] <= self.time: | 191 | if potion[1] <= self.time: | ||
| 192 | value.remove(potion) | 192 | value.remove(potion) | ||
| 193 | flag = True | 193 | flag = True | ||
| 194 | if flag == True: | 194 | if flag == True: | ||
| 195 | self.targets[key].__dict__ = dict(self.base_dict[key]) | 195 | self.targets[key].__dict__ = dict(self.base_dict[key]) | ||
| 196 | for potion in value: | 196 | for potion in value: | ||
| 197 | potion_copy = potion[0].copy() | 197 | potion_copy = potion[0].copy() | ||
| 198 | potion_copy.apply_potion(self.targets[key]) | 198 | potion_copy.apply_potion(self.targets[key]) | ||
| 199 | 199 | ||||
| 200 | 200 | ||||
| t | 201 | t | |||
| 202 | class Target: | ||||
| 203 | def __init__(self): | ||||
| 204 | self.size = 5 | ||||
| 205 | |||||
| 206 | t = Target() | ||||
| 207 | |||||
| 208 | effects = {'grow': lambda target: setattr(target, 'size', target.size*2)} | ||||
| 209 | # Име на ефекта: Функция, която прилага ефекта | ||||
| 210 | |||||
| 211 | grow_potion = Potion(effects, duration=2) | ||||
| 212 | print(grow_potion.__dict__) | ||||
| 213 | double_grow = grow_potion * 2 | ||||
| 214 | print(double_grow.__dict__) | ||||
| 215 | ГоспожатаПоХимия().apply(t, double_grow) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | from queue import PriorityQueue | f | 1 | from queue import PriorityQueue |
| 2 | 2 | ||||
| 3 | 3 | ||||
| 4 | def ascii_sum(sub): | 4 | def ascii_sum(sub): | ||
| 5 | sum = 0 | 5 | sum = 0 | ||
| 6 | for ele in sub: | 6 | for ele in sub: | ||
| n | 7 | sum += ord(ele) | n | 7 | sum += ord(ele) |
| 8 | return sum | 8 | return sum | ||
| 9 | 9 | ||||
| 10 | class Potion: | 10 | class Potion: | ||
| 11 | def __init__(self, effects, duration): | 11 | def __init__(self, effects, duration): | ||
| 12 | self.effects = dict(effects) | 12 | self.effects = dict(effects) | ||
| 13 | self.duration = duration | 13 | self.duration = duration | ||
| n | 14 | self.intensity = {func_name : 1 for func_name in effects.keys()} | n | 14 | self.intensity = {func_name: 1 for func_name in effects.keys()} |
| 15 | self.used = False | 15 | self.used = False | ||
| 16 | self.applied = False | 16 | self.applied = False | ||
| 17 | 17 | ||||
| 18 | def __getattr__(self, func_name): | 18 | def __getattr__(self, func_name): | ||
| 19 | if self.used is True: | 19 | if self.used is True: | ||
| 20 | raise TypeError("Potion is now part of something bigger than itself.") | 20 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 21 | if self.applied is True: | 21 | if self.applied is True: | ||
| 22 | raise TypeError("Potion is depleted.") | 22 | raise TypeError("Potion is depleted.") | ||
| 23 | if func_name in self.effects.keys(): | 23 | if func_name in self.effects.keys(): | ||
| 24 | if self.intensity[func_name] != -1: | 24 | if self.intensity[func_name] != -1: | ||
| 25 | func = self.effects[func_name] | 25 | func = self.effects[func_name] | ||
| 26 | func_intensity = self.intensity[func_name] | 26 | func_intensity = self.intensity[func_name] | ||
| 27 | def result_func(target): | 27 | def result_func(target): | ||
| n | 28 | for _ in range(0,func_intensity): | n | 28 | for _ in range(0, func_intensity): |
| 29 | func(target) | 29 | func(target) | ||
| 30 | self.intensity[func_name] = -1 | 30 | self.intensity[func_name] = -1 | ||
| n | 31 | flag = False | n | ||
| 32 | for key in self.intensity.keys(): | 31 | for key in self.intensity.keys(): | ||
| 33 | if self.intensity[key] != -1: | 32 | if self.intensity[key] != -1: | ||
| n | 34 | flag = True | n | 33 | break |
| 35 | if flag == False: | 34 | else: | ||
| 36 | self.applied = True | 35 | self.applied = True | ||
| 37 | return result_func | 36 | return result_func | ||
| 38 | else: | 37 | else: | ||
| 39 | raise TypeError("Effect is depleted.") | 38 | raise TypeError("Effect is depleted.") | ||
| 40 | else: | 39 | else: | ||
| 41 | raise AttributeError | 40 | raise AttributeError | ||
| 42 | 41 | ||||
| 43 | def __add__(self, other): | 42 | def __add__(self, other): | ||
| 44 | if self.used is True or other.used is True: | 43 | if self.used is True or other.used is True: | ||
| 45 | raise TypeError("Potion is now part of something bigger than itself.") | 44 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 46 | if self.applied is True: | 45 | if self.applied is True: | ||
| 47 | raise TypeError("Potion is depleted.") | 46 | raise TypeError("Potion is depleted.") | ||
| n | 48 | new_intensity = {key : val for key, val in self.intensity.items() if val > -1} | n | 47 | new_intensity = {key: val for key, val in self.intensity.items() if val > -1} |
| 49 | new_effects = {key : val for key, val in self.effects.items() if key in new_intensity.keys()} | 48 | new_effects = {key: val for key, val in self.effects.items() if key in new_intensity.keys()} | ||
| 50 | for func in other.effects.keys(): | 49 | for func in other.effects.keys(): | ||
| 51 | if func not in self.effects.keys() and other.intensity[func] > -1: | 50 | if func not in self.effects.keys() and other.intensity[func] > -1: | ||
| 52 | new_effects[func] = other.effects[func] | 51 | new_effects[func] = other.effects[func] | ||
| 53 | new_intensity[func] = other.intensity[func] | 52 | new_intensity[func] = other.intensity[func] | ||
| 54 | elif other.intensity[func] > -1: | 53 | elif other.intensity[func] > -1: | ||
| 55 | new_intensity[func] += other.intensity[func] | 54 | new_intensity[func] += other.intensity[func] | ||
| 56 | new_duration = max(self.duration, other.duration) | 55 | new_duration = max(self.duration, other.duration) | ||
| 57 | result = Potion(new_effects, new_duration) | 56 | result = Potion(new_effects, new_duration) | ||
| 58 | result.intensity = new_intensity | 57 | result.intensity = new_intensity | ||
| 59 | self.used = True | 58 | self.used = True | ||
| 60 | other.used = True | 59 | other.used = True | ||
| 61 | return result | 60 | return result | ||
| 62 | 61 | ||||
| 63 | 62 | ||||
| 64 | def __sub__(self, other): | 63 | def __sub__(self, other): | ||
| 65 | if self.used is True or other.used is True: | 64 | if self.used is True or other.used is True: | ||
| 66 | raise TypeError("Potion is now part of something bigger than itself.") | 65 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 67 | if self.applied is True: | 66 | if self.applied is True: | ||
| 68 | raise TypeError("Potion is depleted.") | 67 | raise TypeError("Potion is depleted.") | ||
| 69 | for key in other.effects.keys(): | 68 | for key in other.effects.keys(): | ||
| 70 | if key not in self.effects.keys(): | 69 | if key not in self.effects.keys(): | ||
| n | 71 | raise TypeError | n | 70 | raise TypeError("Can't substract") |
| 72 | new_intensity = dict(self.intensity) | 71 | new_intensity = dict(self.intensity) | ||
| 73 | for key in other.effects.keys(): | 72 | for key in other.effects.keys(): | ||
| 74 | new_intensity[key] -= other.intensity[key] | 73 | new_intensity[key] -= other.intensity[key] | ||
| 75 | if new_intensity[key] <= 0: | 74 | if new_intensity[key] <= 0: | ||
| 76 | new_intensity.pop(key) | 75 | new_intensity.pop(key) | ||
| 77 | new_effects = {} | 76 | new_effects = {} | ||
| 78 | for key in new_intensity.keys(): | 77 | for key in new_intensity.keys(): | ||
| 79 | new_effects[key] = self.effects[key] | 78 | new_effects[key] = self.effects[key] | ||
| n | 80 | result = Potion(new_effects,self.duration) | n | 79 | result = Potion(new_effects, self.duration) |
| 81 | result.intensity = new_intensity | 80 | result.intensity = new_intensity | ||
| 82 | self.used = True | 81 | self.used = True | ||
| 83 | other.used = True | 82 | other.used = True | ||
| 84 | return result | 83 | return result | ||
| 85 | 84 | ||||
| 86 | def __mul__(self, other): | 85 | def __mul__(self, other): | ||
| 87 | if self.used is True: | 86 | if self.used is True: | ||
| 88 | raise TypeError("Potion is now part of something bigger than itself.") | 87 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 89 | if self.applied is True: | 88 | if self.applied is True: | ||
| 90 | raise TypeError("Potion is depleted.") | 89 | raise TypeError("Potion is depleted.") | ||
| 91 | new_intensity = {} | 90 | new_intensity = {} | ||
| 92 | for key in self.intensity.keys(): | 91 | for key in self.intensity.keys(): | ||
| 93 | new_intensity[key] = self.intensity[key] * other | 92 | new_intensity[key] = self.intensity[key] * other | ||
| 94 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | 93 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | ||
| 95 | new_intensity[key] = round(new_intensity[key] - 0.1) | 94 | new_intensity[key] = round(new_intensity[key] - 0.1) | ||
| 96 | else: | 95 | else: | ||
| 97 | new_intensity[key] = round(new_intensity[key]) | 96 | new_intensity[key] = round(new_intensity[key]) | ||
| n | 98 | result = Potion(self.effects,self.duration) | n | 97 | result = Potion(self.effects, self.duration) |
| 99 | result.intensity = new_intensity | 98 | result.intensity = new_intensity | ||
| 100 | self.used = True | 99 | self.used = True | ||
| 101 | return result | 100 | return result | ||
| 102 | 101 | ||||
| 103 | def __truediv__(self, other): | 102 | def __truediv__(self, other): | ||
| 104 | if self.used is True: | 103 | if self.used is True: | ||
| 105 | raise TypeError("Potion is now part of something bigger than itself.") | 104 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 106 | if self.applied is True: | 105 | if self.applied is True: | ||
| 107 | raise TypeError("Potion is depleted.") | 106 | raise TypeError("Potion is depleted.") | ||
| 108 | new_intensity = {} | 107 | new_intensity = {} | ||
| 109 | for key in self.intensity.keys(): | 108 | for key in self.intensity.keys(): | ||
| 110 | new_intensity[key] = self.intensity[key] / other | 109 | new_intensity[key] = self.intensity[key] / other | ||
| 111 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | 110 | if new_intensity[key] % 0.5 == 0 and round(new_intensity[key]) != new_intensity[key]: | ||
| 112 | new_intensity[key] = round(new_intensity[key] - 0.1) | 111 | new_intensity[key] = round(new_intensity[key] - 0.1) | ||
| 113 | else: | 112 | else: | ||
| 114 | new_intensity[key] = round(new_intensity[key]) | 113 | new_intensity[key] = round(new_intensity[key]) | ||
| n | 115 | result = Potion(self.effects,self.duration) | n | 114 | result = Potion(self.effects, self.duration) |
| 116 | result.intensity = new_intensity | 115 | result.intensity = new_intensity | ||
| 117 | self.used = True | 116 | self.used = True | ||
| 118 | return tuple([result] * other) | 117 | return tuple([result] * other) | ||
| 119 | 118 | ||||
| 120 | def __eq__(self, other): | 119 | def __eq__(self, other): | ||
| 121 | if self.used is True or other.used is True: | 120 | if self.used is True or other.used is True: | ||
| 122 | raise TypeError("Potion is now part of something bigger than itself.") | 121 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 123 | if self.applied is True: | 122 | if self.applied is True: | ||
| 124 | raise TypeError("Potion is depleted.") | 123 | raise TypeError("Potion is depleted.") | ||
| n | 125 | if self.effects == other.effects and self.intensity == other.intensity: | n | 124 | return self.effects == other.effects and self.intensity == other.intensity |
| 126 | return True | ||||
| 127 | else: | ||||
| 128 | return False | ||||
| 129 | 125 | ||||
| 130 | def __lt__(self, other): | 126 | def __lt__(self, other): | ||
| 131 | if self.used is True or other.used is True: | 127 | if self.used is True or other.used is True: | ||
| 132 | raise TypeError("Potion is now part of something bigger than itself.") | 128 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 133 | if self.applied is True: | 129 | if self.applied is True: | ||
| 134 | raise TypeError("Potion is depleted.") | 130 | raise TypeError("Potion is depleted.") | ||
| 135 | if sum(self.intensity.values()) < sum(other.intensity.values()): | 131 | if sum(self.intensity.values()) < sum(other.intensity.values()): | ||
| 136 | return True | 132 | return True | ||
| 137 | else: | 133 | else: | ||
| 138 | return False | 134 | return False | ||
| 139 | 135 | ||||
| 140 | def apply_potion(self, target): | 136 | def apply_potion(self, target): | ||
| 141 | effect_queue = PriorityQueue() | 137 | effect_queue = PriorityQueue() | ||
| 142 | if self.used is True: | 138 | if self.used is True: | ||
| 143 | raise TypeError("Potion is now part of something bigger than itself.") | 139 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 144 | if self.applied is True: | 140 | if self.applied is True: | ||
| 145 | raise TypeError("Potion is depleted.") | 141 | raise TypeError("Potion is depleted.") | ||
| 146 | for key in self.effects.keys(): | 142 | for key in self.effects.keys(): | ||
| 147 | effect_queue.put(tuple([ascii_sum(key) * -1, key])) | 143 | effect_queue.put(tuple([ascii_sum(key) * -1, key])) | ||
| 148 | while effect_queue.empty() is False: | 144 | while effect_queue.empty() is False: | ||
| 149 | elem = effect_queue.get() | 145 | elem = effect_queue.get() | ||
| 150 | func = self.__getattr__(elem[1]) | 146 | func = self.__getattr__(elem[1]) | ||
| 151 | func(target) | 147 | func(target) | ||
| 152 | self.applied = True | 148 | self.applied = True | ||
| 153 | 149 | ||||
| 154 | def copy(self): | 150 | def copy(self): | ||
| 155 | result = Potion(self.effects, self.duration) | 151 | result = Potion(self.effects, self.duration) | ||
| 156 | result.intensity = dict(self.intensity) | 152 | result.intensity = dict(self.intensity) | ||
| 157 | return result | 153 | return result | ||
| 158 | 154 | ||||
| 159 | 155 | ||||
| 160 | class ГоспожатаПоХимия: | 156 | class ГоспожатаПоХимия: | ||
| 161 | 157 | ||||
| n | 162 | time = 0 | n | 158 | def __init__(self): |
| 159 | self.time = 0 | ||||
| 163 | potions = {} | 160 | self.potions = {} | ||
| 164 | base_dict = {} | 161 | self.base_dict = {} | ||
| 165 | targets = {} | 162 | self.targets = {} | ||
| 166 | 163 | ||||
| 167 | 164 | ||||
| n | 168 | def apply(self,target, potion): | n | 165 | def apply(self, target, potion): |
| 169 | if potion.used is True: | 166 | if potion.used is True: | ||
| 170 | raise TypeError("Potion is now part of something bigger than itself.") | 167 | raise TypeError("Potion is now part of something bigger than itself.") | ||
| 171 | if potion.applied is True: | 168 | if potion.applied is True: | ||
| 172 | raise TypeError("Potion is depleted.") | 169 | raise TypeError("Potion is depleted.") | ||
| 173 | 170 | ||||
| 174 | for key in potion.intensity.keys(): | 171 | for key in potion.intensity.keys(): | ||
| 175 | if potion.intensity[key] == -1: | 172 | if potion.intensity[key] == -1: | ||
| 176 | potion.intensity[key] = 0 | 173 | potion.intensity[key] = 0 | ||
| 177 | 174 | ||||
| n | 178 | if id(target) not in ГоспожатаПоХимия.targets.keys(): | n | 175 | if id(target) not in self.targets.keys(): |
| 179 | ГоспожатаПоХимия.targets[id(target)] = target | 176 | self.targets[id(target)] = target | ||
| 180 | ГоспожатаПоХимия.base_dict[id(target)] = dict(target.__dict__) | 177 | self.base_dict[id(target)] = dict(target.__dict__) | ||
| 181 | ГоспожатаПоХимия.potions[id(target)]= [] | 178 | self.potions[id(target)]= [] | ||
| 182 | 179 | ||||
| 183 | if potion.duration > 0: | 180 | if potion.duration > 0: | ||
| 184 | potion_copy = potion.copy() | 181 | potion_copy = potion.copy() | ||
| n | 185 | ГоспожатаПоХимия.potions[id(target)].append(([potion, ГоспожатаПоХимия.time + potion.duration])) | n | 182 | self.potions[id(target)].append(([potion, self.time + potion.duration])) |
| 186 | potion_copy.apply_potion(target) | 183 | potion_copy.apply_potion(target) | ||
| 187 | 184 | ||||
| 188 | 185 | ||||
| 189 | def tick(self): | 186 | def tick(self): | ||
| n | 190 | ГоспожатаПоХимия.time += 1 | n | 187 | self.time += 1 |
| 191 | for key, value in ГоспожатаПоХимия.potions.items(): | 188 | for key, value in self.potions.items(): | ||
| 192 | flag = False | 189 | flag = False | ||
| 193 | for potion in value: | 190 | for potion in value: | ||
| n | 194 | if potion[1] <= ГоспожатаПоХимия.time: | n | 191 | if potion[1] <= self.time: |
| 195 | value.remove(potion) | 192 | value.remove(potion) | ||
| 196 | flag = True | 193 | flag = True | ||
| 197 | if flag == True: | 194 | if flag == True: | ||
| n | 198 | ГоспожатаПоХимия.targets[key].__dict__ = dict(ГоспожатаПоХимия.base_dict[key]) | n | 195 | self.targets[key].__dict__ = dict(self.base_dict[key]) |
| 199 | for potion in value: | 196 | for potion in value: | ||
| 200 | potion_copy = potion[0].copy() | 197 | potion_copy = potion[0].copy() | ||
| t | 201 | potion_copy.apply_potion(ГоспожатаПоХимия.targets[key]) | t | 198 | potion_copy.apply_potion(self.targets[key]) |
| 199 | |||||
| 200 | |||||
| 201 | |||||
| 202 | class Target: | ||||
| 203 | def __init__(self): | ||||
| 204 | self.size = 5 | ||||
| 205 | |||||
| 206 | t = Target() | ||||
| 207 | |||||
| 208 | effects = {'grow': lambda target: setattr(target, 'size', target.size*2)} | ||||
| 209 | # Име на ефекта: Функция, която прилага ефекта | ||||
| 210 | |||||
| 211 | grow_potion = Potion(effects, duration=2) | ||||
| 212 | print(grow_potion.__dict__) | ||||
| 213 | double_grow = grow_potion * 2 | ||||
| 214 | print(double_grow.__dict__) | ||||
| 215 | ГоспожатаПоХимия().apply(t, double_grow) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||