Advertisement
raultres

Hanabi_Borya

Aug 11th, 2014
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.41 KB | None | 0 0
  1. from enum import Enum
  2.  
  3. class Borya(object):
  4.  
  5.     def __init__(self):
  6.         self.num_cards = raw_input()
  7.         cards = raw_input()
  8.         self.actual_hand = self.get_cards(cards)
  9.         self.hand = self.get_possibilities()
  10.         self.counts = self.construct_counts()
  11.         self.clues = self.construct_clues()
  12.         self.duplicate_check()
  13.         while not self.not_done():
  14.             self.give_clue()
  15.             self.narrow_possibilities()
  16.             self.duplicate_check()
  17.         print 10 - len(self.clues)
  18.  
  19.     def get_cards(self, cards):
  20.         cards = cards.split(' ')
  21.         cards = [HanabiCard(card[0], int(card[1])) for card in cards]
  22.         return cards
  23.  
  24.     def get_possibilities(self):
  25.         hand = list()
  26.         for card in self.actual_hand:
  27.             cards = list()
  28.             for card in self.actual_hand:
  29.                 cards.append(card)
  30.             hand.append(cards)
  31.         return hand
  32.  
  33.     def construct_counts(self):
  34.         counts = dict()
  35.         counts['colors'] = dict()
  36.         counts['numbers'] = dict()
  37.         for card in self.actual_hand:
  38.             if card.color.name not in counts['colors']:
  39.                 counts['colors'][card.color.name] = 0
  40.             if card.number not in counts['numbers']:
  41.                 counts['numbers'][card.number] = 0
  42.         for card in self.actual_hand:
  43.             counts['colors'][card.color.name] += 1
  44.             counts['numbers'][card.number] += 1
  45.         counts = self.delete_small_counts('colors', counts)
  46.         counts = self.delete_small_counts('numbers', counts)
  47.         return counts
  48.  
  49.     def delete_small_counts(self, category, counts):
  50.         counts_dict = counts[category]
  51.         min = counts_dict.values()[0]
  52.         min_key = counts_dict.keys()[0]
  53.         for key, value in counts_dict.iteritems():
  54.             if value<=min:
  55.                 min = value
  56.                 min_key = key
  57.         #print min_key
  58.         counts[category] = {key: value for key, value in \
  59.                         counts[category].iteritems() if key != min_key}
  60.         return counts
  61.  
  62.  
  63.  
  64.     def construct_clues(self):
  65.         clues = Color.__members__.keys()
  66.         for i in range(1,6):
  67.             clues.append(i)
  68.         #print clues
  69.         return clues
  70.  
  71.     def duplicate_check(self):
  72.         for card_num in range(len(self.hand)):
  73.             possibilities = self.hand[card_num]
  74.             if all(card == possibilities[0] for card in possibilities):
  75.                 possibilities = [possibilities[0]]
  76.                 self.purge(possibilities[0], card_num)
  77.  
  78.     def purge(self, card, card_num):
  79.         for card_number in range(len(self.hand)):
  80.             if not card_number == card_num:
  81.                 possibilities = self.hand[card_number]
  82.                 for possibility in possibilities:
  83.                     if card == possibility:
  84.                         possibilities.remove(possibility)
  85.                         break
  86.    
  87.     def not_done(self):
  88.         for possibilities in self.hand:
  89.             if len(possibilities)>1:
  90.                 return False
  91.         return True
  92.    
  93.     def give_clue(self):
  94.         #print 'clue!'
  95.         clue = self.find_max_count()
  96.         #print clue
  97.         #if clue is None:
  98.             #raise Exception("clue is none! wtf")
  99.         if clue in self.clues:
  100.             self.clues.remove(clue)
  101.             self.update_hand_using_clue(clue)
  102.             #else:
  103.                 #raise Exception("same clue twice? wtf")
  104.  
  105.     def find_max_count(self):
  106.         maximum = 0
  107.         clue = None
  108.         for color, value in self.counts['colors'].items():
  109.             if color in self.clues:
  110.                 if value>=maximum:
  111.                     maximum = value
  112.                     clue = color
  113.  
  114.         for number, value in self.counts['numbers'].items():
  115.             if number in self.clues:
  116.                 if value>=maximum:
  117.                     maximum = value
  118.                     clue = number
  119.         return clue
  120.  
  121.     def update_hand_using_clue(self, clue):
  122.         for card_num in range(len(self.actual_hand)):
  123.             card = self.actual_hand[card_num]
  124.             characteristics = list()
  125.             if type(clue) is int:
  126.                 if card.number == clue:
  127.                     characteristics = range(1,6)
  128.                     characteristics.remove(clue)
  129.                     # "doesn't match number"
  130.                 else:
  131.                     #print "matched number"
  132.                     characteristics.append(clue)
  133.             else:
  134.                 if card.color == Color[clue]:
  135.                     characteristics = Color.__members__.keys()
  136.                     characteristics.remove(clue)
  137.                     #print 'doesnt match color'
  138.                 else:
  139.                     characteristics.append(Color[clue])
  140.                     #print 'matches color'
  141.  
  142.             self.purge_characteristic(card_num, characteristics)
  143.  
  144.  
  145.     def purge_characteristic(self, card_num, characteristics):
  146.         #print 'purge character!'
  147.         #print characteristics
  148.         if type(characteristics[0]) is int:
  149.             for characteristic in characteristics:
  150.                 possibility_num = 0
  151.                 while possibility_num<len(self.hand[card_num]):
  152.                     possibility = self.hand[card_num][possibility_num]
  153.                     if possibility.number == characteristic:
  154.                         self.hand[card_num].remove(possibility)
  155.                     else:
  156.                         possibility_num+=1
  157.  
  158.         else:
  159.             for characteristic in characteristics:
  160.                 possibility_num = 0
  161.                 while possibility_num<len(self.hand[card_num]):
  162.                     possibility = self.hand[card_num][possibility_num]
  163.                     if possibility.color.name == characteristic:
  164.                         self.hand[card_num].remove(possibility)
  165.                     else:
  166.                         possibility_num+=1
  167.  
  168.     def narrow_possibilities(self):
  169.         for card_num in range(len(self.hand)):
  170.             possibilities = self.hand[card_num]
  171.             if len(possibilities) == 1:
  172.                 self.purge(possibilities[0], card_num)
  173.  
  174. class HanabiCard(object):
  175.     """
  176.     card class for hanabi cards
  177.     """
  178.     def __init__(self, c, number):
  179.         if c in Color.__members__:
  180.             self.color = Color[c]
  181.         #else:
  182.             #raise Exception("color is out of bounds")
  183.         if number in range(1,6):
  184.             self.number = number
  185.         #else:
  186.             #raise Exception("number is out of bounds")
  187.  
  188.     def __repr__(self):
  189.         return "[%s, %d]"%(self.color, self.number)
  190.  
  191.     def __eq__(self, other):
  192.         return self.number == other.number and self.color == other.color
  193.  
  194. class Color(Enum):
  195.     R = 1
  196.     G = 2
  197.     B = 3
  198.     Y = 4
  199.     W = 5
  200.  
  201. if __name__ == "__main__":
  202.     solve = Borya()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement