comparison frontends/primitivus/card_game.py @ 150:63d20bda5754

Primitivus: Tarot game Tarot game is now playable, scores are not showed yet.
author Goffi <goffi@goffi.org>
date Wed, 28 Jul 2010 19:58:10 +0800
parents 80661755ea8d
children f197b52796ee
comparison
equal deleted inserted replaced
149:3c3f70c01333 150:63d20bda5754
21 21
22 import urwid 22 import urwid
23 from tools.games import TarotCard 23 from tools.games import TarotCard
24 from quick_frontend.quick_card_game import QuickCardGame 24 from quick_frontend.quick_card_game import QuickCardGame
25 from xmlui import XMLUI 25 from xmlui import XMLUI
26 import custom_widgets
27
28 class CardDisplayer(urwid.Text):
29 """Show a card"""
30 signals = ['click']
31
32 def __init__(self, card):
33 self.__selected = False
34 self.card = card
35 urwid.Text.__init__(self, card.getAttrText())
36
37 def selectable(self):
38 return True
39
40 def keypress(self, size, key):
41 if key == ' ':
42 self.select(not self.__selected)
43 self._emit('click')
44 return key
45
46 def select(self, state=True):
47 self.__selected = state
48 attr,txt = self.card.getAttrText()
49 if self.__selected:
50 attr+='_selected'
51 self.set_text((attr,txt))
52 self._invalidate()
53
54 def isSelected(self):
55 return self.__selected
56
57 def getCard(self):
58 return self.card
59
60 def render(self, size, focus=False):
61 canvas = urwid.CompositeCanvas(urwid.Text.render(self, size, focus))
62 if focus:
63 canvas.set_cursor((0,0))
64 return canvas
26 65
27 class Hand(urwid.WidgetWrap): 66 class Hand(urwid.WidgetWrap):
28 """Used to display several cards, and manage a hand""" 67 """Used to display several cards, and manage a hand"""
29 68 signals = ['click']
30 def __init__(self): 69
31 self.columns = urwid.Columns([]) 70 def __init__(self, hand=[], selectable = False, on_click=None, user_data=None):
71 """@param hand: list of Card"""
72 self.__selectable = selectable
73 self.columns = urwid.Columns([],dividechars=1)
74 if on_click:
75 urwid.connect_signal(self, 'click', on_click, user_data)
76 if hand:
77 self.update(hand)
32 urwid.WidgetWrap.__init__(self, self.columns) 78 urwid.WidgetWrap.__init__(self, self.columns)
33 79
80 def selectable(self):
81 return self.__selectable
82
83 def keypress(self, size, key):
84
85 if CardDisplayer in [wid.__class__ for wid in self.columns.widget_list]:
86 return self.columns.keypress(size,key)
87 else:
88 #No card displayed, we still have to manage the clicks
89 if key == ' ':
90 self._emit('click', None)
91 return key
92
93 def getSelected(self):
94 """Return a list of selected cards"""
95 _selected = []
96 for wid in self.columns.widget_list:
97 if wid.__class__ == CardDisplayer and wid.isSelected():
98 _selected.append(wid.getCard())
99 return _selected
100
34 def update(self, hand): 101 def update(self, hand):
35 """Update the hand displayed in this widget""" 102 """Update the hand displayed in this widget
103 @param hand: list of Card"""
36 del self.columns.widget_list[:] 104 del self.columns.widget_list[:]
37 del self.columns.column_types[:] 105 del self.columns.column_types[:]
106 self.columns.widget_list.append(urwid.Text(''))
107 self.columns.column_types.append(('weight',1))
38 for card in hand: 108 for card in hand:
39 self.columns.widget_list.append(urwid.Text(card.getAttrText())) 109 widget = CardDisplayer(card)
40 self.columns.column_types.append(('weight',1)) 110 self.columns.widget_list.append(widget)
41 111 self.columns.column_types.append(('fixed',3))
42 112 urwid.connect_signal(widget, 'click', self.__onClick)
43 113 self.columns.widget_list.append(urwid.Text(''))
114 self.columns.column_types.append(('weight',1))
115 self.columns.set_focus(1)
116
117 def __onClick(self,card_wid):
118 self._emit('click', card_wid)
44 119
45 class Card(TarotCard): 120 class Card(TarotCard):
46 """This class is used to represent a card, logically 121 """This class is used to represent a card, logically
47 and give a text representation with attributes""" 122 and give a text representation with attributes"""
123 SIZE = 3 #size of a displayed card
48 124
49 def __init__(self, suit, value): 125 def __init__(self, suit, value):
50 """@param file: path of the PNG file""" 126 """@param file: path of the PNG file"""
51 TarotCard.__init__(self, (suit, value)) 127 TarotCard.__init__(self, (suit, value))
52 128
76 color = 'red' 152 color = 'red'
77 if self.bout: 153 if self.bout:
78 color = 'special' 154 color = 'special'
79 return ('card_%s' % color,u"%s%s" % (value,suit)) 155 return ('card_%s' % color,u"%s%s" % (value,suit))
80 156
157 def getWidget(self):
158 """Return a widget representing the card"""
159 return CardDisplayer(self)
160
161 class Table(urwid.FlowWidget):
162 """Represent the cards currently on the table"""
163
164 def __init__(self):
165 self.top = self.left = self.bottom = self.right = None
166
167 def putCard(self, location, card):
168 """Put a card on the table
169 @param location: where to put the card (top, left, bottom or right)
170 @param card: Card to play or None"""
171 assert location in ['top','left','bottom','right']
172 assert card.__class__ == Card or card == None
173 if [getattr(self, place) for place in ['top','left','bottom','right']].count(None) == 0:
174 #If the table is full of card, we remove them
175 self.top = self.left = self.bottom = self.right = None
176 setattr(self, location, card)
177 self._invalidate()
178
179 def rows(self,size,focus=False):
180 return self.display_widget(size, focus).rows(size, focus)
181
182 def render(self, size, focus=False):
183 return self.display_widget(size, focus).render(size, focus)
184
185 def display_widget(self, size, focus):
186 cards={}
187 max_col, = size
188 separator = " - "
189 margin = max((max_col-Card.SIZE)/2,0) * ' '
190 margin_center = max((max_col-Card.SIZE*2-len(separator))/2,0) * ' '
191 for location in ['top', 'left', 'bottom', 'right']:
192 card = getattr(self,location)
193 cards[location] = card.getAttrText() if card else Card.SIZE * ' '
194 render_wid = [urwid.Text([margin,cards['top']]),
195 urwid.Text([margin_center,cards['left'],separator,cards['right']]),
196 urwid.Text([margin,cards['bottom']])]
197 return urwid.Pile(render_wid)
198
199
81 class CardGame(QuickCardGame,urwid.WidgetWrap): 200 class CardGame(QuickCardGame,urwid.WidgetWrap):
82 """Widget for card games""" 201 """Widget for card games"""
83 202
84 def __init__(self, parent, referee, players, player_nick): 203 def __init__(self, parent, referee, players, player_nick):
85 QuickCardGame.__init__(self, parent, referee, players, player_nick) 204 QuickCardGame.__init__(self, parent, referee, players, player_nick)
86 self.loadCards() 205 self.loadCards()
87 self.top = urwid.Pile([urwid.Padding(urwid.Text(self.top_nick), 'center')]) 206 self.top = urwid.Pile([urwid.Padding(urwid.Text(self.top_nick), 'center')])
88 self.top_card_wid = urwid.Text('') 207 #self.parent.host.debug()
89 self.center_cards_wid = urwid.Text(' - ') 208 self.table = Table()
90 self.bottom_card_wid = urwid.Text('') 209 self.center = urwid.Columns([('fixed',len(self.left_nick),urwid.Filler(urwid.Text(self.left_nick))),
91 center = urwid.Pile([urwid.Padding(self.top_card_wid,'center'), 210 urwid.Filler(self.table),
211 ('fixed',len(self.right_nick),urwid.Filler(urwid.Text(self.right_nick)))
212 ])
213 """urwid.Pile([urwid.Padding(self.top_card_wid,'center'),
92 urwid.Columns([('fixed',len(self.left_nick),urwid.Text(self.left_nick)), 214 urwid.Columns([('fixed',len(self.left_nick),urwid.Text(self.left_nick)),
93 urwid.Padding(self.center_cards_wid,'center'), 215 urwid.Padding(self.center_cards_wid,'center'),
94 ('fixed',len(self.right_nick),urwid.Text(self.right_nick)) 216 ('fixed',len(self.right_nick),urwid.Text(self.right_nick))
95 ]), 217 ]),
96 urwid.Padding(self.bottom_card_wid,'center') 218 urwid.Padding(self.bottom_card_wid,'center')
97 ]) 219 ])"""
98 body = urwid.Filler(center) 220 self.hand_wid = Hand(selectable = True, on_click = self.onClick)
99 self.hand_wid = Hand() 221 self.main_frame = urwid.Frame(self.center,header=self.top, footer=self.hand_wid, focus_part='footer')
100 self.main_frame = urwid.Frame(body,header=self.top, footer=self.hand_wid)
101 urwid.WidgetWrap.__init__(self,self.main_frame) 222 urwid.WidgetWrap.__init__(self,self.main_frame)
102 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile) 223 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile)
103 224
104 def loadCards(self): 225 def loadCards(self):
105 """Load all the cards in memory""" 226 """Load all the cards in memory"""
131 @param xml_data: SàT xml representation of the form""" 252 @param xml_data: SàT xml representation of the form"""
132 misc = {'callback': self.contratSelected} 253 misc = {'callback': self.contratSelected}
133 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc) 254 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc)
134 form.show() 255 form.show()
135 256
136 """def selectable(self): 257 def showCards(self, game_stage, cards, data):
137 return True 258 """Display cards in the middle of the game (to show for e.g. chien ou poignée)"""
138 259 QuickCardGame.showCards(self, game_stage, cards, data)
139 def keypress(self, size, key): 260 self.center.widget_list[1] = urwid.Filler(Hand(self.to_show))
140 return key 261 self.parent.host.redraw()
141 262
142 def render(self, size, focus=False): 263 def myTurn(self):
143 return self.display_widget(size, focus).render(size, focus) 264 QuickCardGame.myTurn(self)
144 265
145 def display_widget(self, size, focus): 266 def showScores(self, xml_data, winners, loosers):
146 (maxcol,maxrow) = size 267 """Called when the player as to select hist contrat
147 268 @param xml_data: SàT xml representation of the form"""
148 return self.main_frame""" 269 form = XMLUI(self.parent.host, xml_data, title = _('You win \o/') if self.player_nick in winners else _('You loose :('), options = ['NO_CANCEL'])
149 270
271 def invalidCards(self, phase, played_cards, invalid_cards):
272 """Invalid cards have been played
273 @param phase: phase of the game
274 @param played_cards: all the cards played
275 @param invalid_cards: cards which are invalid"""
276 QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards)
277 self.hand_wid.update(self.hand)
278 self.parent.host.redraw()
279
280 def cardsPlayed(self, player, cards):
281 """A card has been played by player"""
282 QuickCardGame.cardsPlayed(self, player, cards)
283 self.table.putCard(self.getPlayerLocation(player),self.played[player])
284 self.parent.host.redraw()
285
286 ##EVENTS##
287 def onClick(self, hand, card_wid):
288 """Called when user do an action on the hand"""
289 if not self.state in ['play','ecart','wait_for_ecart']:
290 #it's not our turn, we ignore the click
291 card_wid.select(False)
292 return
293 if self.center.widget_list[1].original_widget.__class__ == Hand: #if we have a hand displayed
294 self.center.widget_list[1] = urwid.Filler(self.table) #we show again the table
295 if self.state == "chien":
296 self.to_show = []
297 self.state = "wait"
298 elif self.state == "wait_for_ecart":
299 self.state = "ecart"
300 self.hand.extend(self.to_show)
301 self.hand.sort()
302 self.to_show = []
303 self.hand_wid.update(self.hand)
304 if self.state == "ecart":
305 if len(self.hand_wid.getSelected()) == 6:
306 pop_up_widget = custom_widgets.ConfirmDialog(_("Do you put these cards in chien ?"), yes_cb=self.onEcartDone, no_cb=self.parent.host.removePopUp)
307 self.parent.host.showPopUp(pop_up_widget)
308 elif self.state == "play":
309 card = card_wid.getCard()
310 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, [(card.suit, card.value)], profile_key = self.parent.host.profile)
311 self.hand.remove(card)
312 self.hand_wid.update(self.hand)
313 self.state = "wait"
314
315 def onEcartDone(self,button):
316 """Called when player has finished is écart"""
317 ecart = []
318 for card in self.hand_wid.getSelected():
319 ecart.append((card.suit, card.value))
320 self.hand.remove(card)
321 self.hand_wid.update(self.hand)
322 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, ecart, profile_key = self.parent.host.profile)
323 self.state = "wait"
324 self.parent.host.removePopUp()