comparison browser_side/card_game.py @ 39:305e81c7a32c

Tarot game: a game can now be finished
author Goffi <goffi@goffi.org>
date Sun, 22 May 2011 00:15:01 +0200
parents 7bea2ae0c4fb
children 7782a786b2f0
comparison
equal deleted inserted replaced
38:7bea2ae0c4fb 39:305e81c7a32c
37 from pyjamas import DOM 37 from pyjamas import DOM
38 38
39 from pyjamas.dnd import makeDraggable 39 from pyjamas.dnd import makeDraggable
40 from pyjamas.ui.DragWidget import DragWidget, DragContainer 40 from pyjamas.ui.DragWidget import DragWidget, DragContainer
41 from jid import JID 41 from jid import JID
42 from dialog import ConfirmDialog
42 from tools import html_sanitize 43 from tools import html_sanitize
43 from datetime import datetime 44 from datetime import datetime
44 from time import time 45 from time import time
45 from games import TarotCard 46 from games import TarotCard
46 47
47 48
48 49
49 CARD_WIDTH = 74 50 CARD_WIDTH = 74
50 CARD_HEIGHT = 136 51 CARD_HEIGHT = 136
51 CARD_DELTA_Y = 10 52 CARD_DELTA_Y = 30
52 MIN_WIDTH = 950 #Minimum size of the panel 53 MIN_WIDTH = 950 #Minimum size of the panel
53 MIN_HEIGHT = 500 54 MIN_HEIGHT = 500
54 55
55 class ContratChooser(DialogBox): 56 class ContratChooser(DialogBox):
56 57
94 TarotCard.__init__(self, (suit, value)) 95 TarotCard.__init__(self, (suit, value))
95 MouseHandler.__init__(self) 96 MouseHandler.__init__(self)
96 self.addMouseListener(self) 97 self.addMouseListener(self)
97 98
98 def onMouseEnter(self, sender): 99 def onMouseEnter(self, sender):
100 if self._parent.state == "ecart" or self._parent.state == "play":
101 DOM.setStyleAttribute(self.getElement(), "top", "0px")
102
103 def onMouseLeave(self, sender):
104 if not self in self._parent.hand:
105 return
106 if not self in list(self._parent.selected): #FIXME: Workaround pyjs bug, must report it
107 DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y)
108
109 def onMouseUp(self, sender, x, y):
99 if self._parent.state == "ecart": 110 if self._parent.state == "ecart":
100 DOM.setStyleAttribute(self.getElement(), "top", "0px") 111 if self not in list(self._parent.selected):
101 112 self._parent.addToSelection(self)
102 def onMouseLeave(self, sender): 113 else:
103 DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y) 114 self._parent.removeFromSelection(self)
115 elif self._parent.state == "play":
116 self._parent.playCard(self)
104 117
105 class CardPanel(DockPanel, ClickHandler): 118 class CardPanel(DockPanel, ClickHandler):
106 119
107 def __init__(self, parent, referee, players, player_nick): 120 def __init__(self, parent, referee, players, player_nick):
108 DockPanel.__init__(self) 121 DockPanel.__init__(self)
122 idx = (idx + 1) % len(self.players) 135 idx = (idx + 1) % len(self.players)
123 self.top_nick = self.players[idx] 136 self.top_nick = self.players[idx]
124 idx = (idx + 1) % len(self.players) 137 idx = (idx + 1) % len(self.players)
125 self.left_nick = self.players[idx] 138 self.left_nick = self.players[idx]
126 self.bottom_nick = player_nick 139 self.bottom_nick = player_nick
127 self.selected = [] #Card choosed by the player (e.g. during ecart) 140 self.selected = set() #Card choosed by the player (e.g. during ecart)
128 self.hand_size = 13 #number of cards in a hand 141 self.hand_size = 13 #number of cards in a hand
129 self.hand = [] 142 self.hand = []
130 self.to_show = [] 143 self.to_show = []
131 self.state = None 144 self.state = None
132 self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT) 145 self.setSize("%dpx" % MIN_WIDTH, "%dpx" % MIN_HEIGHT)
161 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE) 174 self.setCellVerticalAlignment(_label, HasAlignment.ALIGN_MIDDLE)
162 175
163 176
164 self.center_panel = DockPanel() 177 self.center_panel = DockPanel()
165 self.inner_left = SimplePanel() 178 self.inner_left = SimplePanel()
179 self.inner_left.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
166 self.center_panel.add(self.inner_left, DockPanel.WEST) 180 self.center_panel.add(self.inner_left, DockPanel.WEST)
167 self.center_panel.setCellHeight(self.inner_left, '100%') 181 self.center_panel.setCellHeight(self.inner_left, '100%')
168 self.center_panel.setCellHorizontalAlignment(self.inner_left, HasAlignment.ALIGN_RIGHT) 182 self.center_panel.setCellHorizontalAlignment(self.inner_left, HasAlignment.ALIGN_RIGHT)
169 self.center_panel.setCellVerticalAlignment(self.inner_left, HasAlignment.ALIGN_MIDDLE) 183 self.center_panel.setCellVerticalAlignment(self.inner_left, HasAlignment.ALIGN_MIDDLE)
170 184
171 self.inner_right = SimplePanel() 185 self.inner_right = SimplePanel()
186 self.inner_right.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
172 self.center_panel.add(self.inner_right, DockPanel.EAST) 187 self.center_panel.add(self.inner_right, DockPanel.EAST)
173 self.center_panel.setCellHeight(self.inner_right, '100%') 188 self.center_panel.setCellHeight(self.inner_right, '100%')
174 self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE) 189 self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE)
175 190
176 self.inner_top = SimplePanel() 191 self.inner_top = SimplePanel()
192 self.inner_top.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
177 self.center_panel.add(self.inner_top, DockPanel.NORTH) 193 self.center_panel.add(self.inner_top, DockPanel.NORTH)
178 self.center_panel.setCellWidth(self.inner_top, '100%')
179 self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER) 194 self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER)
180 self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM) 195 self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM)
181 196
182 self.inner_bottom = SimplePanel() 197 self.inner_bottom = SimplePanel()
198 self.inner_bottom.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT)
183 self.center_panel.add(self.inner_bottom, DockPanel.SOUTH) 199 self.center_panel.add(self.inner_bottom, DockPanel.SOUTH)
184 self.center_panel.setCellWidth(self.inner_bottom, '100%')
185 self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER) 200 self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER)
186 self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP) 201 self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP)
187 202
188 self.inner_center = SimplePanel() 203 self.inner_center = SimplePanel()
189 self.center_panel.add(self.inner_center, DockPanel.CENTER) 204 self.center_panel.add(self.inner_center, DockPanel.CENTER)
272 for card in self.to_show: 287 for card in self.to_show:
273 panel.add(card, x_pos, y_pos) 288 panel.add(card, x_pos, y_pos)
274 x_pos+=CARD_WIDTH + 5 289 x_pos+=CARD_WIDTH + 5
275 self.inner_center.setWidget(panel) 290 self.inner_center.setWidget(panel)
276 291
292 def _ecartConfirm(self, confirm):
293 if not confirm:
294 return
295 ecart = []
296 for card in self.selected:
297 ecart.append((card.suit, card.value))
298 self.hand.remove(card)
299 self.selected.clear()
300 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, ecart)
301 self.state = "wait"
302 self.updateHand()
303
304 def addToSelection(self, card):
305 self.selected.add(card)
306 if len(self.selected) == 6:
307 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show()
308
309 def tarotGameInvalidCards(self, phase, played_cards, invalid_cards):
310 """Invalid cards have been played
311 @param phase: phase of the game
312 @param played_cards: all the cards played
313 @param invalid_cards: cards which are invalid"""
314
315 if phase == "play":
316 self.state = "play"
317 elif phase == "ecart":
318 self.state = "ecart"
319 else:
320 error ('INTERNAL ERROR: unmanaged game phase')
321
322 for suit, value in played_cards:
323 self.hand.append(self.cards[(suit, value)])
324
325 self.hand.sort()
326 self.updateHand()
327 Window.alert('Cards played are invalid !')
328
329 def removeFromSelection(self, card):
330 self.selected.remove(card)
331 if len(self.selected) == 6:
332 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show()
277 333
278 def tarotGameChooseContrat(self, xml_data): 334 def tarotGameChooseContrat(self, xml_data):
279 """Called when the player as to select his contrat 335 """Called when the player as to select his contrat
280 @param xml_data: SàT xml representation of the form""" 336 @param xml_data: SàT xml representation of the form"""
281 #for the moment we cheat a little bit and make our own dialog box 337 #for the moment we cheat a little bit and make our own dialog box
284 contrat_chooser.show() 340 contrat_chooser.show()
285 341
286 def contratSelected(self, contrat): 342 def contratSelected(self, contrat):
287 """Must be called when the contrat is selected 343 """Must be called when the contrat is selected
288 @param contrat: one of the valid contrat value""" 344 @param contrat: one of the valid contrat value"""
289 print "Contrat choosed:", contrat
290 self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe') 345 self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe')
291
292
293 346
294 def tarotGameShowCards(self, game_stage, cards, data): 347 def tarotGameShowCards(self, game_stage, cards, data):
295 """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" 348 """Display cards in the middle of the game (to show for e.g. chien ou poignée)"""
296 self.to_show = [] 349 self.to_show = []
297 for suit, value in cards: 350 for suit, value in cards:
300 if game_stage == "chien" and data['attaquant'] == self.player_nick: 353 if game_stage == "chien" and data['attaquant'] == self.player_nick:
301 self.state = "wait_for_ecart" 354 self.state = "wait_for_ecart"
302 else: 355 else:
303 self.state = "chien" 356 self.state = "chien"
304 357
358 def getPlayerLocation(self, nick):
359 """return player location (top,bottom,left or right)"""
360 for location in ['top','left','bottom','right']:
361 if getattr(self,'%s_nick' % location) == nick:
362 return location
363 print ("ERROR: This line should not be reached")
364
365 def tarotGameCardsPlayed(self, player, cards):
366 """A card has been played by player"""
367 if not len(cards):
368 print ("WARNING: cards should not be empty")
369 return
370 if len(cards) > 1:
371 print ("ERROR: can't manage several cards played")
372 if self.to_show:
373 self.to_show = []
374 self.updateToShow()
375 suit, value = cards[0]
376 player_pos = self.getPlayerLocation(player)
377 player_panel = getattr(self, "inner_%s" % player_pos)
378
379 if player_panel.getWidget() != None:
380 #We have already cards on the table, we remove them
381 for pos in ['top','left','bottom','right']:
382 getattr(self, "inner_%s" % pos).setWidget(None)
383
384 card = self.cards[(suit, value)]
385 DOM.setElemAttribute(card.getElement(), "style", "")
386 player_panel.setWidget(card)
387
388 def tarotGameYourTurn(self):
389 """Called when we have to play :)"""
390 if self.state == "chien":
391 self.to_show = []
392 self.updateToShow()
393 self.state = "play"
394
395 def playCard(self, card):
396 self.hand.remove(card)
397 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, [(card.suit, card.value)])
398 self.state = "wait"
399 self.updateHand()