# Path: pypokerengine/engine/pay_info.py
# class PayInfo:
# 
#   PAY_TILL_END = 0
#   ALLIN  = 1
#   FOLDED = 2
# 
#   def __init__(self, amount=0, status=0):
#     self.amount = amount
#     self.status = status
# 
#   def update_by_pay(self, amount):
#     self.amount += amount
# 
#   def update_to_fold(self):
#     self.status = self.FOLDED
# 
#   def update_to_allin(self):
#     self.status = self.ALLIN
# 
#   # serialize format : [amount, status]
#   def serialize(self):
#     return [self.amount, self.status]
# 
#   @classmethod
#   def deserialize(self, serial):
#     return self(amount=serial[0], status=serial[1])
# 
# Path: pypokerengine/engine/card.py
# class Card:
# 
#   CLUB = 2
#   DIAMOND = 4
#   HEART = 8
#   SPADE = 16
# 
#   SUIT_MAP = {
#       2  : 'C',
#       4  : 'D',
#       8  : 'H',
#       16 : 'S'
#   }
# 
#   RANK_MAP = {
#       2  :  '2',
#       3  :  '3',
#       4  :  '4',
#       5  :  '5',
#       6  :  '6',
#       7  :  '7',
#       8  :  '8',
#       9  :  '9',
#       10 : 'T',
#       11 : 'J',
#       12 : 'Q',
#       13 : 'K',
#       14 : 'A'
#   }
# 
# 
#   def __init__(self, suit, rank):
#     self.suit = suit
#     self.rank = 14 if rank == 1 else rank
# 
#   def __eq__(self, other):
#     return self.suit == other.suit and self.rank == other.rank
# 
#   def __str__(self):
#     suit = self.SUIT_MAP[self.suit]
#     rank = self.RANK_MAP[self.rank]
#     return "{0}{1}".format(suit, rank)
# 
#   def to_id(self):
#     rank = 1 if self.rank == 14 else self.rank
#     num = 0
#     tmp = self.suit >> 1
#     while tmp&1 != 1:
#       num += 1
#       tmp >>= 1
# 
#     return rank + 13 * num
# 
#   @classmethod
#   def from_id(cls, card_id):
#     suit, rank = 2, card_id
#     while rank > 13:
#       suit <<= 1
#       rank -= 13
# 
#     return cls(suit, rank)
# 
#   @classmethod
#   def from_str(cls, str_card):
#     assert(len(str_card)==2)
#     inverse = lambda hsh: {v:k for k,v in hsh.items()}
#     suit = inverse(cls.SUIT_MAP)[str_card[0].upper()]
#     rank = inverse(cls.RANK_MAP)[str_card[1]]
#     return cls(suit, rank)
# 
# Path: pypokerengine/engine/poker_constants.py
# class PokerConstants:
# 
#   class Action:
#     FOLD  = 0
#     CALL  = 1
#     RAISE = 2
#     SMALL_BLIND = 3
#     BIG_BLIND = 4
#     ANTE = 5
# 
#   class Street:
#     PREFLOP = 0
#     FLOP = 1
#     TURN = 2
#     RIVER = 3
#     SHOWDOWN = 4
#     FINISHED = 5


from pypokerengine.engine.pay_info import PayInfo
from pypokerengine.engine.card import Card
from pypokerengine.engine.poker_constants import PokerConstants as Const


class Player:

  ACTION_FOLD_STR = "FOLD"
  ACTION_CALL_STR = "CALL"
  ACTION_RAISE_STR = "RAISE"
  ACTION_SMALL_BLIND = "SMALLBLIND"
  ACTION_BIG_BLIND = "BIGBLIND"
  ACTION_ANTE = "ANTE"

  def __init__(self, uuid, initial_stack, name="No Name"):
    self.name = name
    self.uuid = uuid
    self.hole_card = []
    self.stack = initial_stack
    self.round_action_histories = self.__init_round_action_histories()
    self.action_histories = []
    self.pay_info = PayInfo()

  def add_holecard(self, cards):
    if len(self.hole_card) != 0:
      raise ValueError(self.__dup_hole_msg)
    if len(cards) != 2:
      raise ValueError(self.__wrong_num_hole_msg % (len(cards)))

