comparison frontends/src/wix/card_game.py @ 223:86d249b6d9b7

Files reorganisation
author Goffi <goffi@goffi.org>
date Wed, 29 Dec 2010 01:06:29 +0100
parents frontends/wix/card_game.py@d55e56a55cad
children fd9b7834d98a
comparison
equal deleted inserted replaced
222:3198bfd66daa 223:86d249b6d9b7
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 """
5 wix: a SAT frontend
6 Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """
21
22
23
24 import wx
25 import os.path, glob
26 import pdb
27 from logging import debug, info, error
28 from tools.jid import JID
29 from tools.games import TarotCard
30 from quick_frontend.quick_card_game import QuickCardGame
31 from xmlui import XMLUI
32
33 CARD_WIDTH = 74
34 CARD_HEIGHT = 136
35 MIN_WIDTH = 950 #Minimum size of the panel
36 MIN_HEIGHT = 500
37
38 class WxCard(TarotCard):
39 """This class is used to represent a card, graphically and logically"""
40
41 def __init__(self, file):
42 """@param file: path of the PNG file"""
43 self.bitmap = wx.Image(file).ConvertToBitmap()
44 root_name = os.path.splitext(os.path.basename(file))[0]
45 suit,value = root_name.split('_')
46 TarotCard.__init__(self, (suit, value))
47 print "Carte:",suit, value #, self.bout
48
49 def draw(self, dc, x, y):
50 """Draw the card on the device context
51 @param dc: device context
52 @param x: abscissa
53 @param y: ordinate"""
54 dc.DrawBitmap(self.bitmap, x, y, True)
55
56
57 class CardPanel(QuickCardGame,wx.Panel):
58 """This class is used to display the cards"""
59
60 def __init__(self, parent, referee, players, player_nick):
61 QuickCardGame.__init__(self, parent, referee, players, player_nick)
62 wx.Panel.__init__(self, parent)
63 self.SetMinSize(wx.Size(MIN_WIDTH, MIN_HEIGHT))
64 self.loadCards("images/cards/")
65 self.mouse_over_card = None #contain the card to highlight
66 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards
67 self.hand = []
68 self.to_show = []
69 self.state = None
70 self.SetBackgroundColour(wx.GREEN)
71 self.Bind(wx.EVT_SIZE, self.onResize)
72 self.Bind(wx.EVT_PAINT, self.onPaint)
73 self.Bind(wx.EVT_MOTION, self.onMouseMove)
74 self.Bind(wx.EVT_LEFT_UP, self.onMouseClick)
75 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile)
76
77 def loadCards(self, dir):
78 """Load all the cards in memory
79 @param dir: directory where the PNG files are"""
80 QuickCardGame.loadCards(self)
81 for file in glob.glob(dir+'/*_*.png'):
82 card = WxCard(file)
83 self.cards[card.suit, card.value]=card
84 self.deck.append(card)
85
86 def newGame(self, hand):
87 """Start a new game, with given hand"""
88 QuickCardGame.newGame(self, hand)
89 self._recalc_ori()
90 self.Refresh()
91
92 def contratSelected(self, data):
93 """Called when the contrat has been choosed
94 @param data: form result"""
95 debug (_("Contrat choosed"))
96 contrat = data[0][1]
97 QuickCardGame.contratSelected(self, contrat)
98
99 def chooseContrat(self, xml_data):
100 """Called when the player as to select his contrat
101 @param xml_data: SàT xml representation of the form"""
102 misc = {'callback': self.contratSelected}
103 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc)
104
105 def showScores(self, xml_data, winners, loosers):
106 """Called when the player as to select hist contrat
107 @param xml_data: SàT xml representation of the form"""
108 form = XMLUI(self.parent.host, xml_data, title = _('You win \o/') if self.player_nick in winners else _('You loose :('), options = ['NO_CANCEL'])
109
110 def cardsPlayed(self, player, cards):
111 """A card has been played by player"""
112 QuickCardGame.cardsPlayed(self, player, cards)
113 self.Refresh()
114
115 def invalidCards(self, phase, played_cards, invalid_cards):
116 """Invalid cards have been played
117 @param phase: phase of the game
118 @param played_cards: all the cards played
119 @param invalid_cards: cards which are invalid"""
120 QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards)
121
122 self._recalc_ori()
123 self.Refresh()
124 if self._autoplay==None: #No dialog if there is autoplay
125 wx.MessageDialog(self, _("Cards played are invalid !"), _("Error"), wx.OK | wx.ICON_ERROR).ShowModal()
126
127 def _is_on_hand(self, pos_x, pos_y):
128 """Return True if the coordinate are on the hand cards"""
129 if pos_x > self.orig_x and pos_y > self.orig_y \
130 and pos_x < self.orig_x + (len(self.hand)+1) * self.visible_size \
131 and pos_y < self.end_y:
132 return True
133 return False
134
135 def onResize(self, event):
136 self._recalc_ori()
137
138 def _recalc_ori(self):
139 """Recalculate origins of hand, must be call when hand size change"""
140 self.orig_x = (self.GetSizeTuple()[0]-(len(self.hand)+1)*self.visible_size)/2 #where we start to draw cards
141 self.orig_y = self.GetSizeTuple()[1] - CARD_HEIGHT - 20
142 self.end_y = self.orig_y + CARD_HEIGHT
143
144 def onPaint(self, event):
145 dc = wx.PaintDC(self)
146
147 #We print the names to know who play where TODO: print avatars when available
148 max_x, max_y = self.GetSize()
149 border = 10 #border between nick and end of panel
150 right_y = left_y = 200
151 right_width, right_height = dc.GetTextExtent(self.right_nick)
152 right_x = max_x - right_width - border
153 left_x = border
154 top_width, top_height = dc.GetTextExtent(self.top_nick)
155 top_x = (max_x - top_width) / 2
156 top_y = border
157 dc.DrawText(self.right_nick, right_x, right_y)
158 dc.DrawText(self.top_nick, top_x, top_y)
159 dc.DrawText(self.left_nick, left_x, left_y)
160
161 #We draw the played cards:
162 center_y = 200 #ordinate used as center point
163 left_x = (max_x - CARD_WIDTH)/2 - CARD_WIDTH - 5
164 right_x = (max_x/2) + (CARD_WIDTH/2) + 5
165 left_y = right_y = center_y - CARD_HEIGHT/2
166 top_x = bottom_x = (max_x - CARD_WIDTH)/2
167 top_y = center_y - CARD_HEIGHT - 5
168 bottom_y = center_y + 5
169 for side in ['left', 'top', 'right', 'bottom']:
170 card = self.played[getattr(self, side+'_nick')]
171 if card != None:
172 card.draw(dc,locals()[side+'_x'], locals()[side+'_y'])
173
174 x=self.orig_x
175 for card in self.hand:
176 if (self.state == "play" or self.state == "ecart") and card == self.mouse_over_card \
177 or self.state == "ecart" and card in self.selected:
178 y = self.orig_y - 30
179 else:
180 y = self.orig_y
181
182 card.draw(dc,x,y)
183 x+=self.visible_size
184
185 if self.to_show:
186 """There are cards to display in the middle"""
187 size = len(self.to_show)*(CARD_WIDTH+10)-10
188 x = (max_x - size)/2
189 for card in self.to_show:
190 card.draw(dc, x, 150)
191 x+=CARD_WIDTH+10
192
193 def onMouseMove(self, event):
194 pos_x,pos_y = event.GetPosition()
195 if self._is_on_hand(pos_x, pos_y):
196 try:
197 self.mouse_over_card = self.hand[(pos_x-self.orig_x)/self.visible_size]
198 except IndexError:
199 self.mouse_over_card = self.hand[-1]
200 self.Refresh()
201 else:
202 self.mouse_over_card = None
203 self.Refresh()
204
205 def onMouseClick(self, event):
206 print "mouse click:",event.GetPosition()
207 pos_x,pos_y = event.GetPosition()
208
209 if self.state == "chien":
210 self.to_show = []
211 self.state = "wait"
212 return
213 elif self.state == "wait_for_ecart":
214 self.state = "ecart"
215 self.hand.extend(self.to_show)
216 self.hand.sort()
217 self.to_show = []
218 self._recalc_ori()
219 self.Refresh()
220 return
221
222 if self._is_on_hand(pos_x, pos_y):
223 idx = (pos_x-self.orig_x)/self.visible_size
224 if idx == len(self.hand):
225 idx-=1
226 if self.hand[idx] == self.mouse_over_card:
227 if self.state == "ecart":
228 if self.hand[idx] in self.selected:
229 self.selected.remove(self.hand[idx])
230 else:
231 self.selected.append(self.hand[idx])
232 if len(self.selected) == 6: #TODO: use variable here, as chien len can change with variants
233 dlg = wx.MessageDialog(self, _("Do you put these cards in chien ?"), _(u"Écart"), wx.YES_NO | wx.ICON_QUESTION)
234 answer = dlg.ShowModal()
235 if answer == wx.ID_YES:
236 ecart = []
237 for card in self.selected:
238 ecart.append((card.suit, card.value))
239 self.hand.remove(card)
240 del self.selected[:]
241 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, ecart, profile_key = self.parent.host.profile)
242 self.state = "wait"
243
244 self._recalc_ori()
245 self.Refresh()
246 if self.state == "play":
247 card = self.hand[idx]
248 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, [(card.suit, card.value)], profile_key = self.parent.host.profile)
249 del self.hand[idx]
250 self.state = "wait"
251 self._recalc_ori()
252 self.Refresh()
253
254