comparison browser_side/card_game.py @ 243:63e9b680d3e7

browser_side, blog: better PEP8 compliance
author souliane <souliane@mailoo.org>
date Tue, 15 Oct 2013 17:19:03 +0200
parents dec76d4536ad
children 8fdd20399a06
comparison
equal deleted inserted replaced
242:a25aa882e09a 243:63e9b680d3e7
17 17
18 You should have received a copy of the GNU Affero General Public License 18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """ 20 """
21 21
22 import pyjd # this is dummy in pyjs 22 import pyjd # this is dummy in pyjs
23 from pyjamas.ui.AbsolutePanel import AbsolutePanel 23 from pyjamas.ui.AbsolutePanel import AbsolutePanel
24 from pyjamas.ui.VerticalPanel import VerticalPanel 24 from pyjamas.ui.VerticalPanel import VerticalPanel
25 from pyjamas.ui.HorizontalPanel import HorizontalPanel 25 from pyjamas.ui.HorizontalPanel import HorizontalPanel
26 from pyjamas.ui.DockPanel import DockPanel 26 from pyjamas.ui.DockPanel import DockPanel
27 from pyjamas.ui.SimplePanel import SimplePanel 27 from pyjamas.ui.SimplePanel import SimplePanel
41 from dialog import ConfirmDialog, InfoDialog 41 from dialog import ConfirmDialog, InfoDialog
42 from tools import html_sanitize 42 from tools import html_sanitize
43 from datetime import datetime 43 from datetime import datetime
44 from time import time 44 from time import time
45 from games import TarotCard 45 from games import TarotCard
46 from logging import error
46 import re 47 import re
47
48 48
49 49
50 CARD_WIDTH = 74 50 CARD_WIDTH = 74
51 CARD_HEIGHT = 136 51 CARD_HEIGHT = 136
52 CARD_DELTA_Y = 30 52 CARD_DELTA_Y = 30
53 MIN_WIDTH = 950 #Minimum size of the panel 53 MIN_WIDTH = 950 # Minimum size of the panel
54 MIN_HEIGHT = 500 54 MIN_HEIGHT = 500
55
55 56
56 class ContratChooser(DialogBox): 57 class ContratChooser(DialogBox):
57 58
58 def __init__(self, parent): 59 def __init__(self, parent):
59 """ 60 """
76 button_panel.addStyleName("marginAuto") 77 button_panel.addStyleName("marginAuto")
77 self.choose_button = Button("Choose", self.onChoose) 78 self.choose_button = Button("Choose", self.onChoose)
78 button_panel.add(self.choose_button) 79 button_panel.add(self.choose_button)
79 content.add(button_panel) 80 content.add(button_panel)
80 self.setHTML("Please select your contrat") 81 self.setHTML("Please select your contrat")
81 self.setWidget(content) 82 self.setWidget(content)
82 83
83 def onChoose(self, button): 84 def onChoose(self, button):
84 self.hide() 85 self.hide()
85 self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0]) 86 self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0])
86 87
88
87 class CardWidget(TarotCard, Image, MouseHandler): 89 class CardWidget(TarotCard, Image, MouseHandler):
88 """This class is used to represent a card, graphically and logically""" 90 """This class is used to represent a card, graphically and logically"""
89 91
90 def __init__(self, parent, file): 92 def __init__(self, parent, file_):
91 """@param file: path of the PNG file""" 93 """@param file: path of the PNG file"""
92 self._parent = parent 94 self._parent = parent
93 Image.__init__(self,file) 95 Image.__init__(self, file_)
94 root_name = file[file.rfind("/")+1:-4] 96 root_name = file_[file_.rfind("/") + 1:-4]
95 suit,value = root_name.split('_') 97 suit, value = root_name.split('_')
96 TarotCard.__init__(self, (suit, value)) 98 TarotCard.__init__(self, (suit, value))
97 MouseHandler.__init__(self) 99 MouseHandler.__init__(self)
98 self.addMouseListener(self) 100 self.addMouseListener(self)
99 101
100 def onMouseEnter(self, sender): 102 def onMouseEnter(self, sender):
102 DOM.setStyleAttribute(self.getElement(), "top", "0px") 104 DOM.setStyleAttribute(self.getElement(), "top", "0px")
103 105
104 def onMouseLeave(self, sender): 106 def onMouseLeave(self, sender):
105 if not self in self._parent.hand: 107 if not self in self._parent.hand:
106 return 108 return
107 if not self in list(self._parent.selected): #FIXME: Workaround pyjs bug, must report it 109 if not self in list(self._parent.selected): # FIXME: Workaround pyjs bug, must report it
108 DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y) 110 DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y)
109 111
110 def onMouseUp(self, sender, x, y): 112 def onMouseUp(self, sender, x, y):
111 if self._parent.state == "ecart": 113 if self._parent.state == "ecart":
112 if self not in list(self._parent.selected): 114 if self not in list(self._parent.selected):
114 else: 116 else:
115 self._parent.removeFromSelection(self) 117 self._parent.removeFromSelection(self)
116 elif self._parent.state == "play": 118 elif self._parent.state == "play":
117 self._parent.playCard(self) 119 self._parent.playCard(self)
118 120
121
119 class CardPanel(DockPanel, ClickHandler): 122 class CardPanel(DockPanel, ClickHandler):
120 123
121 def __init__(self, parent, referee, players, player_nick): 124 def __init__(self, parent, referee, players, player_nick):
122 DockPanel.__init__(self) 125 DockPanel.__init__(self)
123 ClickHandler.__init__(self) 126 ClickHandler.__init__(self)
124 self._parent = parent 127 self._parent = parent
125 self._autoplay = None #XXX: use 0 to activate fake play, None else 128 self._autoplay = None # XXX: use 0 to activate fake play, None else
126 self.referee = referee 129 self.referee = referee
127 self.players = players 130 self.players = players
128 self.player_nick = player_nick 131 self.player_nick = player_nick
129 self.bottom_nick = self.player_nick 132 self.bottom_nick = self.player_nick
130 idx = self.players.index(self.player_nick) 133 idx = self.players.index(self.player_nick)
133 idx = (idx + 1) % len(self.players) 136 idx = (idx + 1) % len(self.players)
134 self.top_nick = self.players[idx] 137 self.top_nick = self.players[idx]
135 idx = (idx + 1) % len(self.players) 138 idx = (idx + 1) % len(self.players)
136 self.left_nick = self.players[idx] 139 self.left_nick = self.players[idx]
137 self.bottom_nick = player_nick 140 self.bottom_nick = player_nick
138 self.selected = set() #Card choosed by the player (e.g. during ecart) 141 self.selected = set() # Card choosed by the player (e.g. during ecart)
139 self.hand_size = 13 #number of cards in a hand 142 self.hand_size = 13 # number of cards in a hand
140 self.hand = [] 143 self.hand = []
141 self.to_show = [] 144 self.to_show = []
142 self.state = None 145 self.state = None
143 self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT) 146 self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT)
144 self.setStyleName("cardPanel") 147 self.setStyleName("cardPanel")
145 148
146 # Now we set up the layout 149 # Now we set up the layout
147 _label = Label(self.top_nick) 150 _label = Label(self.top_nick)
148 _label.setStyleName('cardGamePlayerNick') 151 _label.setStyleName('cardGamePlayerNick')
149 self.add(_label, DockPanel.NORTH) 152 self.add(_label, DockPanel.NORTH)
150 self.setCellWidth(_label, '100%') 153 self.setCellWidth(_label, '100%')
151 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_CENTER) 154 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_CENTER)
152 155
153
154 self.hand_panel = AbsolutePanel() 156 self.hand_panel = AbsolutePanel()
155 self.add(self.hand_panel, DockPanel.SOUTH) 157 self.add(self.hand_panel, DockPanel.SOUTH)
156 self.setCellWidth(self.hand_panel, '100%') 158 self.setCellWidth(self.hand_panel, '100%')
157 self.setCellHorizontalAlignment(self.hand_panel, HasAlignment.ALIGN_CENTER) 159 self.setCellHorizontalAlignment(self.hand_panel, HasAlignment.ALIGN_CENTER)
158 160
159
160 _label = Label(self.left_nick) 161 _label = Label(self.left_nick)
161 _label.setStyleName('cardGamePlayerNick') 162 _label.setStyleName('cardGamePlayerNick')
162 self.add(_label, DockPanel.WEST) 163 self.add(_label, DockPanel.WEST)
163 self.setCellHeight(_label, '100%') 164 self.setCellHeight(_label, '100%')
164 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 165 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE)
165
166 166
167 _label = Label(self.right_nick) 167 _label = Label(self.right_nick)
168 _label.setStyleName('cardGamePlayerNick') 168 _label.setStyleName('cardGamePlayerNick')
169 self.add(_label, DockPanel.EAST) 169 self.add(_label, DockPanel.EAST)
170 self.setCellHeight(_label, '100%') 170 self.setCellHeight(_label, '100%')
171 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT) 171 self.setCellHorizontalAlignment(_label, HasAlignment.ALIGN_RIGHT)
172 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 172 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE)
173
174 173
175 self.center_panel = DockPanel() 174 self.center_panel = DockPanel()
176 self.inner_left = SimplePanel() 175 self.inner_left = SimplePanel()
177 self.inner_left.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) 176 self.inner_left.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
178 self.center_panel.add(self.inner_left, DockPanel.WEST) 177 self.center_panel.add(self.inner_left, DockPanel.WEST)
183 self.inner_right = SimplePanel() 182 self.inner_right = SimplePanel()
184 self.inner_right.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) 183 self.inner_right.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
185 self.center_panel.add(self.inner_right, DockPanel.EAST) 184 self.center_panel.add(self.inner_right, DockPanel.EAST)
186 self.center_panel.setCellHeight(self.inner_right, '100%') 185 self.center_panel.setCellHeight(self.inner_right, '100%')
187 self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE) 186 self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE)
188 187
189 self.inner_top = SimplePanel() 188 self.inner_top = SimplePanel()
190 self.inner_top.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) 189 self.inner_top.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
191 self.center_panel.add(self.inner_top, DockPanel.NORTH) 190 self.center_panel.add(self.inner_top, DockPanel.NORTH)
192 self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER) 191 self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER)
193 self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM) 192 self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM)
194 193
195 self.inner_bottom = SimplePanel() 194 self.inner_bottom = SimplePanel()
196 self.inner_bottom.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) 195 self.inner_bottom.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
197 self.center_panel.add(self.inner_bottom, DockPanel.SOUTH) 196 self.center_panel.add(self.inner_bottom, DockPanel.SOUTH)
198 self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER) 197 self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER)
199 self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP) 198 self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP)
200 199
201 self.inner_center = SimplePanel() 200 self.inner_center = SimplePanel()
202 self.center_panel.add(self.inner_center, DockPanel.CENTER) 201 self.center_panel.add(self.inner_center, DockPanel.CENTER)
203 self.center_panel.setCellHorizontalAlignment(self.inner_center, HasAlignment.ALIGN_CENTER) 202 self.center_panel.setCellHorizontalAlignment(self.inner_center, HasAlignment.ALIGN_CENTER)
204 self.center_panel.setCellVerticalAlignment(self.inner_center, HasAlignment.ALIGN_MIDDLE) 203 self.center_panel.setCellVerticalAlignment(self.inner_center, HasAlignment.ALIGN_MIDDLE)
205 204
208 self.setCellHeight(self.center_panel, '100%') 207 self.setCellHeight(self.center_panel, '100%')
209 self.setCellVerticalAlignment(self.center_panel, HasAlignment.ALIGN_MIDDLE) 208 self.setCellVerticalAlignment(self.center_panel, HasAlignment.ALIGN_MIDDLE)
210 self.setCellHorizontalAlignment(self.center_panel, HasAlignment.ALIGN_CENTER) 209 self.setCellHorizontalAlignment(self.center_panel, HasAlignment.ALIGN_CENTER)
211 210
212 self.loadCards() 211 self.loadCards()
213 self.mouse_over_card = None #contain the card to highlight 212 self.mouse_over_card = None # contain the card to highlight
214 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards 213 self.visible_size = CARD_WIDTH / 2 # number of pixels visible for cards
215 self.addClickListener(self) 214 self.addClickListener(self)
216
217 215
218 def loadCards(self): 216 def loadCards(self):
219 """Load all the cards in memory""" 217 """Load all the cards in memory"""
220 def _getTarotCardsPathsCb(paths): 218 def _getTarotCardsPathsCb(paths):
221 print "_getTarotCardsPathsCb" 219 print "_getTarotCardsPathsCb"
222 for file in paths: 220 for file_ in paths:
223 print "path:", file 221 print "path:", file_
224 card = CardWidget(self, file) 222 card = CardWidget(self, file_)
225 print "card:", card 223 print "card:", card
226 self.cards[(card.suit, card.value)]=card 224 self.cards[(card.suit, card.value)] = card
227 self.deck.append(card) 225 self.deck.append(card)
228 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) 226 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee)
229 self.cards={} 227 self.cards = {}
230 self.deck=[] 228 self.deck = []
231 self.cards["atout"]={} #As Tarot is a french game, it's more handy & logical to keep french names 229 self.cards["atout"] = {} # As Tarot is a french game, it's more handy & logical to keep french names
232 self.cards["pique"]={} #spade 230 self.cards["pique"] = {} # spade
233 self.cards["coeur"]={} #heart 231 self.cards["coeur"] = {} # heart
234 self.cards["carreau"]={} #diamond 232 self.cards["carreau"] = {} # diamond
235 self.cards["trefle"]={} #club 233 self.cards["trefle"] = {} # club
236 self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb) 234 self._parent.host.bridge.call('getTarotCardsPaths', _getTarotCardsPathsCb)
237 235
238 def onClick(self, sender): 236 def onClick(self, sender):
239 if self.state == "chien": 237 if self.state == "chien":
240 self.to_show = [] 238 self.to_show = []
257 self.updateHand() 255 self.updateHand()
258 256
259 def updateHand(self): 257 def updateHand(self):
260 """Show the cards in the hand in the hand_panel (SOUTH panel)""" 258 """Show the cards in the hand in the hand_panel (SOUTH panel)"""
261 self.hand_panel.clear() 259 self.hand_panel.clear()
262 self.hand_panel.setSize("%dpx" % (self.visible_size * (len(self.hand)+1)), "%dpx" % (CARD_HEIGHT + CARD_DELTA_Y + 10)) 260 self.hand_panel.setSize("%dpx" % (self.visible_size * (len(self.hand) + 1)), "%dpx" % (CARD_HEIGHT + CARD_DELTA_Y + 10))
263 x_pos = 0 261 x_pos = 0
264 y_pos = CARD_DELTA_Y 262 y_pos = CARD_DELTA_Y
265 for card in self.hand: 263 for card in self.hand:
266 self.hand_panel.add(card, x_pos, y_pos) 264 self.hand_panel.add(card, x_pos, y_pos)
267 x_pos+=self.visible_size 265 x_pos += self.visible_size
268 266
269 def updateToShow(self): 267 def updateToShow(self):
270 """Show cards in the center panel""" 268 """Show cards in the center panel"""
271 if not self.to_show: 269 if not self.to_show:
272 _widget = self.inner_center.getWidget() 270 _widget = self.inner_center.getWidget()
273 if _widget: 271 if _widget:
274 self.inner_center.remove(_widget) 272 self.inner_center.remove(_widget)
275 return 273 return
276 panel = AbsolutePanel() 274 panel = AbsolutePanel()
277 panel.setSize("%dpx" % ((CARD_WIDTH + 5) * len(self.to_show) - 5), "%dpx" % (CARD_HEIGHT)) 275 panel.setSize("%dpx" % ((CARD_WIDTH + 5) * len(self.to_show) - 5), "%dpx" % (CARD_HEIGHT))
278 x_pos = 0 276 x_pos = 0
279 y_pos = 0 277 y_pos = 0
280 for card in self.to_show: 278 for card in self.to_show:
281 panel.add(card, x_pos, y_pos) 279 panel.add(card, x_pos, y_pos)
282 x_pos+=CARD_WIDTH + 5 280 x_pos += CARD_WIDTH + 5
283 self.inner_center.setWidget(panel) 281 self.inner_center.setWidget(panel)
284 282
285 def _ecartConfirm(self, confirm): 283 def _ecartConfirm(self, confirm):
286 if not confirm: 284 if not confirm:
287 return 285 return
291 self.hand.remove(card) 289 self.hand.remove(card)
292 self.selected.clear() 290 self.selected.clear()
293 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, ecart) 291 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, ecart)
294 self.state = "wait" 292 self.state = "wait"
295 self.updateHand() 293 self.updateHand()
296 294
297 def addToSelection(self, card): 295 def addToSelection(self, card):
298 self.selected.add(card) 296 self.selected.add(card)
299 if len(self.selected) == 6: 297 if len(self.selected) == 6:
300 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show() 298 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show()
301 299
308 if phase == "play": 306 if phase == "play":
309 self.state = "play" 307 self.state = "play"
310 elif phase == "ecart": 308 elif phase == "ecart":
311 self.state = "ecart" 309 self.state = "ecart"
312 else: 310 else:
313 error ('INTERNAL ERROR: unmanaged game phase') 311 error('INTERNAL ERROR: unmanaged game phase')
314 312
315 for suit, value in played_cards: 313 for suit, value in played_cards:
316 self.hand.append(self.cards[(suit, value)]) 314 self.hand.append(self.cards[(suit, value)])
317 315
318 self.hand.sort() 316 self.hand.sort()
319 self.updateHand() 317 self.updateHand()
320 Window.alert('Cards played are invalid !') 318 Window.alert('Cards played are invalid !')
321 319
322 def removeFromSelection(self, card): 320 def removeFromSelection(self, card):
348 else: 346 else:
349 self.state = "chien" 347 self.state = "chien"
350 348
351 def getPlayerLocation(self, nick): 349 def getPlayerLocation(self, nick):
352 """return player location (top,bottom,left or right)""" 350 """return player location (top,bottom,left or right)"""
353 for location in ['top','left','bottom','right']: 351 for location in ['top', 'left', 'bottom', 'right']:
354 if getattr(self,'%s_nick' % location) == nick: 352 if getattr(self, '%s_nick' % location) == nick:
355 return location 353 return location
356 print ("ERROR: This line should not be reached") 354 print ("ERROR: This line should not be reached")
357 355
358 def tarotGameCardsPlayed(self, player, cards): 356 def tarotGameCardsPlayed(self, player, cards):
359 """A card has been played by player""" 357 """A card has been played by player"""
369 player_pos = self.getPlayerLocation(player) 367 player_pos = self.getPlayerLocation(player)
370 player_panel = getattr(self, "inner_%s" % player_pos) 368 player_panel = getattr(self, "inner_%s" % player_pos)
371 369
372 if player_panel.getWidget() != None: 370 if player_panel.getWidget() != None:
373 #We have already cards on the table, we remove them 371 #We have already cards on the table, we remove them
374 for pos in ['top','left','bottom','right']: 372 for pos in ['top', 'left', 'bottom', 'right']:
375 getattr(self, "inner_%s" % pos).setWidget(None) 373 getattr(self, "inner_%s" % pos).setWidget(None)
376 374
377 card = self.cards[(suit, value)] 375 card = self.cards[(suit, value)]
378 DOM.setElemAttribute(card.getElement(), "style", "") 376 DOM.setElemAttribute(card.getElement(), "style", "")
379 player_panel.setWidget(card) 377 player_panel.setWidget(card)
380 378
381 def tarotGameYourTurn(self): 379 def tarotGameYourTurn(self):
382 """Called when we have to play :)""" 380 """Called when we have to play :)"""
383 if self.state == "chien": 381 if self.state == "chien":
384 self.to_show = [] 382 self.to_show = []
385 self.updateToShow() 383 self.updateToShow()
402 self.state = None 400 self.state = None
403 #empty hand 401 #empty hand
404 self.updateHand() 402 self.updateHand()
405 #nothing on the table 403 #nothing on the table
406 self.updateToShow() 404 self.updateToShow()
407 for pos in ['top','left','bottom','right']: 405 for pos in ['top', 'left', 'bottom', 'right']:
408 getattr(self, "inner_%s" % pos).setWidget(None) 406 getattr(self, "inner_%s" % pos).setWidget(None)
409 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) 407 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee)
410 408
411 if not winners and not loosers: 409 if not winners and not loosers:
412 title = "Draw game" 410 title = "Draw game"
413 else: 411 else:
414 if self.player_nick in winners: 412 if self.player_nick in winners:
415 title = "You <b>win</b> !" 413 title = "You <b>win</b> !"
416 else: 414 else:
417 title = "You <b>loose</b> :(" 415 title = "You <b>loose</b> :("
418 body = re.sub(r'<.*?>',lambda x:'<br />' if '/elem' in x.group(0) else '', xml_data) #Q&D conversion to simple HTML text 416 body = re.sub(r'<.*?>', lambda x: '<br />' if '/elem' in x.group(0) else '', xml_data) # Q&D conversion to simple HTML text
419 InfoDialog(title, body, _new_game).show() 417 InfoDialog(title, body, _new_game).show()