[Python] 54-Poker hands



답은 적지 않지만 풀면서 중복된 값을 찾고 정렬해서 스트레이트 카드인지 여부를 판별하는데 어려움이 있었던것 같다.

소스 코드는 많이 지저분 하지만 나름대로 한번에 풀이한 성과가 있는거 같다.

문제 풀이

  1. CARD 인덱싱할 수 있는 배열을 선언
  2. 승리 여부를 판별할 수 있는 배열 선언
  3. 각 카드를 승리 여부를 판별 할 수 있는 문자로 변환
  4. 플레이어 2명의 카드가 동일한 경우 두번째로 높은 카드를 판별

** collections.Counter 클래스를 이용 **

collections.Counter 클래스는 배열의 중복되는 값을 찾아 Key-Value 형태로 리턴해주기 때문에 One-Pair, Two-Pairs, Full House, Four Card 등과 같은 값을 판별하기 적합하다.


import collections
import logging

CARD_INDEX = ['A', 'T','J','Q','K']
for i in range(2, 10):
  CARD_INDEX.insert(i-1, str(i))


def flushCheck(nums):
  nums = sorted(nums)
  R_FLUSH_CARDS = [CARD_INDEX.index('A'), CARD_INDEX.index('T'), CARD_INDEX.index('J'), CARD_INDEX.index('Q'), CARD_INDEX.index('K')]
  if (len(set(nums).intersection(R_FLUSH_CARDS)) == 5):
    return 'R_FLUSH', nums

  if not isStraight(nums):
    return 'FLUSH', nums  
  return 'S_FLUSH', nums

def isStraight(nums):
  nums = sorted(nums)
  for i in range(0, len(nums)-1):    
    if (nums[i]+1 != nums[i+1]):      
      return False
  return True

def getResult(nums, suits):   

  if (len(set(suits)) == 1):
    return flushCheck(nums)

  cardCounters = collections.Counter(nums).values()  
  if 4 in cardCounters:
    return 'FOUR_OF_A_KIND', nums

  if len(cardCounters) == 2 and (3 in cardCounters) and (2 in cardCounters):
    return 'FULL_HOUSE', nums

  if isStraight(nums):
    return 'STRAIGHT', nums

  if len(cardCounters) == 3 and 3 in cardCounters:
    return 'THREE_OF_KIND', nums

  if len(cardCounters) == 3 and 2 in collections.Counter(cardCounters).values():
    return 'TWO_PAIR', nums

  if len(cardCounters) == 4 and 2 in cardCounters:
    return "ONE_PAIR", nums

  return "None", 'None'

def sperateNumSuit(s):  
  cards = s.split(" ")
  nums = []
  suits = []
  for c in cards:
    num = c[:1]
    suit = c[1:]    
  return nums, suits

def getHighestNum(num1, num2):
  # Ace is highest number
  while True:
    if 0 not in num1:
    num1[num1.index(0)] = 14  

  while True:
    if 0 not in num2:
    num2[num2.index(0)] = 14  

  collectNum1 = collections.Counter(num1)
  collectNum2 = collections.Counter(num2)

  if (len(collectNum1) == 5):
    if 0 in num1:
      return "PLAYER#1 WIN"
    elif 0 in num2:
      return "PLAYER#2 WIN"    
    return (max(num1) > max(num2)) and "PLAYER#1 WIN" or "PLAYER#2 WIN"

  for i in range(1, len(collectNum1)):
    p1Max = max(collectNum1, key=collectNum1.get)
    p2Max = max(collectNum2, key=collectNum2.get)

    if (collectNum1[p1Max] == 1 and collectNum2[p2Max] == 1):
      return max(collectNum1) > max(collectNum2) and "PLAYER#1 WIN" or "PLAYER#2 WIN"            

    if (p1Max == p2Max):
      print collectNum1, collectNum2
      del collectNum1[p1Max]
      del collectNum2[p2Max]      
      print 'DELETE %s' % CARD_INDEX[p1Max]

      if (p1Max > p2Max):
        return "PLAYER#1 WIN"
        return "PLAYER#2 WIN"

if __name__ == '__main__':
  f = open("C:/Users/coozplz/Downloads/p054_poker.txt")
  lines = f.readlines()  
  p1WinCount = 0
  for s in lines:      
    p1, p2 = s[:14], s[15:len(s)-1]
    logging.info("P1=%s, P2=%s" % (p1, p2))
    nums1, suits1 = sperateNumSuit(p1)    
    pr1, n1 = getResult(nums1, suits1)  
    nums2, suits2 = sperateNumSuit(p2)    
    pr2, n2 = getResult(nums2, suits2)
    if pr1 == None:
      pr1 = 'None'
    if pr2 == None:
      pr2 = 'None'

    logging.info("%s,%s / %s, %s" % (pr1, str(n1), pr2, str(n2)))
    if pr1 == pr2:      
      result = getHighestNum(nums1, nums2)
      if (WIN_ORDER.index(pr1) > WIN_ORDER.index(pr2)):
        result = "PLAYER#1 WIN"
        result = "PLAYER#2 WIN"
    if (result == "PLAYER#1 WIN"):
      p1WinCount += 1
      logging.info("Player1 Won!!")
      logging.info("Player2 Won!!")    
    logging.info( "-" * 80)
  logging.info("Total Win Count=%d" % p1WinCount)    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s