Skip to content
Snippets Groups Projects
item.py 4.7 KiB
Newer Older
from game_object import GameObject
from enum import Enum
from player import Player

class ItemId(Enum):
	HONEY = (0, 'R11')
	HERBS = (1, 'R12')
	CLAY = (2, 'R13')
	MINERAL = (3, 'R14')
	POTION = (4, 'R21')
	INCENSE = (5, 'R22')
	GEMS = (6, 'R23')
	LIFE_ELIXIR = (7, 'R31')
	MANA_CRYSTAL = (8, 'R32')
	PHILOSOPHER_STONE = (9, 'R41')

	def __init__(self, index: int, idStr: str):
		assert isinstance(index, int) and isinstance(idStr, str)

		this.index = index
		this.id = idStr

class Item(GameObject):	
	"""docstring for Item"""

	def __init__(self, 
				id: int = None,
				itemId: ItemId = None,
				item: Item = None,
				count: int = None):
		if isinstance(item, Item):
			super().__init__(item.id)
			super().__copyInit(item)
			self.__copyInit(item)

		elif isinstance(itemId, ItemId):
			super().__init__(itemId.id)

			if isinstance(count, int):
				self.__selfInit(count)
			else:
				self.__selfInit(1)

		elif GameObject.isValidId(id):
			super().__init__(id)

			if isinstance(count, int):
				self.__selfInit(count)
			else:
				self.__selfInit(1)

		else:
			raise TypeError('Invalid constructor parameter(s) for Item')

	def __selfInit(self, count: int):
		if count > 0:
			self.__count = count
		else:
			self.__count = 1

	def __copyInit(self, item: Item):
		self.__count = item.__count

	def count(self, newVal: int = None):
		if isinstance(newVal, int): # setter
			if newVal >= 0:
				self.__count = newVal
			else:
				raise ValueError('Item count cannot be negative')
		elif not newVal: # getter
			return __count
		else: # some other param
			raise TypeError('Invalid parameter for newVal')

	"""Number of items used in a single mix"""
	__MIX_USAGE = 3

	@classmethod
	def mixItems(self, item1: Item, item2: Item) -> Item:
		if not isinstance(item1, Item):
			raise TypeError('item1 is not an Item')

		if not isinstance(item2, Item):
			raise TypeError('item2 is not an Item')

		if item1.__count >= Item.__MIX_USAGE and item2.__count >= Item.__MIX_USAGE:
			# define the recipe here
			result = None

			# Level 1 mix
			if ((Item.isEqual(item1, ItemId.HONEY) and Item.isEqual(item2, ItemId.HERBS)) or
				(Item.isEqual(item1, ItemId.HERBS) and Item.isEqual(item2, ItemId.HONEY))):

				result = Item(itemId=ItemId.POTION)

			elif ((Item.isEqual(item1, ItemId.HERBS) and Item.isEqual(item2, ItemId.CLAY)) or
					(Item.isEqual(item1, ItemId.CLAY) and Item.isEqual(item2, ItemId.HERBS))):

				result = Item(itemId=ItemId.INCENSE)

			elif ((Item.isEqual(item1, ItemId.CLAY) and Item.isEqual(item2, ItemId.MINERAL)) or
					(Item.isEqual(item1, ItemId.MINERAL) and Item.isEqual(item2, ItemId.CLAY))):

				result = Item(itemId=ItemId.GEMS)

			# Level 2 mix
			elif ((Item.isEqual(item1, ItemId.POTION) and Item.isEqual(item2, ItemId.INCENSE)) or
					(Item.isEqual(item1, ItemId.INCENSE) and Item.isEqual(item2, ItemId.POTION))):

				result = Item(itemId=ItemId.LIFE_ELIXIR)

			elif ((Item.isEqual(item1, ItemId.INCENSE) and Item.isEqual(item2, ItemId.GEMS)) or 
					(Item.isEqual(item1, ItemId.GEMS) and Item.isEqual(item2, ItemId.INCENSE))):

				result = Item(itemId=ItemId.MANA_CRYSTAL)

			# Level 3 mix
			elif ((Item.isEqual(item1, ItemId.LIFE_ELIXIR) and Item.isEqual(item2, ItemId.MANA_CRYSTAL)) or
					(Item.isEqual(item1, ItemId.MANA_CRYSTAL) and Item.isEqual(item2, ItemId.LIFE_ELIXIR))):

				result = Item(itemId=ItemId.PHILOSOPHER_STONE)

			else:
				raise ValueError('Unknown recipe for item {} and {}'.format(item1.id, item2.id))

			# reduce
			item1.__count -= Item.__MIX_USAGE
			item2.__count -= Item.__MIX_USAGE
			if item1.__count < Item.__MIX_USAGE:
				raise ValueError('not enough items for item1')
			else:
				raise ValueError('not enough items for item2')

	@classmethod
	def isEqual(self, item: Item, itemId: ItemId) -> boolean:
		if isinstance(item, Item) and isinstance(itemId, ItemId):
			return item.__id == itemId.index || item.__id == itemId.id
		else:
			raise TypeError('Invalid parameter(s)')

class ItemOffer(GameObject):
	"""docstring for ItemOffer"""

	def __init__(self, player: Player, offer: Item, demand: Item):
		super().__init__(ItemOffer.generateId())
		
		self.offerer_id = player.id
		self.offer = offer
		self.demand = demand

		# Available means that this offer is available to be get
		self.available = True

	@classmethod
	def generateId(self):
		import hashlib
		import random
		import string

		result = str(int(time.time()))

		# generate a random string with length of 6
		result += (''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(6)))

		md5hash = hashlib.md5()
		md5hash.update(result)

		return str(md5hash.hexdigest())

	def asList(self):
		return [self.offer.__id, self.offer.count, self.demand.__id, self.demand.__count, self.avaliable, self.__id]