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)