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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|