Mercurial > libervia-web
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() |