-
Notifications
You must be signed in to change notification settings - Fork 0
/
trader.py
342 lines (278 loc) · 9.93 KB
/
trader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
""" File that holds all code that creates the different types of traders in the game."""
from __future__ import annotations
from abc import abstractmethod, ABC
from avl import AVLTree
from material import Material
from random_gen import RandomGen
__author__ = 'Shyam Kamalesh Borkar and Jobin Mathew Dan'
# Generated with https://www.namegenerator.co/real-names/english-name-generator
TRADER_NAMES = [
"Pierce Hodge",
"Loren Calhoun",
"Janie Meyers",
"Ivey Hudson",
"Rae Vincent",
"Bertie Combs",
"Brooks Mclaughlin",
"Lea Carpenter",
"Charlie Kidd",
"Emil Huffman",
"Letitia Roach",
"Roger Mathis",
"Allie Graham",
"Stanton Harrell",
"Bert Shepherd",
"Orson Hoover",
"Lyle Randall",
"Jo Gillespie",
"Audie Burnett",
"Curtis Dougherty",
"Bernard Frost",
"Jeffie Hensley",
"Rene Shea",
"Milo Chaney",
"Buck Pierce",
"Drew Flynn",
"Ruby Cameron",
"Collie Flowers",
"Waldo Morgan",
"Winston York",
"Dollie Dickson",
"Etha Morse",
"Dana Rowland",
"Eda Ryan",
"Audrey Cobb",
"Madison Fitzpatrick",
"Gardner Pearson",
"Effie Sheppard",
"Katherine Mercer",
"Dorsey Hansen",
"Taylor Blackburn",
"Mable Hodge",
"Winnie French",
"Troy Bartlett",
"Maye Cummings",
"Charley Hayes",
"Berta White",
"Ivey Mclean",
"Joanna Ford",
"Florence Cooley",
"Vivian Stephens",
"Callie Barron",
"Tina Middleton",
"Linda Glenn",
"Loren Mcdaniel",
"Ruby Goodman",
"Ray Dodson",
"Jo Bass",
"Cora Kramer",
"Taylor Schultz",
]
class Trader(ABC):
""" Abstract class for traders"""
def __init__(self, name: str) -> None:
"""
Constructor for trader
:param name: Name of the Trader
:complexity: The best and worst case complexity is O(1).
"""
self.name = name
self.inventory = AVLTree()
self.active_deal = None
self.trader_type = None
@classmethod
@abstractmethod
def random_trader(cls) -> Trader:
'''
Generate random instance of Trader
'''
pass
def set_all_materials(self, mats: list[Material]) -> None:
"""
Setting all the materials into the trader's inventory
:param mats: The list of materials that the trader would sell
:complexity: The best and worst case complexity is O(N * log(n))
where N is the number of materials and n is the size of the inventory
"""
self.inventory = AVLTree()
for material in mats:
self.add_material(material)
def add_material(self, mat: Material) -> None:
"""
Adding the material into the trader's inventory
:param mat: The material that is added to the trader's inventory
:complexity: The best and worst case complexity is O(log(n)) where
n is the number of items in the inventory (AVL tree).
"""
self.inventory[mat.mining_rate] = mat
def remove_material(self, mat: Material) -> None:
"""
Removing the known material from the traders inventory
:param mat: The material that is removed from the trader's inventory
:complexity: The best and worst case complexity is O(log(n)) where
n is the number of items in the inventory (AVL tree).
"""
del self.inventory[mat.mining_rate]
def is_currently_selling(self) -> bool:
"""
Checks if the trader is currently selling a deal
:return: Returns the state of the active deal
:complexity: The best and worst case complexity is O(1).
"""
if self.active_deal is None:
return False
else:
return True
def current_deal(self) -> tuple[Material, float]:
"""
It would be showing the current deal of the material to the player
:return: Returns the material and its price in a tuple format
:raise ValueError: When there is no active deal
:complexity: The best and worst case complexity is O(1).
"""
if self.active_deal is None:
raise ValueError()
return self.active_deal
@abstractmethod
def generate_deal(self) -> None:
"""
Generating the deal of the material
"""
pass
def generate_price(self) -> float:
"""
Generating the price of the material
:complexity: The best and worst case complexity is O(1).
"""
return round(2 + 8 * RandomGen.random_float(), 2)
def stop_deal(self) -> None:
"""
The trader stops the current deal
:complexity: The best and worst case complexity is O(1).
"""
self.active_deal = None
def __str__(self) -> str:
"""
A string representation of the trader with the current deal
:complexity: The best and worst case complexity is O(1).
:return: Returns the traders' name and what they would be selling
"""
if not self.is_currently_selling():
result = "<{}: {} not currently buying>".format(self.trader_type, self.name)
else:
material = self.active_deal[0]
price = self.active_deal[1]
result = "<{}: {} buying [{}: {}🍗/💎] for {}💰>".format(self.trader_type, self.name, material.name, material.mining_rate, price)
return result
class RandomTrader(Trader):
""" Class that represents a random trader in the game"""
def __init__(self, name: str) -> None:
"""
Constructor for random trader type
:param name: Name of the Random Trader
:complexity: The best and worst case complexity is O(1).
"""
Trader.__init__(self, name)
self.trader_type = "RandomTrader"
def generate_deal(self) -> None:
"""
Generating the deal of the material
:complexity: The best and worst case complexity is O(n) where
n is the number of items in the trader's inventory.
"""
material_list = self.inventory.range_between(0, len(self.inventory) - 1)
material = RandomGen.random_choice(material_list)
price = self.generate_price()
self.active_deal = (material, price)
@classmethod
def random_trader(cls) -> Trader:
'''
Generate random instance of Random Trader
:complexity: The best and worst case complexity is O(1).
:return: the random trader object is returned
'''
random_name = RandomGen.random_choice(TRADER_NAMES)
return RandomTrader(random_name)
class RangeTrader(Trader):
""" Class that represents a range trader in the game"""
def __init__(self, name: str) -> None:
"""
Constructor for range trader type
:param name: Name of the Range Trader
:complexity: The best and worst case complexity is O(1).
"""
Trader.__init__(self, name)
self.trader_type = "RangeTrader"
def generate_deal(self) -> None:
"""
Generating the deal of the material
:complexity: The best and worst case complexity is O(n) where
n is the number of items in the trader's inventory.
"""
i = RandomGen.randint(1, len(self.inventory))
j = RandomGen.randint(i, len(self.inventory))
material_list = self.materials_between(i - 1, j - 1) # subtract 1 from i and j as index should start from 0
material = RandomGen.random_choice(material_list)
price = self.generate_price()
self.active_deal = (material, price)
def materials_between(self, i: int, j: int) -> list[Material]:
"""
Gets the material between the materials in the traders inventory
:param i: the index of the easiest to mine in the list of materials
:param j: the index of the easiest to mine in the list of materials
:complexity: The best and worst case complexity is O(N) where N
represents the number of items in the inventory.
:return: Gets the list of materials between the index i and j
"""
return self.inventory.range_between(i, j)
@classmethod
def random_trader(cls) -> Trader:
'''
Generate random instance of range Trader
:complexity: The best and worst case complexity is O(1).
:return: the range trader object is returned
'''
random_name = RandomGen.random_choice(TRADER_NAMES)
return RangeTrader(random_name)
class HardTrader(Trader):
""" Class that represents a hard trader in the game"""
def __init__(self, name: str) -> None:
"""
Constructor for hard trader type
:param name: Name of the Hard Trader
:complexity: The best and worst case complexity is O(1).
"""
Trader.__init__(self, name)
self.trader_type = "HardTrader"
def generate_deal(self) -> None:
"""
Generating the deal of the material
:complexity: The best and worst case complexity is O(n)
where n is the size of the inventory.
"""
material_list = self.inventory.range_between(0, len(self.inventory) - 1)
material = material_list[-1]
self.remove_material(material)
price = self.generate_price()
self.active_deal = (material, price)
@classmethod
def random_trader(cls) -> Trader:
'''
Generate random instance of Hard Trader
:complexity: The best and worst case complexity is O(1).
:return: the Hard trader object is returned
'''
random_name = RandomGen.random_choice(TRADER_NAMES)
return HardTrader(random_name)
if __name__ == "__main__":
trader = RangeTrader("Jackson")
print(trader)
trader.set_materials([
Material("Coal", 4.5),
Material("Diamonds", 3),
Material("Redstone", 20),
])
trader.generate_deal()
print(trader)
trader.stop_deal()
print(trader)