comparison frontends/wix/card_game.py @ 144:80661755ea8d

Primitivus: Tarot card game implementation - quick frontend: card_game added - wix: card_game splitted with quick frontend - tools: new game library - primitivus: new card_game widget (not finished yet) - primitivus: SàT XML UI management: first draft
author Goffi <goffi@goffi.org>
date Mon, 26 Jul 2010 19:43:44 +0800
parents 8c80d4dec7a8
children 63d20bda5754
comparison
equal deleted inserted replaced
143:119f45746fde 144:80661755ea8d
25 import os.path, glob 25 import os.path, glob
26 import pdb 26 import pdb
27 from logging import debug, info, error 27 from logging import debug, info, error
28 from tools.jid import JID 28 from tools.jid import JID
29 from tools.games import TarotCard 29 from tools.games import TarotCard
30 from quick_frontend.quick_card_game import QuickCardGame
30 from xmlui import XMLUI 31 from xmlui import XMLUI
31 32
32 CARD_WIDTH = 74 33 CARD_WIDTH = 74
33 CARD_HEIGHT = 136 34 CARD_HEIGHT = 136
34 MIN_WIDTH = 950 #Minimum size of the panel 35 MIN_WIDTH = 950 #Minimum size of the panel
35 MIN_HEIGHT = 500 36 MIN_HEIGHT = 500
36 37
37 class wxCard(TarotCard): 38 class WxCard(TarotCard):
38 """This class is used to represent a card, graphically and logically""" 39 """This class is used to represent a card, graphically and logically"""
39 40
40 def __init__(self, file): 41 def __init__(self, file):
41 """@param file: path of the PNG file""" 42 """@param file: path of the PNG file"""
42 self.bitmap = wx.Image(file).ConvertToBitmap() 43 self.bitmap = wx.Image(file).ConvertToBitmap()
43 root_name = os.path.splitext(os.path.basename(file))[0] 44 root_name = os.path.splitext(os.path.basename(file))[0]
44 self.suit,self.value=root_name.split('_') 45 suit,value = root_name.split('_')
45 TarotCard.__init__(self, (self.suit, self.value)) 46 TarotCard.__init__(self, (suit, value))
46 print "Carte:",self.suit, self.value #, self.bout 47 print "Carte:",suit, value #, self.bout
47 48
48 def draw(self, dc, x, y): 49 def draw(self, dc, x, y):
49 """Draw the card on the device context 50 """Draw the card on the device context
50 @param dc: device context 51 @param dc: device context
51 @param x: abscissa 52 @param x: abscissa
52 @param y: ordinate""" 53 @param y: ordinate"""
53 dc.DrawBitmap(self.bitmap, x, y, True) 54 dc.DrawBitmap(self.bitmap, x, y, True)
54 55
55 56
56 class CardPanel(wx.Panel): 57 class CardPanel(QuickCardGame,wx.Panel):
57 """This class is used to display the cards""" 58 """This class is used to display the cards"""
58 59
59 def __init__(self, parent, referee, players, player_nick): 60 def __init__(self, parent, referee, players, player_nick):
61 QuickCardGame.__init__(self, parent, referee, players, player_nick)
60 wx.Panel.__init__(self, parent) 62 wx.Panel.__init__(self, parent)
61 self.parent = parent
62 self.referee = referee
63 self.players = players
64 self.played = {}
65 for player in players:
66 self.played[player] = None
67 self.player_nick = player_nick
68 self.bottom_nick = self.player_nick
69 idx = self.players.index(self.player_nick)
70 idx = (idx + 1) % len(self.players)
71 self.right_nick = self.players[idx]
72 idx = (idx + 1) % len(self.players)
73 self.top_nick = self.players[idx]
74 idx = (idx + 1) % len(self.players)
75 self.left_nick = self.players[idx]
76 self.bottom_nick = player_nick
77 self.SetMinSize(wx.Size(MIN_WIDTH, MIN_HEIGHT)) 63 self.SetMinSize(wx.Size(MIN_WIDTH, MIN_HEIGHT))
78 self.load_cards("/home/goffi/dev/divers/images/cards/") 64 self.loadCards("/home/goffi/dev/divers/images/cards/")
79 self.mouse_over_card = None #contain the card to highlight 65 self.mouse_over_card = None #contain the card to highlight
80 self.selected = [] #Card choosed by the player (e.g. during ecart)
81 self.hand_size = 13 #number of cards in a hand
82 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards 66 self.visible_size = CARD_WIDTH/2 #number of pixels visible for cards
83 self.hand = [] 67 self.hand = []
84 self.to_show = [] 68 self.to_show = []
85 self.state = None 69 self.state = None
86 self.SetBackgroundColour(wx.GREEN) 70 self.SetBackgroundColour(wx.GREEN)
88 self.Bind(wx.EVT_PAINT, self.onPaint) 72 self.Bind(wx.EVT_PAINT, self.onPaint)
89 self.Bind(wx.EVT_MOTION, self.onMouseMove) 73 self.Bind(wx.EVT_MOTION, self.onMouseMove)
90 self.Bind(wx.EVT_LEFT_UP, self.onMouseClick) 74 self.Bind(wx.EVT_LEFT_UP, self.onMouseClick)
91 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile) 75 self.parent.host.bridge.tarotGameReady(player_nick, referee, profile_key = self.parent.host.profile)
92 76
93 def load_cards(self, dir): 77 def loadCards(self, dir):
94 """Load all the cards in memory 78 """Load all the cards in memory
95 @param dir: directory where the PNG files are""" 79 @param dir: directory where the PNG files are"""
96 self.cards={} 80 QuickCardGame.loadCards(self)
97 self.deck=[]
98 self.cards["atout"]={} #As Tarot is a french game, it's more handy & logical to keep french names
99 self.cards["pique"]={} #spade
100 self.cards["coeur"]={} #heart
101 self.cards["carreau"]={} #diamond
102 self.cards["trefle"]={} #club
103 for file in glob.glob(dir+'/*_*.png'): 81 for file in glob.glob(dir+'/*_*.png'):
104 card = wxCard(file) 82 card = WxCard(file)
105 self.cards[card.suit, card.value]=card 83 self.cards[card.suit, card.value]=card
106 self.deck.append(card) 84 self.deck.append(card)
107 """for value in map(str,range(1,22))+['excuse']:
108 self.idx_cards.append(self.cards["atout",value])
109 for suit in ["pique", "coeur", "carreau", "trefle"]:
110 for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]:
111 self.idx_cards.append(self.cards[suit, value])""" #XXX: no need to sort the cards !
112 85
113 def newGame(self, hand): 86 def newGame(self, hand):
114 """Start a new game, with given hand""" 87 """Start a new game, with given hand"""
115 assert (len(self.hand) == 0) 88 QuickCardGame.newGame(self, hand)
116 for suit, value in hand:
117 self.hand.append(self.cards[suit, value])
118 self.hand.sort()
119 self.state = "init"
120 self._recalc_ori() 89 self._recalc_ori()
121 self.Refresh() 90 self.Refresh()
122 91
123 def contratSelected(self, data): 92 def contratSelected(self, data):
124 """Called when the contrat has been choosed 93 """Called when the contrat has been choosed
125 @param data: form result""" 94 @param data: form result"""
126 debug (_("Contrat choosed")) 95 debug (_("Contrat choosed"))
127 contrat = data[0][1] 96 contrat = data[0][1]
128 self.parent.host.bridge.tarotGameContratChoosed(self.player_nick, self.referee, contrat or 'Passe', self.parent.host.profile) 97 QuickCardGame.contratSelected(self, contrat)
129 98
130 def chooseContrat(self, xml_data): 99 def chooseContrat(self, xml_data):
131 """Called when the player as to select hist contrat 100 """Called when the player as to select his contrat
132 @param xml_data: SàT xml representation of the form""" 101 @param xml_data: SàT xml representation of the form"""
133 misc = {'callback': self.contratSelected} 102 misc = {'callback': self.contratSelected}
134 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc) 103 form = XMLUI(self.parent.host, xml_data, title = _('Please choose your contrat'), options = ['NO_CANCEL'], misc = misc)
135
136 def showCards(self, game_stage, cards, data):
137 """Display cards in the middle of the game (to show for e.g. chien ou poignée)"""
138 self.to_show = []
139 for suit, value in cards:
140 self.to_show.append(self.cards[suit, value])
141 if game_stage == "chien" and data['attaquant'] == self.player_nick:
142 self.state = "wait_for_ecart"
143 else:
144 self.state = "chien"
145
146 def MyTurn(self):
147 """Called when we have to play :)"""
148 if self.state == "chien":
149 self.to_show = []
150 self.state = "play"
151 104
152 def showScores(self, xml_data, winners, loosers): 105 def showScores(self, xml_data, winners, loosers):
153 """Called when the player as to select hist contrat 106 """Called when the player as to select hist contrat
154 @param xml_data: SàT xml representation of the form""" 107 @param xml_data: SàT xml representation of the form"""
155 form = XMLUI(self.parent.host, xml_data, title = _('You win \o/') if self.player_nick in winners else _('You loose :('), options = ['NO_CANCEL']) 108 form = XMLUI(self.parent.host, xml_data, title = _('You win \o/') if self.player_nick in winners else _('You loose :('), options = ['NO_CANCEL'])
156 109
157 def cardsPlayed(self, player, cards): 110 def cardsPlayed(self, player, cards):
158 """A card has been played by player""" 111 """A card has been played by player"""
159 if self.to_show: 112 QuickCardGame.cardsPlayed(self, player, cards)
160 self.to_show = []
161 pl_cards = []
162 if self.played[player] != None: #gof: à supprimer
163 for pl in self.played:
164 self.played[pl] = None
165 for suit, value in cards:
166 pl_cards.append(self.cards[suit, value])
167 self.played[player] = pl_cards[0]
168 self.Refresh() 113 self.Refresh()
169 114
170 def invalidCards(self, phase, played_cards, invalid_cards): 115 def invalidCards(self, phase, played_cards, invalid_cards):
171 """Invalid cards have been played 116 """Invalid cards have been played
172 @param phase: phase of the game 117 @param phase: phase of the game
173 @param played_cards: all the cards played 118 @param played_cards: all the cards played
174 @param invalid_cards: cards which are invalid""" 119 @param invalid_cards: cards which are invalid"""
175 120 QuickCardGame.invalidCards(self, phase, played_cards, invalid_cards)
176 if phase == "play": 121
177 self.state = "play"
178 elif phase == "ecart":
179 self.state = "ecart"
180 else:
181 error ('INTERNAL ERROR: unmanaged game phase')
182
183 for suit, value in played_cards:
184 self.hand.append(self.cards[suit, value])
185
186 self._recalc_ori() 122 self._recalc_ori()
187 self.Refresh() 123 self.Refresh()
188 self.hand.sort()
189 wx.MessageDialog(self, _("Cards played are invalid !"), _("Error"), wx.OK | wx.ICON_ERROR).ShowModal() 124 wx.MessageDialog(self, _("Cards played are invalid !"), _("Error"), wx.OK | wx.ICON_ERROR).ShowModal()
190
191
192
193 125
194 def _is_on_hand(self, pos_x, pos_y): 126 def _is_on_hand(self, pos_x, pos_y):
195 """Return True if the coordinate are on the hand cards""" 127 """Return True if the coordinate are on the hand cards"""
196 if pos_x > self.orig_x and pos_y > self.orig_y \ 128 if pos_x > self.orig_x and pos_y > self.orig_y \
197 and pos_x < self.orig_x + (len(self.hand)+1) * self.visible_size \ 129 and pos_x < self.orig_x + (len(self.hand)+1) * self.visible_size \