# HG changeset patch # User Goffi # Date 1280318290 -28800 # Node ID 63d20bda575450d972054affdc7cf6ca850ff0fd # Parent 3c3f70c0133368ad386275720435fa94cab193f7 Primitivus: Tarot game Tarot game is now playable, scores are not showed yet. diff -r 3c3f70c01333 -r 63d20bda5754 frontends/primitivus/card_game.py --- a/frontends/primitivus/card_game.py Wed Jul 28 19:56:56 2010 +0800 +++ b/frontends/primitivus/card_game.py Wed Jul 28 19:58:10 2010 +0800 @@ -23,28 +23,104 @@ from tools.games import TarotCard from quick_frontend.quick_card_game import QuickCardGame from xmlui import XMLUI +import custom_widgets + +class CardDisplayer(urwid.Text): + """Show a card""" + signals = ['click'] + + def __init__(self, card): + self.__selected = False + self.card = card + urwid.Text.__init__(self, card.getAttrText()) + + def selectable(self): + return True + + def keypress(self, size, key): + if key == ' ': + self.select(not self.__selected) + self._emit('click') + return key + + def select(self, state=True): + self.__selected = state + attr,txt = self.card.getAttrText() + if self.__selected: + attr+='_selected' + self.set_text((attr,txt)) + self._invalidate() + + def isSelected(self): + return self.__selected + + def getCard(self): + return self.card + + def render(self, size, focus=False): + canvas = urwid.CompositeCanvas(urwid.Text.render(self, size, focus)) + if focus: + canvas.set_cursor((0,0)) + return canvas class Hand(urwid.WidgetWrap): """Used to display several cards, and manage a hand""" + signals = ['click'] - def __init__(self): - self.columns = urwid.Columns([]) + def __init__(self, hand=[], selectable = False, on_click=None, user_data=None): + """@param hand: list of Card""" + self.__selectable = selectable + self.columns = urwid.Columns([],dividechars=1) + if on_click: + urwid.connect_signal(self, 'click', on_click, user_data) + if hand: + self.update(hand) urwid.WidgetWrap.__init__(self, self.columns) + def selectable(self): + return self.__selectable + + def keypress(self, size, key): + + if CardDisplayer in [wid.__class__ for wid in self.columns.widget_list]: + return self.columns.keypress(size,key) + else: + #No card displayed, we still have to manage the clicks + if key == ' ': + self._emit('click', None) + return key + + def getSelected(self): + """Return a list of selected cards""" + _selected = [] + for wid in self.columns.widget_list: + if wid.__class__ == CardDisplayer and wid.isSelected(): + _selected.append(wid.getCard()) + return _selected + def update(self, hand): - """Update the hand displayed in this widget""" + """Update the hand displayed in this widget + @param hand: list of Card""" del self.columns.widget_list[:] del self.columns.column_types[:] + self.columns.widget_list.append(urwid.Text('')) + self.columns.column_types.append(('weight',1)) for card in hand: - self.columns.widget_list.append(urwid.Text(card.getAttrText())) - self.columns.column_types.append(('weight',1)) - + widget = CardDisplayer(card) + self.columns.widget_list.append(widget) + self.columns.column_types.append(('fixed',3)) + urwid.connect_signal(widget, 'click', self.__onClick) + self.columns.widget_list.append(urwid.Text('')) + self.columns.column_types.append(('weight',1)) + self.columns.set_focus(1) - + def __onClick(self,card_wid): + self._emit('click', card_wid) class Card(TarotCard): """This class is used to represent a card, logically and give a text representation with attributes""" + SIZE = 3 #size of a displayed card def __init__(self, suit, value): """@param file: path of the PNG file""" @@ -78,6 +154,49 @@ color = 'special' return ('card_%s' % color,u"%s%s" % (value,suit)) + def getWidget(self): + """Return a widget representing the card""" + return CardDisplayer(self) + +class Table(urwid.FlowWidget): + """Represent the cards currently on the table""" + + def __init__(self): + self.top = self.left = self.bottom = self.right = None + + def putCard(self, location, card): + """Put a card on the table + @param location: where to put the card (top, left, bottom or right) + @param card: Card to play or None""" + assert location in ['top','left','bottom','right'] + assert card.__class__ == Card or card == None + if [getattr(self, place) for place in ['top','left','bottom','right']].count(None) == 0: + #If the table is full of card, we remove them + self.top = self.left = self.bottom = self.right = None + setattr(self, location, card) + self._invalidate() + + def rows(self,size,focus=False): + return self.display_widget(size, focus).rows(size, focus) + + def render(self, size, focus=False): + return self.display_widget(size, focus).render(size, focus) + + def display_widget(self, size, focus): + cards={} + max_col, = size + separator = " - " + margin = max((max_col-Card.SIZE)/2,0) * ' ' + margin_center = max((max_col-Card.SIZE*2-len(separator))/2,0) * ' ' + for location in ['top', 'left', 'bottom', 'right']: + card = getattr(self,location) + cards[location] = card.getAttrText() if card else Card.SIZE * ' ' + render_wid = [urwid.Text([margin,cards['top']]), + urwid.Text([margin_center,cards['left'],separator,cards['right']]), + urwid.Text([margin,cards['bottom']])] + return urwid.Pile(render_wid) + + class CardGame(QuickCardGame,urwid.WidgetWrap): """Widget for card games""" @@ -85,19 +204,21 @@ QuickCardGame.__init__(self, parent, referee, players, player_nick) self.loadCards() self.top = urwid.Pile([urwid.Padding(urwid.Text(self.top_nick), 'center')]) - self.top_card_wid = urwid.Text('') - self.center_cards_wid = urwid.Text(' - ') - self.bottom_card_wid = urwid.Text('') - center = urwid.Pile([urwid.Padding(self.top_card_wid,'center'), + #self.parent.host.debug() + self.table = Table() + self.center = urwid.Columns([('fixed',len(self.left_nick),urwid.Filler(urwid.Text(self.left_nick))), + urwid.Filler(self.table), + ('fixed',len(self.right_nick),urwid.Filler(urwid.Text(self.right_nick))) + ]) + """urwid.Pile([urwid.Padding(self.top_card_wid,'center'), urwid.Columns([('fixed',len(self.left_nick),urwid.Text(self.left_nick)), urwid.Padding(self.center_cards_wid,'center'), ('fixed',len(self.right_nick),urwid.Text(self.right_nick)) ]), urwid.Padding(self.bottom_card_wid,'center') - ]) - body = urwid.Filler(center) - self.hand_wid = Hand() - self.main_frame = urwid.Frame(body,header=self.top, footer=self.hand_wid) + ])""" + self.hand_wid = Hand(selectable = True, on_click = self.onClick) + self.main_frame = urwid.Frame(self.center,header=self.top, footer=self.hand_wid, focus_part='footer') urwid.WidgetWrap.__init__(self,self.main_frame) self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile) @@ -133,17 +254,71 @@ form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc) form.show() - """def selectable(self): - return True + def showCards(self, game_stage, cards, data): + """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" + QuickCardGame.showCards(self, game_stage, cards, data) + self.center.widget_list[1] = urwid.Filler(Hand(self.to_show)) + self.parent.host.redraw() + + def myTurn(self): + QuickCardGame.myTurn(self) + + def showScores(self, xml_data, winners, loosers): + """Called when the player as to select hist contrat + @param xml_data: SàT xml representation of the form""" + form = XMLUI(self.parent.host, xml_data, title = _('You win \o/') if self.player_nick in winners else _('You loose :('), options = ['NO_CANCEL']) + + def invalidCards(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""" + QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards) + self.hand_wid.update(self.hand) + self.parent.host.redraw() + + def cardsPlayed(self, player, cards): + """A card has been played by player""" + QuickCardGame.cardsPlayed(self, player, cards) + self.table.putCard(self.getPlayerLocation(player),self.played[player]) + self.parent.host.redraw() - def keypress(self, size, key): - return key - - def render(self, size, focus=False): - return self.display_widget(size, focus).render(size, focus) + ##EVENTS## + def onClick(self, hand, card_wid): + """Called when user do an action on the hand""" + if not self.state in ['play','ecart','wait_for_ecart']: + #it's not our turn, we ignore the click + card_wid.select(False) + return + if self.center.widget_list[1].original_widget.__class__ == Hand: #if we have a hand displayed + self.center.widget_list[1] = urwid.Filler(self.table) #we show again the table + if self.state == "chien": + self.to_show = [] + self.state = "wait" + elif self.state == "wait_for_ecart": + self.state = "ecart" + self.hand.extend(self.to_show) + self.hand.sort() + self.to_show = [] + self.hand_wid.update(self.hand) + if self.state == "ecart": + if len(self.hand_wid.getSelected()) == 6: + pop_up_widget = custom_widgets.ConfirmDialog(_("Do you put these cards in chien ?"), yes_cb=self.onEcartDone, no_cb=self.parent.host.removePopUp) + self.parent.host.showPopUp(pop_up_widget) + elif self.state == "play": + card = card_wid.getCard() + self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, [(card.suit, card.value)], profile_key = self.parent.host.profile) + self.hand.remove(card) + self.hand_wid.update(self.hand) + self.state = "wait" - def display_widget(self, size, focus): - (maxcol,maxrow) = size - - return self.main_frame""" - + def onEcartDone(self,button): + """Called when player has finished is écart""" + ecart = [] + for card in self.hand_wid.getSelected(): + ecart.append((card.suit, card.value)) + self.hand.remove(card) + self.hand_wid.update(self.hand) + self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, ecart, profile_key = self.parent.host.profile) + self.state = "wait" + self.parent.host.removePopUp() diff -r 3c3f70c01333 -r 63d20bda5754 frontends/quick_frontend/quick_app.py --- a/frontends/quick_frontend/quick_app.py Wed Jul 28 19:56:56 2010 +0800 +++ b/frontends/quick_frontend/quick_app.py Wed Jul 28 19:58:10 2010 +0800 @@ -316,7 +316,7 @@ return debug (_("My turn to play")) if self.chat_wins.has_key(room_jid): - self.chat_wins[room_jid].getGame("Tarot").MyTurn() + self.chat_wins[room_jid].getGame("Tarot").myTurn() def tarotScore(self, room_jid, xml_data, winners, loosers, profile): """Called when the game is finished and the score are updated""" diff -r 3c3f70c01333 -r 63d20bda5754 frontends/wix/card_game.py --- a/frontends/wix/card_game.py Wed Jul 28 19:56:56 2010 +0800 +++ b/frontends/wix/card_game.py Wed Jul 28 19:58:10 2010 +0800 @@ -121,7 +121,7 @@ self._recalc_ori() self.Refresh() - wx.MessageDialog(self, _("Cards played are invalid !"), _("Error"), wx.OK | wx.ICON_ERROR).ShowModal() + #gof: wx.MessageDialog(self, _("Cards played are invalid !"), _("Error"), wx.OK | wx.ICON_ERROR).ShowModal() def _is_on_hand(self, pos_x, pos_y): """Return True if the coordinate are on the hand cards"""