Mercurial > libervia-backend
comparison frontends/src/primitivus/card_game.py @ 686:ae95b0327412
plugin card_game: better PEP-8 compliance
author | souliane <souliane@mailoo.org> |
---|---|
date | Mon, 28 Oct 2013 18:49:01 +0100 |
parents | 2805fa3f4bdf |
children | af0d08a84cc6 |
comparison
equal
deleted
inserted
replaced
685:0b9bd47dffcd | 686:ae95b0327412 |
---|---|
21 from urwid_satext import sat_widgets | 21 from urwid_satext import sat_widgets |
22 from sat.tools.frontends.games import TarotCard | 22 from sat.tools.frontends.games import TarotCard |
23 from sat_frontends.quick_frontend.quick_card_game import QuickCardGame | 23 from sat_frontends.quick_frontend.quick_card_game import QuickCardGame |
24 from sat_frontends.primitivus.xmlui import XMLUI | 24 from sat_frontends.primitivus.xmlui import XMLUI |
25 | 25 |
26 | |
26 class CardDisplayer(urwid.Text): | 27 class CardDisplayer(urwid.Text): |
27 """Show a card""" | 28 """Show a card""" |
28 signals = ['click'] | 29 signals = ['click'] |
29 | 30 |
30 def __init__(self, card): | 31 def __init__(self, card): |
40 self.select(not self.__selected) | 41 self.select(not self.__selected) |
41 self._emit('click') | 42 self._emit('click') |
42 return key | 43 return key |
43 | 44 |
44 def mouse_event(self, size, event, button, x, y, focus): | 45 def mouse_event(self, size, event, button, x, y, focus): |
45 if urwid.is_mouse_press(event) and button == 1: | 46 if urwid.is_mouse_event(event) and button == 1: |
46 self.select(not self.__selected) | 47 self.select(not self.__selected) |
47 self._emit('click') | 48 self._emit('click') |
48 return True | 49 return True |
49 | 50 |
50 return False | 51 return False |
51 | 52 |
52 def select(self, state=True): | 53 def select(self, state=True): |
53 self.__selected = state | 54 self.__selected = state |
54 attr,txt = self.card.getAttrText() | 55 attr, txt = self.card.getAttrText() |
55 if self.__selected: | 56 if self.__selected: |
56 attr+='_selected' | 57 attr += '_selected' |
57 self.set_text((attr,txt)) | 58 self.set_text((attr, txt)) |
58 self._invalidate() | 59 self._invalidate() |
59 | 60 |
60 def isSelected(self): | 61 def isSelected(self): |
61 return self.__selected | 62 return self.__selected |
62 | 63 |
64 return self.card | 65 return self.card |
65 | 66 |
66 def render(self, size, focus=False): | 67 def render(self, size, focus=False): |
67 canvas = urwid.CompositeCanvas(urwid.Text.render(self, size, focus)) | 68 canvas = urwid.CompositeCanvas(urwid.Text.render(self, size, focus)) |
68 if focus: | 69 if focus: |
69 canvas.set_cursor((0,0)) | 70 canvas.set_cursor((0, 0)) |
70 return canvas | 71 return canvas |
72 | |
71 | 73 |
72 class Hand(urwid.WidgetWrap): | 74 class Hand(urwid.WidgetWrap): |
73 """Used to display several cards, and manage a hand""" | 75 """Used to display several cards, and manage a hand""" |
74 signals = ['click'] | 76 signals = ['click'] |
75 | 77 |
76 def __init__(self, hand=[], selectable = False, on_click=None, user_data=None): | 78 def __init__(self, hand=[], selectable=False, on_click=None, user_data=None): |
77 """@param hand: list of Card""" | 79 """@param hand: list of Card""" |
78 self.__selectable = selectable | 80 self.__selectable = selectable |
79 self.columns = urwid.Columns([],dividechars=1) | 81 self.columns = urwid.Columns([], dividechars=1) |
80 if on_click: | 82 if on_click: |
81 urwid.connect_signal(self, 'click', on_click, user_data) | 83 urwid.connect_signal(self, 'click', on_click, user_data) |
82 if hand: | 84 if hand: |
83 self.update(hand) | 85 self.update(hand) |
84 urwid.WidgetWrap.__init__(self, self.columns) | 86 urwid.WidgetWrap.__init__(self, self.columns) |
87 return self.__selectable | 89 return self.__selectable |
88 | 90 |
89 def keypress(self, size, key): | 91 def keypress(self, size, key): |
90 | 92 |
91 if CardDisplayer in [wid.__class__ for wid in self.columns.widget_list]: | 93 if CardDisplayer in [wid.__class__ for wid in self.columns.widget_list]: |
92 return self.columns.keypress(size,key) | 94 return self.columns.keypress(size, key) |
93 else: | 95 else: |
94 #No card displayed, we still have to manage the clicks | 96 #No card displayed, we still have to manage the clicks |
95 if key == ' ': | 97 if key == ' ': |
96 self._emit('click', None) | 98 self._emit('click', None) |
97 return key | 99 return key |
111 del self.columns.column_types[:] | 113 del self.columns.column_types[:] |
112 self.columns.contents.append((urwid.Text(''),('weight',1, False))) | 114 self.columns.contents.append((urwid.Text(''),('weight',1, False))) |
113 for card in hand: | 115 for card in hand: |
114 widget = CardDisplayer(card) | 116 widget = CardDisplayer(card) |
115 self.columns.widget_list.append(widget) | 117 self.columns.widget_list.append(widget) |
116 self.columns.column_types.append(('fixed',3)) | 118 self.columns.column_types.append(('fixed', 3)) |
117 urwid.connect_signal(widget, 'click', self.__onClick) | 119 urwid.connect_signal(widget, 'click', self.__onClick) |
118 self.columns.contents.append((urwid.Text(''),('weight',1, False))) | 120 self.columns.contents.append((urwid.Text(''), ('weight', 1, False))) |
119 self.columns.set_focus(1) | 121 self.columns.set_focus(1) |
120 | 122 |
121 def __onClick(self,card_wid): | 123 def __onClick(self, card_wid): |
122 self._emit('click', card_wid) | 124 self._emit('click', card_wid) |
125 | |
123 | 126 |
124 class Card(TarotCard): | 127 class Card(TarotCard): |
125 """This class is used to represent a card, logically | 128 """This class is used to represent a card, logically |
126 and give a text representation with attributes""" | 129 and give a text representation with attributes""" |
127 SIZE = 3 #size of a displayed card | 130 SIZE = 3 # size of a displayed card |
128 | 131 |
129 def __init__(self, suit, value): | 132 def __init__(self, suit, value): |
130 """@param file: path of the PNG file""" | 133 """@param file: path of the PNG file""" |
131 TarotCard.__init__(self, (suit, value)) | 134 TarotCard.__init__(self, (suit, value)) |
132 | 135 |
133 def getAttrText(self): | 136 def getAttrText(self): |
134 """return text representation of the card with attributes""" | 137 """return text representation of the card with attributes""" |
135 try: | 138 try: |
136 value = "%02i" % int(self.value) | 139 value = "%02i" % int(self.value) |
137 except ValueError: | 140 except ValueError: |
138 value = self.value[0].upper()+self.value[1] | 141 value = self.value[0].upper() + self.value[1] |
139 if self.suit == "atout": | 142 if self.suit == "atout": |
140 if self.value == "excuse": | 143 if self.value == "excuse": |
141 suit = 'c' | 144 suit = 'c' |
142 else: | 145 else: |
143 suit = 'A' | 146 suit = 'A' |
154 elif self.suit == "carreau": | 157 elif self.suit == "carreau": |
155 suit = u'♦' | 158 suit = u'♦' |
156 color = 'red' | 159 color = 'red' |
157 if self.bout: | 160 if self.bout: |
158 color = 'special' | 161 color = 'special' |
159 return ('card_%s' % color,u"%s%s" % (value,suit)) | 162 return ('card_%s' % color, u"%s%s" % (value, suit)) |
160 | 163 |
161 def getWidget(self): | 164 def getWidget(self): |
162 """Return a widget representing the card""" | 165 """Return a widget representing the card""" |
163 return CardDisplayer(self) | 166 return CardDisplayer(self) |
167 | |
164 | 168 |
165 class Table(urwid.FlowWidget): | 169 class Table(urwid.FlowWidget): |
166 """Represent the cards currently on the table""" | 170 """Represent the cards currently on the table""" |
167 | 171 |
168 def __init__(self): | 172 def __init__(self): |
170 | 174 |
171 def putCard(self, location, card): | 175 def putCard(self, location, card): |
172 """Put a card on the table | 176 """Put a card on the table |
173 @param location: where to put the card (top, left, bottom or right) | 177 @param location: where to put the card (top, left, bottom or right) |
174 @param card: Card to play or None""" | 178 @param card: Card to play or None""" |
175 assert location in ['top','left','bottom','right'] | 179 assert location in ['top', 'left', 'bottom', 'right'] |
176 assert isinstance(card,Card) or card == None | 180 assert isinstance(card, Card) or card == None |
177 if [getattr(self, place) for place in ['top','left','bottom','right']].count(None) == 0: | 181 if [getattr(self, place) for place in ['top', 'left', 'bottom', 'right']].count(None) == 0: |
178 #If the table is full of card, we remove them | 182 #If the table is full of card, we remove them |
179 self.top = self.left = self.bottom = self.right = None | 183 self.top = self.left = self.bottom = self.right = None |
180 setattr(self, location, card) | 184 setattr(self, location, card) |
181 self._invalidate() | 185 self._invalidate() |
182 | 186 |
183 def rows(self,size,focus=False): | 187 def rows(self, size, focus=False): |
184 return self.display_widget(size, focus).rows(size, focus) | 188 return self.display_widget(size, focus).rows(size, focus) |
185 | 189 |
186 def render(self, size, focus=False): | 190 def render(self, size, focus=False): |
187 return self.display_widget(size, focus).render(size, focus) | 191 return self.display_widget(size, focus).render(size, focus) |
188 | 192 |
189 def display_widget(self, size, focus): | 193 def display_widget(self, size, focus): |
190 cards={} | 194 cards = {} |
191 max_col, = size | 195 max_col, = size |
192 separator = " - " | 196 separator = " - " |
193 margin = max((max_col-Card.SIZE)/2,0) * ' ' | 197 margin = max((max_col - Card.SIZE) / 2, 0) * ' ' |
194 margin_center = max((max_col-Card.SIZE*2-len(separator))/2,0) * ' ' | 198 margin_center = max((max_col - Card.SIZE * 2 - len(separator)) / 2, 0) * ' ' |
195 for location in ['top', 'left', 'bottom', 'right']: | 199 for location in ['top', 'left', 'bottom', 'right']: |
196 card = getattr(self,location) | 200 card = getattr(self, location) |
197 cards[location] = card.getAttrText() if card else Card.SIZE * ' ' | 201 cards[location] = card.getAttrText() if card else Card.SIZE * ' ' |
198 render_wid = [urwid.Text([margin,cards['top']]), | 202 render_wid = [urwid.Text([margin, cards['top']]), |
199 urwid.Text([margin_center,cards['left'],separator,cards['right']]), | 203 urwid.Text([margin_center, cards['left'], separator, cards['right']]), |
200 urwid.Text([margin,cards['bottom']])] | 204 urwid.Text([margin, cards['bottom']])] |
201 return urwid.Pile(render_wid) | 205 return urwid.Pile(render_wid) |
202 | 206 |
203 | 207 |
204 class CardGame(QuickCardGame,urwid.WidgetWrap): | 208 class CardGame(QuickCardGame, urwid.WidgetWrap): |
205 """Widget for card games""" | 209 """Widget for card games""" |
206 | 210 |
207 def __init__(self, parent, referee, players, player_nick): | 211 def __init__(self, parent, referee, players, player_nick): |
208 QuickCardGame.__init__(self, parent, referee, players, player_nick) | 212 QuickCardGame.__init__(self, parent, referee, players, player_nick) |
209 self.loadCards() | 213 self.loadCards() |
210 self.top = urwid.Pile([urwid.Padding(urwid.Text(self.top_nick), 'center')]) | 214 self.top = urwid.Pile([urwid.Padding(urwid.Text(self.top_nick), 'center')]) |
211 #self.parent.host.debug() | 215 #self.parent.host.debug() |
212 self.table = Table() | 216 self.table = Table() |
213 self.center = urwid.Columns([('fixed',len(self.left_nick),urwid.Filler(urwid.Text(self.left_nick))), | 217 self.center = urwid.Columns([('fixed', len(self.left_nick), urwid.Filler(urwid.Text(self.left_nick))), |
214 urwid.Filler(self.table), | 218 urwid.Filler(self.table), |
215 ('fixed',len(self.right_nick),urwid.Filler(urwid.Text(self.right_nick))) | 219 ('fixed', len(self.right_nick), urwid.Filler(urwid.Text(self.right_nick))) |
216 ]) | 220 ]) |
217 """urwid.Pile([urwid.Padding(self.top_card_wid,'center'), | 221 """urwid.Pile([urwid.Padding(self.top_card_wid,'center'), |
218 urwid.Columns([('fixed',len(self.left_nick),urwid.Text(self.left_nick)), | 222 urwid.Columns([('fixed',len(self.left_nick),urwid.Text(self.left_nick)), |
219 urwid.Padding(self.center_cards_wid,'center'), | 223 urwid.Padding(self.center_cards_wid,'center'), |
220 ('fixed',len(self.right_nick),urwid.Text(self.right_nick)) | 224 ('fixed',len(self.right_nick),urwid.Text(self.right_nick)) |
221 ]), | 225 ]), |
222 urwid.Padding(self.bottom_card_wid,'center') | 226 urwid.Padding(self.bottom_card_wid,'center') |
223 ])""" | 227 ])""" |
224 self.hand_wid = Hand(selectable = True, on_click = self.onClick) | 228 self.hand_wid = Hand(selectable=True, on_click=self.onClick) |
225 self.main_frame = urwid.Frame(self.center,header=self.top, footer=self.hand_wid, focus_part='footer') | 229 self.main_frame = urwid.Frame(self.center, header=self.top, footer=self.hand_wid, focus_part='footer') |
226 urwid.WidgetWrap.__init__(self,self.main_frame) | 230 urwid.WidgetWrap.__init__(self, self.main_frame) |
227 self.parent.host.bridge.tarotGameReady(player_nick, referee, self.parent.host.profile) | 231 self.parent.host.bridge.tarotGameReady(player_nick, referee, self.parent.host.profile) |
228 | 232 |
229 def loadCards(self): | 233 def loadCards(self): |
230 """Load all the cards in memory""" | 234 """Load all the cards in memory""" |
231 QuickCardGame.loadCards(self) | 235 QuickCardGame.loadCards(self) |
232 for value in map(str,range(1,22))+['excuse']: | 236 for value in map(str, range(1, 22)) + ['excuse']: |
233 card = Card('atout',value) | 237 card = Card('atout', value) |
234 self.cards[card.suit, card.value]=card | 238 self.cards[card.suit, card.value] = card |
235 self.deck.append(card) | 239 self.deck.append(card) |
236 for suit in ["pique", "coeur", "carreau", "trefle"]: | 240 for suit in ["pique", "coeur", "carreau", "trefle"]: |
237 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]: | 241 for value in map(str, range(1, 11)) + ["valet", "cavalier", "dame", "roi"]: |
238 card = Card(suit,value) | 242 card = Card(suit, value) |
239 self.cards[card.suit, card.value]=card | 243 self.cards[card.suit, card.value] = card |
240 self.deck.append(card) | 244 self.deck.append(card) |
241 | 245 |
242 def newGame(self, hand): | 246 def newGame(self, hand): |
243 """Start a new game, with given hand""" | 247 """Start a new game, with given hand""" |
244 QuickCardGame.newGame(self, hand) | 248 QuickCardGame.newGame(self, hand) |
253 | 257 |
254 def chooseContrat(self, xml_data): | 258 def chooseContrat(self, xml_data): |
255 """Called when the player as to select his contrat | 259 """Called when the player as to select his contrat |
256 @param xml_data: SàT xml representation of the form""" | 260 @param xml_data: SàT xml representation of the form""" |
257 misc = {'callback': self.contratSelected} | 261 misc = {'callback': self.contratSelected} |
258 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc) | 262 form = XMLUI(self.parent.host, xml_data, title=_('Please choose your contrat'), options=['NO_CANCEL'], misc=misc) |
259 form.show() | 263 form.show() |
260 | 264 |
261 def showCards(self, game_stage, cards, data): | 265 def showCards(self, game_stage, cards, data): |
262 """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" | 266 """Display cards in the middle of the game (to show for e.g. chien ou poignée)""" |
263 QuickCardGame.showCards(self, game_stage, cards, data) | 267 QuickCardGame.showCards(self, game_stage, cards, data) |
270 def showScores(self, xml_data, winners, loosers): | 274 def showScores(self, xml_data, winners, loosers): |
271 """Called when the player as to select hist contrat | 275 """Called when the player as to select hist contrat |
272 @param xml_data: SàT xml representation of the form""" | 276 @param xml_data: SàT xml representation of the form""" |
273 def _new_game(ignore): | 277 def _new_game(ignore): |
274 self.resetRound() | 278 self.resetRound() |
275 for location in ['top','left','bottom','right']: | 279 for location in ['top', 'left', 'bottom', 'right']: |
276 self.table.putCard(location, None) | 280 self.table.putCard(location, None) |
277 self.parent.host.redraw() | 281 self.parent.host.redraw() |
278 self.parent.host.bridge.tarotGameReady(self.player_nick, self.referee, self.parent.host.profile) | 282 self.parent.host.bridge.tarotGameReady(self.player_nick, self.referee, self.parent.host.profile) |
279 if not winners and not loosers: | 283 if not winners and not loosers: |
280 title = _("Draw game") | 284 title = _("Draw game") |
281 else: | 285 else: |
282 title = _('You win \o/') if self.player_nick in winners else _('You loose :(') | 286 title = _('You win \o/') if self.player_nick in winners else _('You loose :(') |
283 form = XMLUI(self.parent.host, xml_data, title = title, options = ['NO_CANCEL'], misc={'callback':_new_game}) | 287 form = XMLUI(self.parent.host, xml_data, title=title, options=['NO_CANCEL'], misc={'callback': _new_game}) |
284 form.show() | 288 form.show() |
285 | 289 |
286 def invalidCards(self, phase, played_cards, invalid_cards): | 290 def invalidCards(self, phase, played_cards, invalid_cards): |
287 """Invalid cards have been played | 291 """Invalid cards have been played |
288 @param phase: phase of the game | 292 @param phase: phase of the game |
289 @param played_cards: all the cards played | 293 @param played_cards: all the cards played |
290 @param invalid_cards: cards which are invalid""" | 294 @param invalid_cards: cards which are invalid""" |
291 QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards) | 295 QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards) |
292 self.hand_wid.update(self.hand) | 296 self.hand_wid.update(self.hand) |
293 if self._autoplay==None: #No dialog if there is autoplay | 297 if self._autoplay == None: # No dialog if there is autoplay |
294 self.parent.host.notify(_('Cards played are invalid !')) | 298 self.parent.host.notify(_('Cards played are invalid !')) |
295 self.parent.host.redraw() | 299 self.parent.host.redraw() |
296 | 300 |
297 def cardsPlayed(self, player, cards): | 301 def cardsPlayed(self, player, cards): |
298 """A card has been played by player""" | 302 """A card has been played by player""" |
299 QuickCardGame.cardsPlayed(self, player, cards) | 303 QuickCardGame.cardsPlayed(self, player, cards) |
300 self.table.putCard(self.getPlayerLocation(player),self.played[player]) | 304 self.table.putCard(self.getPlayerLocation(player), self.played[player]) |
301 self._checkState() | 305 self._checkState() |
302 self.parent.host.redraw() | 306 self.parent.host.redraw() |
303 | 307 |
304 def _checkState(self): | 308 def _checkState(self): |
305 if isinstance(self.center.widget_list[1].original_widget, Hand): #if we have a hand displayed | 309 if isinstance(self.center.widget_list[1].original_widget, Hand): # if we have a hand displayed |
306 self.center.widget_list[1] = urwid.Filler(self.table) #we show again the table | 310 self.center.widget_list[1] = urwid.Filler(self.table) # we show again the table |
307 if self.state == "chien": | 311 if self.state == "chien": |
308 self.to_show = [] | 312 self.to_show = [] |
309 self.state = "wait" | 313 self.state = "wait" |
310 elif self.state == "wait_for_ecart": | 314 elif self.state == "wait_for_ecart": |
311 self.state = "ecart" | 315 self.state = "ecart" |
312 self.hand.extend(self.to_show) | 316 self.hand.extend(self.to_show) |
313 self.hand.sort() | 317 self.hand.sort() |
314 self.to_show = [] | 318 self.to_show = [] |
315 self.hand_wid.update(self.hand) | 319 self.hand_wid.update(self.hand) |
316 | 320 |
317 | |
318 ##EVENTS## | 321 ##EVENTS## |
319 def onClick(self, hand, card_wid): | 322 def onClick(self, hand, card_wid): |
320 """Called when user do an action on the hand""" | 323 """Called when user do an action on the hand""" |
321 if not self.state in ['play','ecart','wait_for_ecart']: | 324 if not self.state in ['play', 'ecart', 'wait_for_ecart']: |
322 #it's not our turn, we ignore the click | 325 #it's not our turn, we ignore the click |
323 card_wid.select(False) | 326 card_wid.select(False) |
324 return | 327 return |
325 self._checkState() | 328 self._checkState() |
326 if self.state == "ecart": | 329 if self.state == "ecart": |
327 if len(self.hand_wid.getSelected()) == 6: | 330 if len(self.hand_wid.getSelected()) == 6: |
328 pop_up_widget = sat_widgets.ConfirmDialog(_("Do you put these cards in chien ?"), yes_cb=self.onEcartDone, no_cb=self.parent.host.removePopUp) | 331 pop_up_widget = sat_widgets.ConfirmDialog(_("Do you put these cards in chien ?"), yes_cb=self.onEcartDone, no_cb=self.parent.host.removePopUp) |
329 self.parent.host.showPopUp(pop_up_widget) | 332 self.parent.host.showPopUp(pop_up_widget) |
330 elif self.state == "play": | 333 elif self.state == "play": |
331 card = card_wid.getCard() | 334 card = card_wid.getCard() |
332 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, [(card.suit, card.value)], self.parent.host.profile) | 335 self.parent.host.bridge.tarotGamePlayCards(self.player_nick, self.referee, [(card.suit, card.value)], self.parent.host.profile) |
333 self.hand.remove(card) | 336 self.hand.remove(card) |
334 self.hand_wid.update(self.hand) | 337 self.hand_wid.update(self.hand) |
335 self.state = "wait" | 338 self.state = "wait" |
336 | 339 |
337 def onEcartDone(self,button): | 340 def onEcartDone(self, button): |
338 """Called when player has finished is écart""" | 341 """Called when player has finished his écart""" |
339 ecart = [] | 342 ecart = [] |
340 for card in self.hand_wid.getSelected(): | 343 for card in self.hand_wid.getSelected(): |
341 ecart.append((card.suit, card.value)) | 344 ecart.append((card.suit, card.value)) |
342 self.hand.remove(card) | 345 self.hand.remove(card) |
343 self.hand_wid.update(self.hand) | 346 self.hand_wid.update(self.hand) |