결과
답은 적지 않지만 풀면서 중복된 값을 찾고 정렬해서 스트레이트 카드인지 여부를 판별하는데 어려움이 있었던것 같다.
소스 코드는 많이 지저분 하지만 나름대로 한번에 풀이한 성과가 있는거 같다.
문제 풀이
- CARD 인덱싱할 수 있는 배열을 선언
- 승리 여부를 판별할 수 있는 배열 선언
- 각 카드를 승리 여부를 판별 할 수 있는 문자로 변환
- 플레이어 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'] WIN_ORDER = ['None', 'HIGH', 'ONE_PAIR', 'TWO_PAIR', 'THREE_OF_KIND' , 'STRAIGHT', 'FLUSH', 'FULL_HOUSE', 'FOUR_OF_A_KIND', 'S_FLUSH', 'R_FLUSH'] for i in range(2, 10): CARD_INDEX.insert(i-1, str(i)) logging.basicConfig(filename='D:/result.log',level=logging.DEBUG) 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:] nums.append(CARD_INDEX.index(num)) suits.append(suit) return nums, suits def getHighestNum(num1, num2): # Ace is highest number while True: if 0 not in num1: break num1[num1.index(0)] = 14 while True: if 0 not in num2: break 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] else: if (p1Max > p2Max): return "PLAYER#1 WIN" else: 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) else: if (WIN_ORDER.index(pr1) > WIN_ORDER.index(pr2)): result = "PLAYER#1 WIN" else: result = "PLAYER#2 WIN" if (result == "PLAYER#1 WIN"): p1WinCount += 1 logging.info("Player1 Won!!") else: logging.info("Player2 Won!!") logging.info( "-" * 80) logging.info("Total Win Count=%d" % p1WinCount)