Primitivus: Tarot game

Tarot game is now playable, scores are not showed yet.
This commit is contained in:
Goffi 2010-07-28 19:58:10 +08:00
commit 20a88f9909
3 changed files with 203 additions and 28 deletions

View file

@ -23,28 +23,104 @@ import urwid
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 @@ class Card(TarotCard):
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 @@ class CardGame(QuickCardGame,urwid.WidgetWrap):
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 @@ class CardGame(QuickCardGame,urwid.WidgetWrap):
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 keypress(self, size, key):
return key
def render(self, size, focus=False):
return self.display_widget(size, focus).render(size, focus)
def display_widget(self, size, focus):
(maxcol,maxrow) = size
return self.main_frame"""
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()
##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 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()

View file

@ -316,7 +316,7 @@ class QuickApp():
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"""

View file

@ -121,7 +121,7 @@ class CardPanel(QuickCardGame,wx.Panel):
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"""