Mercurial > libervia-web
comparison browser_side/card_game.py @ 381:b96b8b666d17
plugin card_game: update to use the new XMLUI mechanism + copy the autoplay mode from QuickFrontend:
TODO: the new round is not starting after the scores have been displayed
author | souliane <souliane@mailoo.org> |
---|---|
date | Wed, 26 Feb 2014 02:28:19 +0100 |
parents | 564208366dd6 |
children | d52f529a6d42 |
comparison
equal
deleted
inserted
replaced
380:5e0e2032928c | 381:b96b8b666d17 |
---|---|
17 # You should have received a copy of the GNU Affero General Public License | 17 # You should have received a copy of the GNU Affero General Public License |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 import pyjd # this is dummy in pyjs | 20 import pyjd # this is dummy in pyjs |
21 from pyjamas.ui.AbsolutePanel import AbsolutePanel | 21 from pyjamas.ui.AbsolutePanel import AbsolutePanel |
22 from pyjamas.ui.VerticalPanel import VerticalPanel | |
23 from pyjamas.ui.HorizontalPanel import HorizontalPanel | |
24 from pyjamas.ui.DockPanel import DockPanel | 22 from pyjamas.ui.DockPanel import DockPanel |
25 from pyjamas.ui.SimplePanel import SimplePanel | 23 from pyjamas.ui.SimplePanel import SimplePanel |
26 from pyjamas.ui.DialogBox import DialogBox | |
27 from pyjamas.ui.ListBox import ListBox | |
28 from pyjamas.ui.Image import Image | 24 from pyjamas.ui.Image import Image |
29 from pyjamas.ui.Label import Label | 25 from pyjamas.ui.Label import Label |
30 from pyjamas.ui.Button import Button | |
31 from pyjamas.ui.ClickListener import ClickHandler | 26 from pyjamas.ui.ClickListener import ClickHandler |
32 from pyjamas.ui.MouseListener import MouseHandler | 27 from pyjamas.ui.MouseListener import MouseHandler |
33 from pyjamas.ui import HasAlignment | 28 from pyjamas.ui import HasAlignment |
34 from pyjamas import Window | 29 from pyjamas import Window |
35 from pyjamas import DOM | 30 from pyjamas import DOM |
36 | 31 |
37 from dialog import ConfirmDialog, InfoDialog | 32 from dialog import ConfirmDialog, GenericDialog |
33 from xmlui import XMLUI | |
38 from sat_frontends.tools.games import TarotCard | 34 from sat_frontends.tools.games import TarotCard |
39 import re | 35 from sat.core.i18n import _ |
40 | 36 |
41 | 37 |
42 CARD_WIDTH = 74 | 38 CARD_WIDTH = 74 |
43 CARD_HEIGHT = 136 | 39 CARD_HEIGHT = 136 |
44 CARD_DELTA_Y = 30 | 40 CARD_DELTA_Y = 30 |
45 MIN_WIDTH = 950 # Minimum size of the panel | 41 MIN_WIDTH = 950 # Minimum size of the panel |
46 MIN_HEIGHT = 500 | 42 MIN_HEIGHT = 500 |
47 | |
48 | |
49 class ContratChooser(DialogBox): | |
50 | |
51 def __init__(self, parent): | |
52 """ | |
53 Dialog asking to choose the contrat | |
54 """ | |
55 self._parent = parent | |
56 DialogBox.__init__(self, modal=False, centered=True) | |
57 | |
58 content = VerticalPanel() | |
59 content.setWidth('100%') | |
60 self.contrats_list = ListBox() | |
61 self.contrats_list.setVisibleItemCount(5) | |
62 self.contrats_list.setWidth("100%") | |
63 self.contrats_list.setStyleName('contratsChooser') | |
64 for contrat in ['Passe', 'Petite', 'Garde', 'Garde Sans', 'Garde Contre']: | |
65 self.contrats_list.addItem(contrat) | |
66 self.contrats_list.setSelectedIndex(0) | |
67 content.add(self.contrats_list) | |
68 button_panel = HorizontalPanel() | |
69 button_panel.addStyleName("marginAuto") | |
70 self.choose_button = Button("Choose", self.onChoose) | |
71 button_panel.add(self.choose_button) | |
72 content.add(button_panel) | |
73 self.setHTML("Please select your contrat") | |
74 self.setWidget(content) | |
75 | |
76 def onChoose(self, button): | |
77 self.hide() | |
78 self._parent.contratSelected(self.contrats_list.getSelectedItemText()[0]) | |
79 | 43 |
80 | 44 |
81 class CardWidget(TarotCard, Image, MouseHandler): | 45 class CardWidget(TarotCard, Image, MouseHandler): |
82 """This class is used to represent a card, graphically and logically""" | 46 """This class is used to represent a card, graphically and logically""" |
83 | 47 |
238 self.updateToShow() | 202 self.updateToShow() |
239 self.updateHand() | 203 self.updateHand() |
240 | 204 |
241 def tarotGameNew(self, hand): | 205 def tarotGameNew(self, hand): |
242 """Start a new game, with given hand""" | 206 """Start a new game, with given hand""" |
207 if hand is []: # reset the display after the scores have been showed | |
208 self.selected.clear() | |
209 del self.hand[:] | |
210 del self.to_show[:] | |
211 self.state = None | |
212 #empty hand | |
213 self.updateHand() | |
214 #nothing on the table | |
215 self.updateToShow() | |
216 for pos in ['top', 'left', 'bottom', 'right']: | |
217 getattr(self, "inner_%s" % pos).setWidget(None) | |
218 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) | |
219 return | |
243 for suit, value in hand: | 220 for suit, value in hand: |
244 self.hand.append(self.cards[(suit, value)]) | 221 self.hand.append(self.cards[(suit, value)]) |
245 self.hand.sort() | 222 self.hand.sort() |
246 self.state = "init" | 223 self.state = "init" |
247 self.updateHand() | 224 self.updateHand() |
305 for suit, value in played_cards: | 282 for suit, value in played_cards: |
306 self.hand.append(self.cards[(suit, value)]) | 283 self.hand.append(self.cards[(suit, value)]) |
307 | 284 |
308 self.hand.sort() | 285 self.hand.sort() |
309 self.updateHand() | 286 self.updateHand() |
310 Window.alert('Cards played are invalid !') | 287 if self._autoplay == None: # No dialog if there is autoplay |
288 Window.alert('Cards played are invalid !') | |
289 self.__fakePlay() | |
311 | 290 |
312 def removeFromSelection(self, card): | 291 def removeFromSelection(self, card): |
313 self.selected.remove(card) | 292 self.selected.remove(card) |
314 if len(self.selected) == 6: | 293 if len(self.selected) == 6: |
315 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show() | 294 ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show() |
316 | 295 |
317 def tarotGameChooseContrat(self, xml_data): | 296 def tarotGameChooseContrat(self, xml_data): |
318 """Called when the player as to select his contrat | 297 """Called when the player has to select his contrat |
319 @param xml_data: SàT xml representation of the form""" | 298 @param xml_data: SàT xml representation of the form""" |
320 #for the moment we cheat a little bit and make our own dialog box | 299 body = XMLUI(self._parent.host, xml_data, flags=['NO_CANCEL']) |
321 #but XMLUI must be user ASAP, as in other frontends | 300 _dialog = GenericDialog(_('Please choose your contrat'), body, options=['NO_CLOSE']) |
322 contrat_chooser = ContratChooser(self) | 301 body.setCloseCb(_dialog.close) |
323 contrat_chooser.show() | 302 _dialog.show() |
324 | |
325 def contratSelected(self, contrat): | |
326 """Must be called when the contrat is selected | |
327 @param contrat: one of the valid contrat value""" | |
328 self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe') | |
329 | 303 |
330 def tarotGameShowCards(self, game_stage, cards, data): | 304 def tarotGameShowCards(self, game_stage, cards, data): |
331 """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" | 305 """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" |
332 self.to_show = [] | 306 self.to_show = [] |
333 for suit, value in cards: | 307 for suit, value in cards: |
372 """Called when we have to play :)""" | 346 """Called when we have to play :)""" |
373 if self.state == "chien": | 347 if self.state == "chien": |
374 self.to_show = [] | 348 self.to_show = [] |
375 self.updateToShow() | 349 self.updateToShow() |
376 self.state = "play" | 350 self.state = "play" |
351 self.__fakePlay() | |
352 | |
353 def __fakePlay(self): | |
354 """Convenience method for stupid autoplay | |
355 /!\ don't forgot to comment any interactive dialog for invalid card""" | |
356 if self._autoplay == None: | |
357 return | |
358 if self._autoplay >= len(self.hand): | |
359 self._autoplay = 0 | |
360 card = self.hand[self._autoplay] | |
361 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, [(card.suit, card.value)]) | |
362 del self.hand[self._autoplay] | |
363 self.state = "wait" | |
364 self._autoplay += 1 | |
377 | 365 |
378 def playCard(self, card): | 366 def playCard(self, card): |
379 self.hand.remove(card) | 367 self.hand.remove(card) |
380 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, [(card.suit, card.value)]) | 368 self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, [(card.suit, card.value)]) |
381 self.state = "wait" | 369 self.state = "wait" |
382 self.updateHand() | 370 self.updateHand() |
383 | 371 |
384 def tarotGameScore(self, xml_data, winners, loosers): | 372 def tarotGameScore(self, xml_data, winners, loosers): |
385 """Show score at this end of a round""" | 373 """Show score at the end of a round""" |
386 ###XXX: we cheat here as XMLUI is not implemented yet | |
387 #TODO: usr XMLUI | |
388 def _new_game(): | |
389 self.selected.clear() | |
390 del self.hand[:] | |
391 del self.to_show[:] | |
392 self.state = None | |
393 #empty hand | |
394 self.updateHand() | |
395 #nothing on the table | |
396 self.updateToShow() | |
397 for pos in ['top', 'left', 'bottom', 'right']: | |
398 getattr(self, "inner_%s" % pos).setWidget(None) | |
399 self._parent.host.bridge.call('tarotGameReady', None, self.player_nick, self.referee) | |
400 | |
401 if not winners and not loosers: | 374 if not winners and not loosers: |
402 title = "Draw game" | 375 title = "Draw game" |
403 else: | 376 else: |
404 if self.player_nick in winners: | 377 if self.player_nick in winners: |
405 title = "You <b>win</b> !" | 378 title = "You <b>win</b> !" |
406 else: | 379 else: |
407 title = "You <b>loose</b> :(" | 380 title = "You <b>loose</b> :(" |
408 body = re.sub(r'<.*?>', lambda x: '<br />' if '/elem' in x.group(0) else '', xml_data) # Q&D conversion to simple HTML text | 381 body = XMLUI(self._parent.host, xml_data, title=title, flags=['NO_CANCEL']) |
409 InfoDialog(title, body, _new_game).show() | 382 _dialog = GenericDialog(title, body, options=['NO_CLOSE']) |
383 body.setCloseCb(_dialog.close) | |
384 _dialog.show() |