링크
결과
답은 적지 않지만 풀면서 중복된 값을 찾고 정렬해서 스트레이트 카드인지 여부를 판별하는데 어려움이 있었던것 같다.
소스 코드는 많이 지저분 하지만 나름대로 한번에 풀이한 성과가 있는거 같다.
문제 풀이
- 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)