1 """simpocker.py
2 Pocker simulation for probability varaition by user number
3 By Hyung-Yong Kim, 2003-1
4 http://bioinfo.sarang.net/wiki/PockerSimulation
5 """
6
7 import unittest, random
8
9
10 SEQ_NUMBER=('2','3','4','5','6','7','8','9','0','J','Q','K','1')
11 SEQ_NUMBER_REVERSE=('1','K','Q','J','0','9','8','7','6','5','4','3','2','1')
12 SEQ_FEATURE=('C','H','D','S')
13 SEQ_FEATURE_REVERSE=('S','D','H','C')
14 SEQ_CARDS=('StiFl','Pocker','House','Flush','Straight','Triple',
15 'TwoPair','OnePair')
16
17 class Trump:
18 def __init__(self):
19 self.cards=[]
20 for number in SEQ_NUMBER:
21 for feature in SEQ_FEATURE:
22 self.cards.append(number+feature)
23 random.shuffle(self.cards)
24 def getCard(self):
25 card=self.cards.pop()
26 return card
27
28 class Cards:
29 def __init__(self, aCardList=None):
30 for each in SEQ_CARDS:
31 setattr(self, each, None)
32 self.Triple=[]; self.OnePair=[]
33 if aCardList:
34 self.cards=aCardList
35 self.initdecide()
36 else: self.cards=[]
37
38 def put(self, aCard):
39 self.cards.append(aCard)
40 if len(self.cards) == 7:
41 self.initdecide()
42 def get(self):
43 return self.cards
44 def __str__(self):
45 return str(self.cards)
46
47 def initdecide(self):
48 self.numberOfFeatures = {'S':0, 'D':0, 'H':0, 'C':0}
49 self.numberOfNumbers = {'0':0, '1':0, '2':0, '3':0,
50 '4':0, '5':0, '6':0, '7':0,
51 '8':0, '9':0, 'J':0, 'Q':0, 'K':0,}
52 self.numbers=[]
53 for card in self.cards:
54 self.numbers.append(card[0])
55 self.numberOfFeatures[card[1]]+=1
56 self.numberOfNumbers[card[0]]+=1
57 for fName in SEQ_FEATURE:
58 if self.numberOfFeatures[fName] >= 5: self.Flush=fName
59 for nName in SEQ_NUMBER:
60 if self.numberOfNumbers[nName] == 4: self.Pocker=nName
61 elif self.numberOfNumbers[nName] == 3: self.Triple.append(nName)
62 elif self.numberOfNumbers[nName] == 2: self.OnePair.append(nName)
63
64 def findCardByNum(self, aNum):
65 if not aNum: return
66 for fName in SEQ_FEATURE_REVERSE:
67 card = aNum + fName
68 if card in self.cards:
69 return card
70 def findCardByFea(self, aFea):
71 if not aFea: return
72 for nName in SEQ_NUMBER_REVERSE:
73 card = nName + aFea
74 if card in self.cards:
75 return card
76
77 def isFlush(self):
78 return self.findCardByFea(self.Flush)
79 def isPocker(self):
80 return self.findCardByNum(self.Pocker)
81 def isHouse(self):
82 if len(self.Triple) ==2:
83 return self.Triple
84 elif self.Triple and self.OnePair:
85 return [self.OnePair[0], self.Triple[0]]
86 def isTriple(self):
87 if self.Triple:
88 return self.Triple[-1]
89 def isOnePair(self):
90 if self.OnePair:
91 return self.findCardByNum(self.OnePair[-1])
92 def isTwoPair(self):
93 if self.OnePair:
94 if len(self.OnePair) > 1:
95 return [self.findCardByNum(self.OnePair[-2]),
96 self.findCardByNum(self.OnePair[-1]),
97 ]
98 def isStraight(self,aNumberList=None):
99 if aNumberList:
100 aList = aNumberList
101 else:
102 aList = self.numbers
103 i=0;j=0
104 for num in SEQ_NUMBER_REVERSE:
105 j+=1
106 if num in aList:
107 i+=1
108 if i==5:
109 self.Straight = SEQ_NUMBER_REVERSE[j-5]
110 break
111 continue
112 i=0
113 return self.findCardByNum(self.Straight)
114
115 def isStiFl(self):
116 if self.isFlush():
117 feature = self.isFlush()[1]
118 newList=[]
119 for card in self.cards:
120 if card[1] == feature: newList.append(card[0])
121 return self.isStraight(newList)
122
123 def decide(self):
124 if self.isStiFl():
125 return ('StiFl',self.isStiFl())
126 elif self.isPocker():
127 return ('Pocker',self.isPocker())
128 elif self.isHouse():
129 return ('House',self.isHouse())
130 elif self.isFlush():
131 return ('Flush',self.isFlush())
132 elif self.isStraight():
133 return ('Straight',self.isStraight())
134 elif self.isTriple():
135 return ('Triple',self.isTriple())
136 elif self.isTwoPair():
137 return ('TwoPair',self.isTwoPair())
138 elif self.isOnePair():
139 return ('OnePair',self.isOnePair())
140 else:
141 for num in SEQ_NUMBER_REVERSE:
142 if num in self.numbers:
143 for feature in SEQ_FEATURE_REVERSE:
144 card = num+feature
145 if card in self.cards:
146 return (None, card)
147
148 class Game:
149 def __init__(self, aNumOfPlayers):
150 t=Trump()
151 self.results=[]
152 for player in range(aNumOfPlayers):
153 c=Cards()
154 for i in range(7):
155 c.put(t.getCard())
156 self.results.append(c)
157 def getRawResult(self):
158 return self.results
159 def getDecidedResult(self):
160 decidedResult=[]
161 for cards in self.results:
162 decidedResult.append(cards.decide())
163 return decidedResult
164 def getSimpleJokboList(self):
165 return getEachItems(self.getDecidedResult(),0)
166 def judgeWinner(self):
167 return judge(self.getDecidedResult())
168 def getResultRecord(self):
169
170 record=[]
171 record.append(self.judgeWinner()[0])
172 record.extend(self.getSimpleJokboList())
173 return record
174
175 class GameStat:
176 def __init__(self, aNumOfGames, aNumOfPlayers):
177 self.numOfGames = aNumOfGames
178 self.numOfPlayers = aNumOfPlayers
179 self.result=[]
180 for i in range(aNumOfGames):
181 g=Game(aNumOfPlayers)
182 self.result.append(g.getResultRecord())
183 self.jokboFreq={}; self.jokboFreq[None]=0
184 for cards in SEQ_CARDS:
185 self.jokboFreq[cards]=0
186 self.jokboWin = self.jokboFreq.copy()
187
188 def getRawResult(self):
189 return self.result
190 def calculateEmitProb(self):
191 for eachRecord in self.result:
192 for jokbo in eachRecord[1:]:
193 self.jokboFreq[jokbo]+=1
194 def getEmitProb(self):
195 n = self.numOfGames * self.numOfPlayers
196 return self.jokboFreq, n
197 def calculateWinProb(self):
198 for eachRecord in self.result:
199 win=eachRecord[eachRecord[0]+1]
200 self.jokboWin[win]+=1
201 for jokbo in eachRecord[1:]:
202 self.jokboFreq[jokbo]+=1
203 def getWinProb(self):
204 return self.jokboWin, self.jokboFreq
205
206
207 def getEachItems(aList,aIth):
208 """return i'th items in list """
209 result=[]
210 for each in aList:
211 result.append(each[aIth])
212 return result
213
214 def getHighestCard(aList):
215 winNum=None; winFea=None
216 if len(aList[0]) == 1:
217 numList = aList
218 else:
219 numList = getEachItems(aList,0)
220 for num in SEQ_NUMBER_REVERSE:
221 if num in numList:
222 winNum=num
223 if len(aList[0]) == 1: return num
224 break
225 lastList=[]
226 for card in aList:
227 if card[0]==winNum:
228 lastList.append(card)
229 for fea in SEQ_FEATURE_REVERSE:
230 if fea in getEachItems(lastList,1):
231 winFea=fea
232 break
233 return winNum+winFea
234
235 def judge(aList):
236 cardsNames = getEachItems(aList,0)
237 highCardList = getEachItems(aList,1)
238 winnerIndex=None; winners=[]; winnerJokbo=None
239 for jokbo in SEQ_CARDS:
240 if jokbo in cardsNames:
241 winnerJokbo=jokbo
242 if cardsNames.count(jokbo) ==1:
243 winnerIndex=cardsNames.index(jokbo)
244 return (winnerIndex, winnerJokbo)
245 else:
246 i=0
247 for myJokbo in cardsNames:
248 if jokbo == myJokbo: winners.append(i)
249 i+=1
250 lastCardList=[];lastCardAll=[]
251 for j in winners:
252 if jokbo in ('TwoPair','House'):
253 lastCard=highCardList[j][1]
254 lastCardAll.append(highCardList[j])
255 else:
256 lastCard=highCardList[j]
257 lastCardList.append(lastCard)
258
259 hgCard=getHighestCard(lastCardList)
260 if jokbo in ('TwoPair','House'):
261 for oneCards in lastCardAll:
262 if hgCard in oneCards:
263 hgCardIndex=highCardList.index(oneCards)
264 else:
265 hgCardIndex=highCardList.index(hgCard)
266 return (hgCardIndex, winnerJokbo)
267
268 hgCard=getHighestCard(highCardList)
269 return (highCardList.index(hgCard), None)
270
271
272
273
274 class PockerTest(unittest.TestCase):
275 def testTrump(self):
276 t=Trump()
277 self.assertEquals(52, len(t.cards))
278 t.getCard()
279 self.assertEquals(51, len(t.cards))
280 def testCards(self):
281 c=Cards(['1S','2S','3D','4S','2C','9H','0H'])
282 self.assertEquals(['1S','2S','3D','4S','2C','9H','0H'], c.get())
283 def testGame(self):
284 g=Game(4)
285 result=g.getRawResult()
286 self.assertEquals(4, len(result))
287 for card in result:
288 self.assertEquals(7,len(card.cards))
289 self.assertNotEquals(result[0], result[1])
290
291 class CardsEachJudgmentTest(unittest.TestCase):
292 def testFlush(self):
293 c=Cards(['1S', '2S', '3S', '4S', '5S', '7C', '8C'])
294 self.assertEquals('1S',c.isFlush())
295 c=Cards(['1S', '2S', '3S', '4S', '5C', '7C', '8C'])
296 self.assertEquals(None, c.isFlush())
297 c=Cards(['1S', '2S', '3C', '4C', '5C', '7C', '8C'])
298 self.assertEquals('8C', c.isFlush())
299 def testPocker(self):
300 c=Cards(['1S','1D','1H','1C','2S','4S','6C'])
301 self.assertEquals('1S', c.isPocker())
302 def testHouse(self):
303 c=Cards(['1S','1D','1H','2S','2D','2H','6C'])
304 self.assertEquals(['2','1'], c.isHouse())
305 c=Cards(['1S','1D','1H','2S','2D','3H','6C'])
306 self.assertEquals(['2','1'], c.isHouse())
307 def testTriple(self):
308 c=Cards(['1S','1D','1H','2S','2D','3H','6C'])
309 self.assertEquals('1', c.isTriple())
310 def testOnePair(self):
311 c = Cards(['1S','1D','4H','2S','2D','3H','6C'])
312 self.assertEquals('1S', c.isOnePair())
313 c = Cards(['1S','1D','4H','2S','5D','3H','6C'])
314 self.assertEquals('1S', c.isOnePair())
315 def testTwoPair(self):
316 c = Cards(['1S','1D','4H','2S','2D','3H','6C'])
317 self.assertEquals(['2S','1S'], c.isTwoPair())
318 def testStraight(self):
319 c = Cards(['1S','2D','3H','3S','4D','4H','5C'])
320 self.assertEquals('5C', c.isStraight())
321 c = Cards(['1S','KD','QH','JS','0D','4H','5C'])
322 self.assertEquals('1S', c.isStraight())
323 c = Cards(['8S','9D','JH','0S','7D','QH','5C'])
324 self.assertEquals('QH', c.isStraight())
325 c = Cards(['2S','3D','4H','5S','7D','8H','5C'])
326 self.assertEquals(None, c.isStraight())
327 c = Cards(['2S','3D','4H','5S','7D','7H','6S'])
328 self.assertEquals('7D', c.isStraight())
329 def testStiFl(self):
330 c = Cards(['2S','3S','4S','5S','7S','7H','6S'])
331 self.assertEquals('7S', c.isStiFl())
332 c = Cards(['KS','0S','1S','JS','QS','7H','6S'])
333 self.assertEquals('1S', c.isStiFl())
334 c = Cards(['KS','0S','1D','JS','QS','7H','6S'])
335 self.assertEquals(None, c.isStiFl())
336
337 class CardsTotalJudgmentTest(unittest.TestCase):
338 def testOnePair(self):
339 c=Cards(['1S', '1C', '3D', '4S', '5S', '7C', '8C'])
340 self.assertEquals(('OnePair','1S'), c.decide())
341 c=Cards(['2S', '1C', '3D', '4S', '8S', '7C', '7S'])
342 self.assertEquals(('OnePair','7S'), c.decide())
343 def testTwoPair(self):
344 c=Cards(['1S', '1C', '3D', '4S', '5S', '7C', '7S'])
345 self.assertEquals(('TwoPair',['7S','1S']), c.decide())
346 c=Cards(['KD', 'KC', '3D', '4S', '5C', '5H', '8S'])
347 self.assertEquals(('TwoPair',['5H','KD']), c.decide())
348 def testTriple(self):
349 c=Cards(['1S', '1C', '1D', '4S', '5S', '7C', '2H'])
350 self.assertEquals(('Triple','1'), c.decide())
351 def testStraight(self):
352 c=Cards(['3S', '4C', '5D', '6S', '5S', '7C', '7H'])
353 self.assertEquals(('Straight','7H'), c.decide())
354 def testFlush(self):
355 c=Cards(['3S', '4S', '5S', '6S', '5S', '7C', '7H'])
356 self.assertEquals(('Flush','6S'), c.decide())
357 def testPocker(self):
358 c=Cards(['3S', '3C', '3H', '6S', '5S', '7C', '3D'])
359 self.assertEquals(('Pocker','3S'), c.decide())
360 def testStiFl(self):
361 c=Cards(['2C', '3C', '4C', '6C', '5C', '8C', '3D'])
362 self.assertEquals(('StiFl','6C'), c.decide())
363 def testNone(self):
364 c=Cards(['2C', '3C', '4C', '7S', '5C', '8D', 'KD'])
365 self.assertEquals((None,'KD'), c.decide())
366
367 class JudgeWinner(unittest.TestCase):
368 def testOneCard(self):
369 input=['1S','2S','4S','KS']
370 self.assertEquals('1S', getHighestCard(input))
371 def testTwoCard(self):
372 input=['4C','2S','4D','2C']
373 self.assertEquals('4D', getHighestCard(input))
374 def testOneJokbo(self):
375 input=[('OnePair','1S'), ('Flush','6S'), (None, '1S')]
376 self.assertEquals((1,'Flush'), judge(input))
377 def testTwoJokbo(self):
378 input=[('OnePair','4C'), ('OnePair','4D'), (None, '2S')]
379 self.assertEquals((1,'OnePair'), judge(input))
380 def testTwoTwoPair(self):
381 input=[('TwoPair',['4C','1C']), ('OnePair','4D'),
382 ('TwoPair',['2S','7C'])]
383 self.assertEquals((0,'TwoPair'), judge(input))
384 def testTwoHouse(self):
385 input=[('House',['4','K']), ('OnePair','4D'),
386 ('House',['2','1'])]
387 self.assertEquals((2,'House'), judge(input))
388 def testTwoNone(self):
389 input=[(None,'4C'), (None,'4D'), (None,'2D')]
390 self.assertEquals((1,None), judge(input))
391
392 class GameStatTest(unittest.TestCase):
393 def testJudgeWinner(self):
394 g=Game(4)
395 result=g.judgeWinner()
396 self.assertEquals(str, type(result[1]))
397 def testGetResultRecord(self):
398 g=Game(4)
399
400 resultRecord=g.getResultRecord()
401 self.assertEquals(int, type(resultRecord[0]))
402 self.assertEquals(5, len(resultRecord))
403 def testGameStat(self):
404 gs=GameStat(10,4)
405 self.assertEquals(10,len(gs.getRawResult()))
406
407 def emitProbEachJokbo():
408 gs=GameStat(20000,4)
409 gs.calculateEmitProb()
410 jokboFreqDict,n=gs.getEmitProb()
411 for key,value in jokboFreqDict.items():
412 print key,'...',100*float(value)/n
413
414 def winProbEachJokbo(aNumOfPlayers):
415 gs=GameStat(20000,aNumOfPlayers)
416 gs.calculateWinProb()
417 jokboWinDict,jokboFreqDict=gs.getWinProb()
418 for key,value in jokboFreqDict.items():
419 print key,'...',100*(float(jokboWinDict[key])/value)
420
421 def testAll():
422 unittest.main(argv=('','-v'))
423 def testPart():
424 myTests = [JudgeWinner('testOneJokbo'),
425 JudgeWinner('testTwoJokbo'),
426 ]
427 suite = unittest.TestSuite()
428 for eachTest in myTests:
429 suite.addTest(eachTest)
430 unittest.TextTestRunner().run(suite)
431
432 if __name__=='__main__':
433 testAll()
434
435
436