comparison frontends/wix/card_game.py @ 92:2503de7fb4c7

Tarot game: chien/écart stage - tarot plugin: new methods/signals tarotGamePlayCards, tarotGameShowCards, tarotGameYourTurn - tarot plugin: protocole update - tarot plugin: family renamed in suit - wix: card_game: card can be selected for écart, card move when mouse is over only if it's our turn
author Goffi <goffi@goffi.org>
date Sat, 29 May 2010 20:53:03 +0930
parents 39c672544593
children 2f87651a5ad8
comparison
equal deleted inserted replaced
91:39c672544593 92:2503de7fb4c7
31 CARD_WIDTH = 74 31 CARD_WIDTH = 74
32 CARD_HEIGHT = 136 32 CARD_HEIGHT = 136
33 MIN_WIDTH = 950 #Minimum size of the panel 33 MIN_WIDTH = 950 #Minimum size of the panel
34 MIN_HEIGHT = 500 34 MIN_HEIGHT = 500
35 35
36 families_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have swith the usual order 'trefle' and 'carreau' because card are more easy to see if couleur change (black, red, black, red) 36 suits_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have swith the usual order 'trefle' and 'carreau' because card are more easy to see if couleur change (black, red, black, red)
37 values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"] 37 values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"]
38 38
39 class Card(): 39 class Card():
40 """This class is used to represent a card, graphically and logically""" 40 """This class is used to represent a card, graphically and logically"""
41 41
42 def __init__(self, file): 42 def __init__(self, file):
43 """@param file: path of the PNG file""" 43 """@param file: path of the PNG file"""
44 self.bitmap = wx.Image(file).ConvertToBitmap() 44 self.bitmap = wx.Image(file).ConvertToBitmap()
45 root_name = os.path.splitext(os.path.basename(file))[0] 45 root_name = os.path.splitext(os.path.basename(file))[0]
46 self.family,self.value=root_name.split('_') 46 self.suit,self.value=root_name.split('_')
47 self.bout = True if self.family=="atout" and self.value in ["1","21","excuse"] else False 47 #gof: self.bout = True if self.suit=="atout" and self.value in ["1","21","excuse"] else False
48 48
49 print "Carte:",self.family, self.value, self.bout 49 print "Carte:",self.suit, self.value #, self.bout
50 50
51 def __cmp__(self, other): 51 def __cmp__(self, other):
52 if other == None: 52 if other == None:
53 return 1 53 return 1
54 if self.family != other.family: 54 if self.suit != other.suit:
55 idx1 = families_order.index(self.family) 55 idx1 = suits_order.index(self.suit)
56 idx2 = families_order.index(other.family) 56 idx2 = suits_order.index(other.suit)
57 return idx1.__cmp__(idx2) 57 return idx1.__cmp__(idx2)
58 if self.family == 'atout': 58 if self.suit == 'atout':
59 if self.value == other.value == 'excuse': 59 if self.value == other.value == 'excuse':
60 return 0 60 return 0
61 if self.value == 'excuse': 61 if self.value == 'excuse':
62 return -1 62 return -1
63 if other.value == 'excuse': 63 if other.value == 'excuse':
64 return 1 64 return 1
65 return int(self.value).__cmp__(int(other.value)) 65 return int(self.value).__cmp__(int(other.value))
66 #at this point we have the same family which is not 'atout' 66 #at this point we have the same suit which is not 'atout'
67 idx1 = values_order.index(self.value) 67 idx1 = values_order.index(self.value)
68 idx2 = values_order.index(other.value) 68 idx2 = values_order.index(other.value)
69 return idx1.__cmp__(idx2) 69 return idx1.__cmp__(idx2)
70 70
71 def __str__(self): 71 def __str__(self):
72 return "[%s,%s]" % (self.family, self.value) 72 return "[%s,%s]" % (self.suit, self.value)
73 73
74 def draw(self, dc, x, y): 74 def draw(self, dc, x, y):
75 """Draw the card on the device context 75 """Draw the card on the device context
76 @param dc: device context 76 @param dc: device context
77 @param x: abscissa 77 @param x: abscissa
80 80
81 81
82 class CardPanel(wx.Panel): 82 class CardPanel(wx.Panel):
83 """This class is used to display the cards""" 83 """This class is used to display the cards"""
84 84
85 def __init__(self, parent, referee, players, user): 85 def __init__(self, parent, referee, players, player_nick):
86 wx.Panel.__init__(self, parent) 86 wx.Panel.__init__(self, parent)
87 self.parent = parent 87 self.parent = parent
88 self.referee = referee 88 self.referee = referee
89 self.players = players 89 self.players = players
90 self.user = user 90 self.player_nick = player_nick
91 self.bottom_nick = self.user 91 self.bottom_nick = self.player_nick
92 idx = self.players.index(self.user) 92 idx = self.players.index(self.player_nick)
93 idx = (idx + 1) % len(self.players) 93 idx = (idx + 1) % len(self.players)
94 self.right_nick = self.players[idx] 94 self.right_nick = self.players[idx]
95 idx = (idx + 1) % len(self.players) 95 idx = (idx + 1) % len(self.players)
96 self.top_nick = self.players[idx] 96 self.top_nick = self.players[idx]
97 idx = (idx + 1) % len(self.players) 97 idx = (idx + 1) % len(self.players)
98 self.left_nick = self.players[idx] 98 self.left_nick = self.players[idx]
99 self.SetMinSize(wx.Size(MIN_WIDTH, MIN_HEIGHT)) 99 self.SetMinSize(wx.Size(MIN_WIDTH, MIN_HEIGHT))
100 self.load_cards("/home/goffi/dev/divers/images/cards/") 100 self.load_cards("/home/goffi/dev/divers/images/cards/")
101 self.selected = None #contain the card to highlight 101 self.mouse_over_card = None #contain the card to highlight
102 self.selected = [] #Card choosed by the player (e.g. during ecart)
102 self.hand_size = 13 #number of cards in a hand 103 self.hand_size = 13 #number of cards in a hand
103 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards 104 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards
104 self.hand = [] 105 self.hand = []
105 self.my_turn = False 106 self.to_show = []
107 self.state = None
106 self.SetBackgroundColour(wx.GREEN) 108 self.SetBackgroundColour(wx.GREEN)
107 self.Bind(wx.EVT_SIZE, self.onResize) 109 self.Bind(wx.EVT_SIZE, self.onResize)
108 self.Bind(wx.EVT_PAINT, self.onPaint) 110 self.Bind(wx.EVT_PAINT, self.onPaint)
109 self.Bind(wx.EVT_MOTION, self.onMouseMove) 111 self.Bind(wx.EVT_MOTION, self.onMouseMove)
110 self.Bind(wx.EVT_LEFT_UP, self.onMouseClick) 112 self.Bind(wx.EVT_LEFT_UP, self.onMouseClick)
111 self.parent.host.bridge.tarotGameReady(user, referee, profile_key = self.parent.host.profile) 113 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile)
112 114
113 def load_cards(self, dir): 115 def load_cards(self, dir):
114 """Load all the cards in memory 116 """Load all the cards in memory
115 @param dir: directory where the PNG files are""" 117 @param dir: directory where the PNG files are"""
116 self.cards={} 118 self.cards={}
120 self.cards["coeur"]={} #heart 122 self.cards["coeur"]={} #heart
121 self.cards["carreau"]={} #diamond 123 self.cards["carreau"]={} #diamond
122 self.cards["trefle"]={} #club 124 self.cards["trefle"]={} #club
123 for file in glob.glob(dir+'/*_*.png'): 125 for file in glob.glob(dir+'/*_*.png'):
124 card = Card(file) 126 card = Card(file)
125 self.cards[card.family, card.value]=card 127 self.cards[card.suit, card.value]=card
126 self.deck.append(card) 128 self.deck.append(card)
127 """for value in map(str,range(1,22))+['excuse']: 129 """for value in map(str,range(1,22))+['excuse']:
128 self.idx_cards.append(self.cards["atout",value]) 130 self.idx_cards.append(self.cards["atout",value])
129 for family in ["pique", "coeur", "carreau", "trefle"]: 131 for suit in ["pique", "coeur", "carreau", "trefle"]:
130 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]: 132 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]:
131 self.idx_cards.append(self.cards[family, value])""" #XXX: no need to sort the cards ! 133 self.idx_cards.append(self.cards[suit, value])""" #XXX: no need to sort the cards !
132 134
133 def newGame(self, hand): 135 def newGame(self, hand):
134 """Start a new game, with given hand""" 136 """Start a new game, with given hand"""
135 print "gof: new game ici avec",hand
136 assert (len(self.hand) == 0) 137 assert (len(self.hand) == 0)
137 for family, value in hand: 138 for suit, value in hand:
138 self.hand.append(self.cards[family, value]) 139 self.hand.append(self.cards[suit, value])
139 self.hand.sort() 140 self.hand.sort()
140 self.my_turn = True 141 self.state = "init"
142 self._recalc_ori()
143 self.Refresh()
141 144
142 def contratSelected(self, data): 145 def contratSelected(self, data):
143 """Called when the contrat has been choosed 146 """Called when the contrat has been choosed
144 @param data: form result""" 147 @param data: form result"""
145 debug (_("Contrat choosed")) 148 debug (_("Contrat choosed"))
146 print "\n\n\n===============>>>> \o/ :) :) :) ", data, "\n\n\n"
147 contrat = data[0][1] 149 contrat = data[0][1]
148 self.parent.host.bridge.tarotGameContratChoosed(self.user, self.referee, contrat or 'Passe', self.parent.host.profile) 150 self.parent.host.bridge.tarotGameContratChoosed(self.player_nick, self.referee, contrat or 'Passe', self.parent.host.profile)
149 151
150 def chooseContrat(self, xml_data): 152 def chooseContrat(self, xml_data):
151 """Called when the player as to select hist contrat 153 """Called when the player as to select hist contrat
152 @param xml_data: SàT xml representation of the form""" 154 @param xml_data: SàT xml representation of the form"""
153 misc = {'callback': self.contratSelected} 155 misc = {'callback': self.contratSelected}
154 form = Form(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc) 156 form = Form(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc)
155 157
158 def showCards(self, game_stage, cards, data):
159 """Display cards in the middle of the game (to show for e.g. chien ou poignée)"""
160 self.to_show = []
161 for suit, value in cards:
162 self.to_show.append(self.cards[suit, value])
163 if game_stage == "chien" and data['attaquant'] == self.player_nick:
164 self.state = "wait_for_ecart"
165 else:
166 self.state = "chien"
167
168 def MyTurn(self):
169 """Called when we have to play :)"""
170 if self.state == "chien":
171 self.to_show = []
172 self.state="play"
156 173
157 def _is_on_hand(self, pos_x, pos_y): 174 def _is_on_hand(self, pos_x, pos_y):
158 """Return True if the coordinate are on the hand cards""" 175 """Return True if the coordinate are on the hand cards"""
159 if pos_x > self.orig_x and pos_y > self.orig_y \ 176 if pos_x > self.orig_x and pos_y > self.orig_y \
160 and pos_x < self.orig_x + (len(self.hand)+1) * self.visible_size \ 177 and pos_x < self.orig_x + (len(self.hand)+1) * self.visible_size \
164 181
165 def onResize(self, event): 182 def onResize(self, event):
166 self._recalc_ori() 183 self._recalc_ori()
167 184
168 def _recalc_ori(self): 185 def _recalc_ori(self):
169 """Recalculate origines, must be call when size change""" 186 """Recalculate origins of hand, must be call when hand size change"""
170 self.orig_x = (self.GetSizeTuple()[0]-(len(self.hand)+1)*self.visible_size)/2 #where we start to draw cards 187 self.orig_x = (self.GetSizeTuple()[0]-(len(self.hand)+1)*self.visible_size)/2 #where we start to draw cards
171 self.orig_y = self.GetSizeTuple()[1] - CARD_HEIGHT - 20 188 self.orig_y = self.GetSizeTuple()[1] - CARD_HEIGHT - 20
172 self.end_y = self.orig_y + CARD_HEIGHT 189 self.end_y = self.orig_y + CARD_HEIGHT
173 190
174 def onPaint(self, event): 191 def onPaint(self, event):
188 dc.DrawText(self.top_nick, top_x, top_y) 205 dc.DrawText(self.top_nick, top_x, top_y)
189 dc.DrawText(self.left_nick, left_x, left_y) 206 dc.DrawText(self.left_nick, left_x, left_y)
190 207
191 x=self.orig_x 208 x=self.orig_x
192 for card in self.hand: 209 for card in self.hand:
193 card.draw(dc,x,self.orig_y - 30 if self.my_turn and card == self.selected else self.orig_y) 210 if (self.state == "play" or self.state == "ecart") and card == self.mouse_over_card \
211 or self.state == "ecart" and card in self.selected:
212 y = self.orig_y - 30
213 else:
214 y = self.orig_y
215
216 card.draw(dc,x,y)
194 x+=self.visible_size 217 x+=self.visible_size
218
219 if self.to_show:
220 """There are cards to display in the middle"""
221 size = len(self.to_show)*(CARD_WIDTH+10)-10
222 x = (max_x - size)/2
223 for card in self.to_show:
224 card.draw(dc, x, 150)
225 x+=CARD_WIDTH+10
195 226
196 def onMouseMove(self, event): 227 def onMouseMove(self, event):
197 pos_x,pos_y = event.GetPosition() 228 pos_x,pos_y = event.GetPosition()
198 if self._is_on_hand(pos_x, pos_y): 229 if self._is_on_hand(pos_x, pos_y):
199 try: 230 try:
200 self.selected = self.hand[(pos_x-self.orig_x)/self.visible_size] 231 self.mouse_over_card = self.hand[(pos_x-self.orig_x)/self.visible_size]
201 except IndexError: 232 except IndexError:
202 self.selected = self.hand[-1] 233 self.mouse_over_card = self.hand[-1]
203 self.Refresh() 234 self.Refresh()
204 else: 235 else:
205 self.selected = None 236 self.mouse_over_card = None
206 self.Refresh() 237 self.Refresh()
207 238
208 def onMouseClick(self, event): 239 def onMouseClick(self, event):
209 print "mouse click:",event.GetPosition() 240 print "mouse click:",event.GetPosition()
210 pos_x,pos_y = event.GetPosition() 241 pos_x,pos_y = event.GetPosition()
242
243 if self.state == "chien":
244 self.to_show = []
245 self.state = "wait"
246 return
247 elif self.state == "wait_for_ecart":
248 self.state = "ecart"
249 self.hand.extend(self.to_show)
250 self.hand.sort()
251 self.to_show = []
252 self._recalc_ori()
253 self.Refresh()
254 return
255
211 if self._is_on_hand(pos_x, pos_y): 256 if self._is_on_hand(pos_x, pos_y):
212 idx = (pos_x-self.orig_x)/self.visible_size 257 idx = (pos_x-self.orig_x)/self.visible_size
213 if idx == len(self.hand): 258 if idx == len(self.hand):
214 idx-=1 259 idx-=1
215 if self.hand[idx] == self.selected: 260 if self.hand[idx] == self.mouse_over_card:
216 del self.hand[idx] 261 if self.state == "ecart":
217 self._recalc_ori() 262 if self.hand[idx] in self.selected:
218 self.Refresh() 263 self.selected.remove(self.hand[idx])
264 else:
265 self.selected.append(self.hand[idx])
266 if len(self.selected) == 6: #TODO: use variable here, as chien len can change with variants
267 dlg = wx.MessageDialog(self, _("Do you put these cards in chien ?"), _(u"Écart"), wx.YES_NO | wx.ICON_QUESTION)
268 answer = dlg.ShowModal()
269 if answer == wx.ID_YES:
270 ecart = []
271 for card in self.selected:
272 ecart.append((card.suit, card.value))
273 self.hand.remove(card)
274 print "gof: Cartes envoyes au chien:", ecart
275 del self.selected[:]
276 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, ecart, profile_key = self.parent.host.profile)
277 self.state = "wait"
278
279 self._recalc_ori()
280 self.Refresh()