forked from AllenDowney/ThinkPython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Poker.py
184 lines (142 loc) · 5.63 KB
/
Poker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
"""This module contains code from
Think Python: an Introduction to Software Design
Allen B. Downey
Copyright 2010 Allen B. Downey
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
This program requires Gui.py, which is part of
Swampy; you can download it from thinkpython.com/swampy.
"""
from Tkinter import NW
import Gui
import PokerHand
import ImageTk
class Table(Gui.Gui):
"""A Table displays a green canvas and a control area."""
def __init__(self):
Gui.Gui.__init__(self)
self.cardset = None # the images used to display cards
self.views = {} # map from Hands to HandViews
self.setup()
def setup(self):
self.ca_width = 100
self.ca_height = 100
# left frame
self.row()
self.canvas = self.ca(width=self.ca_width, height=self.ca_height,
bg='dark green', transforms=[])
# right frame
self.col([1,1,1])
self.bu('Quit', command=self.quit)
self.bu('Deal', command=self.deal_hands)
self.bu('Print', command=self.canvas.dump)
def set_cardset(self, cardset, numhands=6, numcards=9):
"""associate a cardset with this table, which has the
effect of changing the size of the canvas and setting
up the coordinate Transform"""
self.cardset = cardset
width = self.cardset.width
height = self.cardset.height
self.canvas.add_transform(TableTransform(width, height))
self.canvas.configure(width=width*numcards, height=height*numhands)
def deal_hands(self, nhands=6, ncards=7):
"""deal the cards and display them on the canvas,
storing the Hands and HandViews in self.views"""
# if there are old HandViews, get rid of them
if len(self.views) != 0:
self.clear()
# shuffle the deck
deck = PokerHand.Deck()
deck.shuffle()
# deal the cards and display each Hand
for i in range(nhands):
hand = PokerHand.PokerHand()
deck.move_cards(hand, ncards)
# classify the hand.
# this version only checks for flushes
if hand.has_flush():
hand.label = 'flush'
view = HandView(hand, self)
view.draw(0, i)
self.views[hand] = view
def clear(self):
"""delete the graphical representation of the HandViews,
then delete the HandViews"""
for view in self.views.values():
view.delete()
self.views = {}
class TableTransform(Gui.Transform):
"""transform coordinates so that the x-axis is in units of card widths
and the y-axis is in units of card heights. The origin is in the
upper left corner, and the y-axis points down."""
def __init__(self, width, height):
self.width = width
self.height = height
def trans(self, p):
x = p[0] * self.width
y = p[1] * self.height
return [x, y]
class Cardset(dict):
"""A cardset is a dictionary that maps a tuple (suit,rank) onto
an Image that depicts the card. In addition, the dictionary
contains a key 'back' that maps to an Image that depicts the
back of the card."""
def __init__(self, dir=None, ext='gif'):
"""create a cardset, reading cards from the given directory"""
dict.__init__(self)
if dir:
self.read_cards(dir, ext)
def read_cards(self, dir, ext='gif'):
suits = 'cdhs'
for rank in range(1,14):
for suit in range(4):
filename = '%s/%.2d%s.%s' % (dir, rank, suits[suit], ext)
image = ImageTk.PhotoImage(file=filename)
self[suit,rank] = image
filename = '%s/back01.gif' % (dir)
try:
image = ImageTk.PhotoImage(file=filename)
self['back'] = image
except:
pass
# cardset keeps track of the width and height of the cards
self.width = image.width()
self.height = image.height()
def lookup(self, card):
"""lookup the given card and return the Image that depicts it"""
return self[card.suit, card.rank]
class HandView:
"""A HandView object represents a Hand being displayed on a Table"""
def __init__(self, hand, table):
self.hand = hand
self.table = table
def draw(self, x=0, y=0):
"""draw the hand at the given location on the table.
the Tk tag for this item is a string based on the object id"""
self.tag = 'HandView%d' % id(self)
cardset = self.table.cardset
width = cardset.width
height = cardset.height
for card in self.hand.cards:
self.draw_card(card, x, y)
x += 1
# display the hand's label next to the hand
self.table.canvas.text([x, y], self.hand.label,
fill='white', anchor=NW, tag=self.tag)
def draw_card(self, card, x, y):
"""draw a single card at the given position"""
image = self.table.cardset.lookup(card)
self.table.canvas.image([x, y], image, anchor=NW, tag=self.tag)
def move(self, dx=0, dy=0):
"""move the entire handset right by dx and down by dy"""
self.table.move_item(self.tag, dx, dy)
def delete(self):
"""remove the graphical representation of this HandView"""
self.table.canvas.delete(self.tag)
def main(name, cardstyle='tuxedo', *args):
table = Table()
cardset = Cardset('cardsets/cardset-' + cardstyle)
table.set_cardset(cardset)
table.mainloop()
if __name__ == '__main__':
import sys
main(*sys.argv)