diff 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
line wrap: on
line diff
--- 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()