Mercurial > libervia-backend
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() |