# Path: pypokerengine/engine/pay_info.py
# class PayInfo:
# 
#   PAY_TILL_END = 0
#   ALLIN  = 1
#   FOLDED = 2
# 
#   def __init__(self, amount=0, status=0):
#     self.amount = amount
#     self.status = status
# 
#   def update_by_pay(self, amount):
#     self.amount += amount
# 
#   def update_to_fold(self):
#     self.status = self.FOLDED
# 
#   def update_to_allin(self):
#     self.status = self.ALLIN
# 
#   # serialize format : [amount, status]
#   def serialize(self):
#     return [self.amount, self.status]
# 
#   @classmethod
#   def deserialize(self, serial):
#     return self(amount=serial[0], status=serial[1])
# 
# Path: pypokerengine/engine/card.py
# class Card:
# 
#   CLUB = 2
#   DIAMOND = 4
#   HEART = 8
#   SPADE = 16
# 
#   SUIT_MAP = {
#       2  : 'C',
#       4  : 'D',
#       8  : 'H',
#       16 : 'S'
#   }
# 
#   RANK_MAP = {
#       2  :  '2',
#       3  :  '3',
#       4  :  '4',
#       5  :  '5',
#       6  :  '6',
#       7  :  '7',
#       8  :  '8',
#       9  :  '9',
#       10 : 'T',
#       11 : 'J',
#       12 : 'Q',
#       13 : 'K',
#       14 : 'A'
#   }
# 
# 
#   def __init__(self, suit, rank):
#     self.suit = suit
#     self.rank = 14 if rank == 1 else rank
# 
#   def __eq__(self, other):
#     return self.suit == other.suit and self.rank == other.rank
# 
#   def __str__(self):
#     suit = self.SUIT_MAP[self.suit]
#     rank = self.RANK_MAP[self.rank]
#     return "{0}{1}".format(suit, rank)
# 
#   def to_id(self):
#     rank = 1 if self.rank == 14 else self.rank
#     num = 0
#     tmp = self.suit >> 1
#     while tmp&1 != 1:
#       num += 1
#       tmp >>= 1
# 
#     return rank + 13 * num
# 
#   @classmethod
#   def from_id(cls, card_id):
#     suit, rank = 2, card_id
#     while rank > 13:
#       suit <<= 1
#       rank -= 13
# 
#     return cls(suit, rank)
# 
#   @classmethod
#   def from_str(cls, str_card):
#     assert(len(str_card)==2)
#     inverse = lambda hsh: {v:k for k,v in hsh.items()}
#     suit = inverse(cls.SUIT_MAP)[str_card[0].upper()]
#     rank = inverse(cls.RANK_MAP)[str_card[1]]
#     return cls(suit, rank)
# 
# Path: pypokerengine/engine/poker_constants.py
# class PokerConstants:
# 
#   class Action:
#     FOLD  = 0
#     CALL  = 1
#     RAISE = 2
#     SMALL_BLIND = 3
#     BIG_BLIND = 4
#     ANTE = 5
# 
#   class Street:
#     PREFLOP = 0
#     FLOP = 1
#     TURN = 2
#     RIVER = 3
#     SHOWDOWN = 4
#     FINISHED = 5


# Path: pypokerengine/engine/player.py
from pypokerengine.engine.pay_info import PayInfo
from pypokerengine.engine.card import Card
from pypokerengine.engine.poker_constants import PokerConstants as Const



class Player:

  ACTION_FOLD_STR = "FOLD"
  ACTION_CALL_STR = "CALL"
  ACTION_RAISE_STR = "RAISE"
  ACTION_SMALL_BLIND = "SMALLBLIND"
  ACTION_BIG_BLIND = "BIGBLIND"
  ACTION_ANTE = "ANTE"

  def __init__(self, uuid, initial_stack, name="No Name"):
    self.name = name
    self.uuid = uuid
    self.hole_card = []
    self.stack = initial_stack
    self.round_action_histories = self.__init_round_action_histories()
    self.action_histories = []
    self.pay_info = PayInfo()

  def add_holecard(self, cards):
    if len(self.hole_card) != 0:
      raise ValueError(self.__dup_hole_msg)
    if len(cards) != 2:
      raise ValueError(self.__wrong_num_hole_msg % (len(cards)))

    if not all([isinstance(card, Card) for card in cards]):