# HG changeset patch # User Goffi # Date 1306016101 -7200 # Node ID 305e81c7a32c1117899b531fff32bf44e69b8fd5 # Parent 7bea2ae0c4fb1ede66e50bf0b2fa9d56757686bd Tarot game: a game can now be finished diff -r 7bea2ae0c4fb -r 305e81c7a32c browser_side/card_game.py --- a/browser_side/card_game.py Thu May 19 02:00:59 2011 +0200 +++ b/browser_side/card_game.py Sun May 22 00:15:01 2011 +0200 @@ -39,6 +39,7 @@ from pyjamas.dnd import makeDraggable from pyjamas.ui.DragWidget import DragWidget, DragContainer from jid import JID +from dialog import ConfirmDialog from tools import html_sanitize from datetime import datetime from time import time @@ -48,7 +49,7 @@ CARD_WIDTH = 74 CARD_HEIGHT = 136 -CARD_DELTA_Y = 10 +CARD_DELTA_Y = 30 MIN_WIDTH = 950 #Minimum size of the panel MIN_HEIGHT = 500 @@ -96,11 +97,23 @@ self.addMouseListener(self) def onMouseEnter(self, sender): - if self._parent.state == "ecart": + if self._parent.state == "ecart" or self._parent.state == "play": DOM.setStyleAttribute(self.getElement(), "top", "0px") def onMouseLeave(self, sender): - DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y) + if not self in self._parent.hand: + return + if not self in list(self._parent.selected): #FIXME: Workaround pyjs bug, must report it + DOM.setStyleAttribute(self.getElement(), "top", "%dpx" % CARD_DELTA_Y) + + def onMouseUp(self, sender, x, y): + if self._parent.state == "ecart": + if self not in list(self._parent.selected): + self._parent.addToSelection(self) + else: + self._parent.removeFromSelection(self) + elif self._parent.state == "play": + self._parent.playCard(self) class CardPanel(DockPanel, ClickHandler): @@ -124,7 +137,7 @@ idx = (idx + 1) % len(self.players) self.left_nick = self.players[idx] self.bottom_nick = player_nick - self.selected = [] #Card choosed by the player (e.g. during ecart) + self.selected = set() #Card choosed by the player (e.g. during ecart) self.hand_size = 13 #number of cards in a hand self.hand = [] self.to_show = [] @@ -163,25 +176,27 @@ self.center_panel = DockPanel() self.inner_left = SimplePanel() + self.inner_left.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) self.center_panel.add(self.inner_left, DockPanel.WEST) self.center_panel.setCellHeight(self.inner_left, '100%') self.center_panel.setCellHorizontalAlignment(self.inner_left, HasAlignment.ALIGN_RIGHT) self.center_panel.setCellVerticalAlignment(self.inner_left, HasAlignment.ALIGN_MIDDLE) self.inner_right = SimplePanel() + self.inner_right.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) self.center_panel.add(self.inner_right, DockPanel.EAST) self.center_panel.setCellHeight(self.inner_right, '100%') self.center_panel.setCellVerticalAlignment(self.inner_right, HasAlignment.ALIGN_MIDDLE) self.inner_top = SimplePanel() + self.inner_top.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) self.center_panel.add(self.inner_top, DockPanel.NORTH) - self.center_panel.setCellWidth(self.inner_top, '100%') self.center_panel.setCellHorizontalAlignment(self.inner_top, HasAlignment.ALIGN_CENTER) self.center_panel.setCellVerticalAlignment(self.inner_top, HasAlignment.ALIGN_BOTTOM) self.inner_bottom = SimplePanel() + self.inner_bottom.setSize("%dpx" % CARD_WIDTH, "%dpx" % CARD_HEIGHT) self.center_panel.add(self.inner_bottom, DockPanel.SOUTH) - self.center_panel.setCellWidth(self.inner_bottom, '100%') self.center_panel.setCellHorizontalAlignment(self.inner_bottom, HasAlignment.ALIGN_CENTER) self.center_panel.setCellVerticalAlignment(self.inner_bottom, HasAlignment.ALIGN_TOP) @@ -274,6 +289,47 @@ x_pos+=CARD_WIDTH + 5 self.inner_center.setWidget(panel) + def _ecartConfirm(self, confirm): + if not confirm: + return + ecart = [] + for card in self.selected: + ecart.append((card.suit, card.value)) + self.hand.remove(card) + self.selected.clear() + self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, ecart) + self.state = "wait" + self.updateHand() + + def addToSelection(self, card): + self.selected.add(card) + if len(self.selected) == 6: + ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show() + + def tarotGameInvalidCards(self, phase, played_cards, invalid_cards): + """Invalid cards have been played + @param phase: phase of the game + @param played_cards: all the cards played + @param invalid_cards: cards which are invalid""" + + if phase == "play": + self.state = "play" + elif phase == "ecart": + self.state = "ecart" + else: + error ('INTERNAL ERROR: unmanaged game phase') + + for suit, value in played_cards: + self.hand.append(self.cards[(suit, value)]) + + self.hand.sort() + self.updateHand() + Window.alert('Cards played are invalid !') + + def removeFromSelection(self, card): + self.selected.remove(card) + if len(self.selected) == 6: + ConfirmDialog(self._ecartConfirm, "Put these cards into chien ?").show() def tarotGameChooseContrat(self, xml_data): """Called when the player as to select his contrat @@ -286,11 +342,8 @@ def contratSelected(self, contrat): """Must be called when the contrat is selected @param contrat: one of the valid contrat value""" - print "Contrat choosed:", contrat self._parent.host.bridge.call('tarotGameContratChoosed', None, self.player_nick, self.referee, contrat or 'Passe') - - def tarotGameShowCards(self, game_stage, cards, data): """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" self.to_show = [] @@ -302,3 +355,45 @@ else: self.state = "chien" + def getPlayerLocation(self, nick): + """return player location (top,bottom,left or right)""" + for location in ['top','left','bottom','right']: + if getattr(self,'%s_nick' % location) == nick: + return location + print ("ERROR: This line should not be reached") + + def tarotGameCardsPlayed(self, player, cards): + """A card has been played by player""" + if not len(cards): + print ("WARNING: cards should not be empty") + return + if len(cards) > 1: + print ("ERROR: can't manage several cards played") + if self.to_show: + self.to_show = [] + self.updateToShow() + suit, value = cards[0] + player_pos = self.getPlayerLocation(player) + player_panel = getattr(self, "inner_%s" % player_pos) + + if player_panel.getWidget() != None: + #We have already cards on the table, we remove them + for pos in ['top','left','bottom','right']: + getattr(self, "inner_%s" % pos).setWidget(None) + + card = self.cards[(suit, value)] + DOM.setElemAttribute(card.getElement(), "style", "") + player_panel.setWidget(card) + + def tarotGameYourTurn(self): + """Called when we have to play :)""" + if self.state == "chien": + self.to_show = [] + self.updateToShow() + self.state = "play" + + def playCard(self, card): + self.hand.remove(card) + self._parent.host.bridge.call('tarotGamePlayCards', None, self.player_nick, self.referee, [(card.suit, card.value)]) + self.state = "wait" + self.updateHand() diff -r 7bea2ae0c4fb -r 305e81c7a32c browser_side/dialog.py --- a/browser_side/dialog.py Thu May 19 02:00:59 2011 +0200 +++ b/browser_side/dialog.py Sun May 22 00:15:01 2011 +0200 @@ -81,3 +81,31 @@ def onCancel(self): self.hide() +class ConfirmDialog(DialogBox): + + def __init__(self, callback, text='Are you sure ?'): + """ + Dialog to confirm an action + @param callback: method to call when contacts have been choosed + """ + self.callback = callback + DialogBox.__init__(self, centered=True) + + content = VerticalPanel() + content.setWidth('100%') + button_panel = HorizontalPanel() + self.confirm_button = Button("OK", self.onConfirm) + button_panel.add(self.confirm_button) + button_panel.add(Button("Cancel", self.onCancel)) + content.add(button_panel) + self.setHTML(text) + self.setWidget(content) + + def onConfirm(self): + self.hide() + self.callback(True) + + def onCancel(self): + self.hide() + self.callback(False) + diff -r 7bea2ae0c4fb -r 305e81c7a32c browser_side/panels.py --- a/browser_side/panels.py Thu May 19 02:00:59 2011 +0200 +++ b/browser_side/panels.py Sun May 22 00:15:01 2011 +0200 @@ -147,6 +147,8 @@ _new_panel.historyPrint() elif item_type=="CONTACT_TITLE": _new_panel = MicroblogPanel(self.host, accept_all=True) + else: + return self.host.mpanels.remove(self) self.host.mpanels.append(_new_panel) grid = self.getParent() diff -r 7bea2ae0c4fb -r 305e81c7a32c libervia.py --- a/libervia.py Thu May 19 02:00:59 2011 +0200 +++ b/libervia.py Sun May 22 00:15:01 2011 +0200 @@ -66,7 +66,8 @@ def __init__(self): LiberviaJsonProxy.__init__(self, "/json_api", ["getContacts", "sendMessage", "sendMblog", "getMblogNodes", "getProfileJid", "getHistory", - "getPresenceStatus", "getRoomJoined", "launchTarotGame", "getTarotCardsPaths", "tarotGameReady", "tarotGameContratChoosed"]) + "getPresenceStatus", "getRoomJoined", "launchTarotGame", "getTarotCardsPaths", "tarotGameReady", "tarotGameContratChoosed", + "tarotGamePlayCards"]) class BridgeSignals(LiberviaJsonProxy): def __init__(self): @@ -173,7 +174,10 @@ self._tarotGameStartedCb(*args) elif name == 'tarotGameNew' or \ name == 'tarotGameChooseContrat' or \ - name == 'tarotGameShowCards': + name == 'tarotGameShowCards' or \ + name == 'tarotGameInvalidCards' or \ + name == 'tarotGameCardsPlayed' or \ + name == 'tarotGameYourTurn': self._tarotGameGenericCb(name, args[0], args[1:]) def _getProfileJidCB(self, jid): diff -r 7bea2ae0c4fb -r 305e81c7a32c libervia.tac --- a/libervia.tac Thu May 19 02:00:59 2011 +0200 +++ b/libervia.tac Sun May 22 00:15:01 2011 +0200 @@ -137,6 +137,11 @@ """Tell to the server that we are ready to start the game""" profile = self.session.sat_profile self.sat_host.bridge.tarotGameContratChoosed(player_nick, referee, contrat, profile) + + def jsonrpc_tarotGamePlayCards(self, player_nick, referee, cards): + """Tell to the server that we are ready to start the game""" + profile = self.session.sat_profile + self.sat_host.bridge.tarotGamePlayCards(player_nick, referee, cards, profile) class Register(jsonrpc.JSONRPC): """This class manage the registration procedure with SàT @@ -362,7 +367,7 @@ self.bridge.register("connected", self.signal_handler.connected) self.bridge.register("connectionError", self.signal_handler.connectionError) for signal_name in ['presenceUpdate', 'personalEvent', 'newMessage', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', - 'tarotGameChooseContrat', 'tarotGameShowCards']: + 'tarotGameChooseContrat', 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn']: self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name)) root.putChild('json_signal_api', self.signal_handler) root.putChild('json_api', MethodHandler(self))