diff --git a/pysollib/app.py b/pysollib/app.py index a1022d71..7da29e8a 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -150,15 +150,14 @@ class Options: # fonts self.fonts = {"default" : None, #"default" : ("helvetica", 12), - "sans" : ("times", 14), # for html - "fixed" : ("courier", 14), # for html & log + "sans" : ("times", 12), # for html + "fixed" : ("courier", 12), # for html & log "small" : ("helvetica", 12), "canvas_default" : ("helvetica", 12), #"canvas_card" : ("helvetica", 12), "canvas_fixed" : ("courier", 12), - "canvas_large" : ("helvetica", 18), - "canvas_small" : ("helvetica", 12), # not used? - #"tree_small" : ("helvetica", 12), + "canvas_large" : ("helvetica", 16), + "canvas_small" : ("helvetica", 10), } if os.name == 'posix': self.fonts["sans"] = ("helvetica", 12) @@ -579,6 +578,8 @@ class Application: ) self.commandline = Struct( loadgame = None, # load a game ? + game = None, + gameid = None, ) self.demo_counter = 0 @@ -619,12 +620,21 @@ class Application: game.destruct() destruct(game) game = None - if self.commandline.loadgame and not self.nextgame.loadedgame: - try: - self.nextgame.loadedgame = tmpgame._loadGame(self.commandline.loadgame, self) - self.nextgame.loadedgame.gstats.holded = 0 - except: - self.nextgame.loadedgame = None + if not self.nextgame.loadedgame: + if self.commandline.loadgame: + try: + self.nextgame.loadedgame = tmpgame._loadGame(self.commandline.loadgame, self) + self.nextgame.loadedgame.gstats.holded = 0 + except: + self.nextgame.loadedgame = None + elif not self.commandline.game is None: + gameid = self.gdb.getGameByName(self.commandline.game) + if gameid is None: + print >> sys.stderr, "WARNING: can't find game:", self.commandline.game + else: + self.nextgame.id, self.nextgame.random = gameid, None + elif not self.commandline.gameid is None: + self.nextgame.id, self.nextgame.random = self.commandline.gameid, None self.opt.game_holded = 0 tmpgame.destruct() destruct(tmpgame) diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index bde03651..e1e124f6 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -572,6 +572,13 @@ class GameManager: self.getGamesIdSortedByName() return self.__games_by_altname + # find game by name + def getGameByName(self, name): + gi = self.__all_gamenames.get(name) + if gi: + return gi.id + return None + # /*********************************************************************** # // diff --git a/pysollib/games/camelot.py b/pysollib/games/camelot.py index 0e1ea5b8..0231c7e5 100644 --- a/pysollib/games/camelot.py +++ b/pysollib/games/camelot.py @@ -222,6 +222,8 @@ class SlyFox_Foundation(SS_FoundationStack): if not SS_FoundationStack.acceptsCards(self, from_stack, cards): return False if from_stack in self.game.s.rows: + if len(self.game.s.talon.cards) == 0: + return True return self.game.num_dealled <= 0 return True @@ -332,10 +334,47 @@ class SlyFox(Game): self.texts.misc.config(text=text) +class OpenSlyFox(SlyFox): + + def createGame(self): + playcards = 6 + + l, s = Layout(self), self.s + self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+2*playcards*l.YOFFSET+l.TEXT_HEIGHT) + + x, y = l.XM, l.YM + s.talon = SlyFox_Talon(x, y, self) + s.waste = s.talon + l.createText(s.talon, 'ne') + tx, ty, ta, tf = l.getTextAttr(s.talon, "ss") + font = self.app.getFont("canvas_default") + self.texts.misc = MfxCanvasText(self.canvas, tx, ty, + anchor=ta, font=font) + + x += 2*l.XS + for i in range(4): + s.foundations.append(SlyFox_Foundation(x, y, self, suit=i)) + s.foundations.append(SlyFox_Foundation(x+4*l.XS, y, self, suit=i, + base_rank=KING, dir=-1)) + x += l.XS + y = l.YM+l.YS+l.TEXT_HEIGHT + for i in range(2): + x = l.XM + for j in range(10): + stack = SlyFox_RowStack(x, y, self, max_cards=UNLIMITED_CARDS) + s.rows.append(stack) + stack.CARD_YOFFSET = l.YOFFSET + x += l.XS + y += l.YS+playcards*l.YOFFSET + + l.defaultStackGroups() + # register the game registerGame(GameInfo(280, Camelot, "Camelot", GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(610, SlyFox, "Sly Fox", - GI.GT_NUMERICA, 2, 0, GI.SL_MOSTLY_SKILL)) + GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(614, OpenSlyFox, "Open Sly Fox", + GI.GT_NUMERICA | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/games/grandduchess.py b/pysollib/games/grandduchess.py index 57f92061..72027fc5 100644 --- a/pysollib/games/grandduchess.py +++ b/pysollib/games/grandduchess.py @@ -78,16 +78,25 @@ class GrandDuchess(Game): # game layout # - def createGame(self): + def createGame(self, rows=4): # create layout + max_rows = max(10, 4+rows) l, s = Layout(self), self.s # set window - w, h = l.XM+9*l.XS, l.YM+2*l.YS+18*l.YOFFSET + w, h = l.XM+max_rows*l.XS, l.YM+2*l.YS+18*l.YOFFSET self.setSize(w, h) # create stacks x, y = l.XM, l.YM + s.talon = GrandDuchess_Talon(x, y, self, max_rounds=4) + l.createText(s.talon, 'se') + tx, ty, ta, tf = l.getTextAttr(s.talon, 'ne') + font = self.app.getFont('canvas_default') + s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, + anchor=ta, font=font) + + x += 2*l.XS for i in range(4): s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) x += l.XS @@ -95,25 +104,18 @@ class GrandDuchess(Game): s.foundations.append(SS_FoundationStack(x, y, self, suit=i, base_rank=KING, dir=-1)) x += l.XS - x, y = l.XM+2*l.XS, l.YM+l.YS - for i in range(4): + x, y = l.XM+(max_rows-rows)*l.XS/2, l.YM+l.YS + for i in range(rows): stack = BasicRowStack(x, y, self, max_move=1, max_accept=0) stack.CARD_YOFFSET = l.YOFFSET s.rows.append(stack) x += l.XS - x, y = l.XM, l.YM+l.YS + dx = (max_rows-rows)*l.XS/4-l.XS/2 + x, y = l.XM+dx, l.YM+l.YS s.reserves.append(GrandDuchess_Reserve(x, y, self)) - x, y = l.XM+7*l.XS, l.YM+l.YS + x, y = self.width-dx-l.XS, l.YM+l.YS s.reserves.append(GrandDuchess_Reserve(x, y, self)) - x, y = self.width-l.XS, self.height-l.YS - s.talon = GrandDuchess_Talon(x, y, self, max_rounds=4) - l.createText(s.talon, 'n') - tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") - font = self.app.getFont("canvas_default") - s.talon.texts.rounds = MfxCanvasText(self.canvas, - tx, ty-l.TEXT_MARGIN, - anchor=ta, font=font) # define stack-groups l.defaultStackGroups() @@ -133,7 +135,34 @@ class GrandDuchess(Game): return ((), (), self.sg.dropstacks) +# /*********************************************************************** +# // Parisienne +# ************************************************************************/ + +class Parisienne(GrandDuchess): + def _shuffleHook(self, cards): + # move one Ace and one King of each suit to top of the Talon + # (i.e. first cards to be dealt) + return self._shuffleHookMoveToTop(cards, + lambda c: (c.rank in (ACE, KING) and c.deck == 0, (c.rank, c.suit))) + + def startGame(self): + self.s.talon.dealRow(rows=self.s.foundations, frames=0) + GrandDuchess.startGame(self) + + +class GrandDuchessPlus(GrandDuchess): + def createGame(self): + GrandDuchess.createGame(self, rows=6) + + + registerGame(GameInfo(557, GrandDuchess, "Grand Duchess", GI.GT_2DECK_TYPE, 2, 3)) - +registerGame(GameInfo(617, Parisienne, "Parisienne", + GI.GT_2DECK_TYPE, 2, 3, + rules_filename='grandduchess.html', + altnames=('La Parisienne', 'Parisian') )) +registerGame(GameInfo(618, GrandDuchessPlus, "Grand Duchess +", + GI.GT_2DECK_TYPE, 2, 3)) diff --git a/pysollib/games/katzenschwanz.py b/pysollib/games/katzenschwanz.py index 2c737756..970a1a02 100644 --- a/pysollib/games/katzenschwanz.py +++ b/pysollib/games/katzenschwanz.py @@ -178,7 +178,7 @@ class Kings(DerKatzenschwanz): def _shuffleHook(self, cards): for c in cards[:]: - if c.rank == 12: + if c.rank == KING: cards.remove(c) break cards.append(c) @@ -289,7 +289,7 @@ class SalicLaw(DerKatzenschwanz): y += l.YS x, y = l.XM, l.YM+l.YS*len(self.Foundation_Classes) - self.setRegion(s.foundations[-8:], (-999, -999, 999999, y - l.XM / 2)) + self.setRegion(s.foundations, (-999, -999, 999999, y - l.XM / 2)) for i in range(8): stack = self.RowStack_Class(x, y, self, max_move=1) stack.CARD_XOFFSET = xoffset @@ -350,44 +350,6 @@ class Deep(DerKatzenschwanz): self.s.talon.dealRow() -# /*********************************************************************** -# // Laggard Lady -# ************************************************************************/ - -class LaggardLady_RowStack(OpenStack): - def acceptsCards(self, from_stack, cards): - if not OpenStack.acceptsCards(self, from_stack, cards): - return False - return len(self.game.s.talon.cards) == 0 and len(self.cards) == 1 - - -class LaggardLady(SalicLaw): - - Foundation_Classes = [ - StackWrapper(RK_FoundationStack, base_rank=5, max_cards=6), - StackWrapper(RK_FoundationStack, base_rank=4, max_cards=6, dir=-1, mod=13), - ] - RowStack_Class = StackWrapper(LaggardLady_RowStack, max_accept=1, min_cards=1) - - ROW_BASE_RANK = QUEEN - - def _shuffleHook(self, cards): - for c in cards[:]: - if c.rank == QUEEN: - cards.remove(c) - break - cards.append(c) - return cards - - def isGameWon(self): - if self.s.talon.cards: - return False - for s in self.s.foundations: - if len(s.cards) != 6: - return False - return True - - # /*********************************************************************** # // Faerie Queen # ************************************************************************/ @@ -423,9 +385,64 @@ class FaerieQueen(SalicLaw): # /*********************************************************************** +# // Intrigue +# // Laggard Lady # // Glencoe # ************************************************************************/ +class Intrigue_RowStack(OpenStack): + def acceptsCards(self, from_stack, cards): + if not OpenStack.acceptsCards(self, from_stack, cards): + return False + return len(self.game.s.talon.cards) == 0 and len(self.cards) == 1 + + +class Intrigue(SalicLaw): + + Foundation_Classes = [ + StackWrapper(RK_FoundationStack, base_rank=5, max_cards=6), + StackWrapper(RK_FoundationStack, base_rank=4, max_cards=6, dir=-1, mod=13), + ] + RowStack_Class = StackWrapper(Intrigue_RowStack, max_accept=1, min_cards=1) + + ROW_BASE_RANK = QUEEN + + def _shuffleHook(self, cards): + for c in cards[:]: + if c.rank == QUEEN: + cards.remove(c) + break + cards.append(c) + return cards + + def isGameWon(self): + if self.s.talon.cards: + return False + for s in self.s.foundations: + if len(s.cards) != 6: + return False + return True + + +class LaggardLady_Foundation(RK_FoundationStack): + def acceptsCards(self, from_stack, cards): + if not RK_FoundationStack.acceptsCards(self, from_stack, cards): + return False + c = cards[0] + if c.rank in (4, 5): + i = list(self.game.s.foundations).index(self) % 8 + r = self.game.s.rows[i] + if not r.cards: + return False + return True + +class LaggardLady(Intrigue): + Foundation_Classes = [ + StackWrapper(LaggardLady_Foundation, base_rank=5, max_cards=6), + StackWrapper(LaggardLady_Foundation, base_rank=4, max_cards=6, dir=-1, mod=13), + ] + + class Glencoe_Foundation(RK_FoundationStack): def acceptsCards(self, from_stack, cards): if not RK_FoundationStack.acceptsCards(self, from_stack, cards): @@ -439,16 +456,13 @@ class Glencoe_Foundation(RK_FoundationStack): return c.suit == r.cards[0].suit return True - -class Glencoe(LaggardLady): - +class Glencoe(Intrigue): Foundation_Classes = [ StackWrapper(Glencoe_Foundation, base_rank=5, max_cards=6), StackWrapper(Glencoe_Foundation, base_rank=4, max_cards=6, dir=-1, mod=13), ] - # register the game registerGame(GameInfo(141, DerKatzenschwanz, "Cat's Tail", GI.GT_FREECELL | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL, @@ -464,11 +478,16 @@ registerGame(GameInfo(299, SalicLaw, "Salic Law", GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(442, Deep, "Deep", GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) -registerGame(GameInfo(523, LaggardLady, "Laggard Lady", +registerGame(GameInfo(523, Intrigue, "Intrigue", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(611, FaerieQueen, "Faerie Queen", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(612, Glencoe, "Glencoe", - GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED, + rules_filename="intrigue.html")) +registerGame(GameInfo(616, LaggardLady, "Laggard Lady", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED, + rules_filename="intrigue.html")) + diff --git a/pysollib/games/parallels.py b/pysollib/games/parallels.py index eec12e78..ce5f4cb2 100644 --- a/pysollib/games/parallels.py +++ b/pysollib/games/parallels.py @@ -35,6 +35,7 @@ from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint # /*********************************************************************** # // Parallels +# // British Blockade # ************************************************************************/ class Parallels_RowStack(BasicRowStack): @@ -167,9 +168,22 @@ class Parallels(Game): self.s.talon.dealRow(rows=self.s.rows[:10]) +class BritishBlockade(Parallels): + + def fillStack(self, stack): + if not stack.cards and stack in self.s.rows: + if self.s.talon.cards: + old_state = self.enterState(self.S_FILL) + self.s.talon.flipMove() + self.s.talon.moveMove(1, stack) + self.leaveState(old_state) + + # register the game registerGame(GameInfo(428, Parallels, "Parallels", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(615, BritishBlockade, "British Blockade", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) diff --git a/pysollib/games/pyramid.py b/pysollib/games/pyramid.py index ba7ee49e..5a23824c 100644 --- a/pysollib/games/pyramid.py +++ b/pysollib/games/pyramid.py @@ -595,6 +595,86 @@ class Fifteens(Elevens): self.leaveState(old_state) +# /*********************************************************************** +# // Triple Alliance +# ************************************************************************/ + +class TripleAlliance_Reserve(ReserveStack): + def acceptsCards(self, from_stack, cards): + if not ReserveStack.acceptsCards(self, from_stack, cards): + return False + r_ranks = [] + for r in self.game.s.reserves: + if r.cards: + r_ranks.append(r.cards[0].rank) + if not r_ranks: + return True + r_ranks.append(cards[0].rank) + r_ranks.sort() + if len(r_ranks) == 2: + return r_ranks[1]-r_ranks[0] in (1, 12) + for i in range(3): + j, k = (i+1)%3, (i+2)%3 + if ((r_ranks[i]+1) % 13 == r_ranks[j] and + (r_ranks[j]+1) % 13 == r_ranks[k]): + return True + return False + + +class TripleAlliance(Game): + + def createGame(self): + + l, s = Layout(self), self.s + w0 = l.XS+5*l.XOFFSET + self.setSize(l.XM+5*w0, l.YM+5*l.YS) + + x, y = l.XM, l.YM + for i in range(3): + s.reserves.append(TripleAlliance_Reserve(x, y, self)) + x += l.XS + x, y = self.width-l.XS, l.YM + s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT, + max_move=0, max_accept=0, max_cards=52)) + y = l.YM+l.YS + nstacks = 0 + for i in range(4): + x = l.XM + for j in range(5): + stack = BasicRowStack(x, y, self, max_accept=0) + s.rows.append(stack) + stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 + x += w0 + nstacks += 1 + if nstacks >= 18: + break + y += l.YS + + x, y = self.width-l.XS, self.height-l.YS + s.talon = InitialDealTalonStack(x, y, self) + + l.defaultStackGroups() + + def startGame(self): + self.s.talon.dealRow(frames=0) + self.s.talon.dealRow(frames=0) + self.startDealSample() + self.s.talon.dealRowAvail() + + def fillStack(self, stack): + for r in self.s.reserves: + if not r.cards: + return + if not self.demo: + self.playSample("droppair", priority=200) + old_state = self.enterState(self.S_FILL) + for r in self.s.reserves: + r.moveMove(1, self.s.foundations[0]) + self.leaveState(old_state) + + def isGameWon(self): + return len(self.s.foundations[0].cards) == 51 + # register the game registerGame(GameInfo(38, Pyramid, "Pyramid", @@ -615,6 +695,7 @@ registerGame(GameInfo(596, SuitElevens, "Suit Elevens", GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK)) registerGame(GameInfo(597, Fifteens, "Fifteens", GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) - +registerGame(GameInfo(619, TripleAlliance, "Triple Alliance", + GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/games/sultan.py b/pysollib/games/sultan.py index b3363a1c..d358bf25 100644 --- a/pysollib/games/sultan.py +++ b/pysollib/games/sultan.py @@ -417,27 +417,29 @@ class Matrimony_Talon(DealRowTalonStack): rows = self.game.s.rows r = self.game.s.rows[-self.round] for i in range(len(r.cards)): - num_cards = num_cards + 1 + num_cards += 1 self.game.moveMove(1, r, self, frames=4) self.game.flipMove(self) assert len(self.cards) == num_cards self.game.nextRoundMove(self) + return num_cards def dealCards(self, sound=0): if sound: self.game.startDealSample() + num_cards = 0 if len(self.cards) == 0: - self._redeal() + num_cards += self._redeal() if self.round == 1: - n = self.dealRowAvail(sound=0) + num_cards += self.dealRowAvail(sound=0) else: rows = self.game.s.rows[-self.round+1:] - n = self.dealRowAvail(rows=rows, sound=0) + num_cards += self.dealRowAvail(rows=rows, sound=0) while self.cards: - n += self.dealRowAvail(rows=self.game.s.rows, sound=0) + num_cards += self.dealRowAvail(rows=self.game.s.rows, sound=0) if sound: self.game.stopSamples() - return n + return num_cards class Matrimony(Game): diff --git a/pysollib/main.py b/pysollib/main.py index 04e9e9dc..4c0629a1 100644 --- a/pysollib/main.py +++ b/pysollib/main.py @@ -84,8 +84,9 @@ Please check your %s installation. def parse_option(argv): prog_name = argv[0] try: - optlist, args = getopt.getopt(argv[1:], "hD:", - ["fg=", "foreground=", + optlist, args = getopt.getopt(argv[1:], "g:i:hD:", + ["game=", "gameid=", + "fg=", "foreground=", "bg=", "background=", "fn=", "font=", "noplugins", @@ -97,6 +98,8 @@ def parse_option(argv): % (prog_name, err, prog_name) return None opts = {"help": False, + "game": None, + "gameid": None, "fg": None, "bg": None, "fn": None, @@ -107,6 +110,10 @@ def parse_option(argv): for i in optlist: if i[0] in ("-h", "--help"): opts["help"] = True + elif i[0] in ("-g", "--game"): + opts["game"] = i[1] + elif i[0] in ("-i", "--gameid"): + opts["gameid"] = i[1] elif i[0] in ("--fg", "--foreground"): opts["fg"] = i[1] elif i[0] in ("--bg", "--background"): @@ -122,6 +129,7 @@ def parse_option(argv): if opts["help"]: print _("""Usage: %s [OPTIONS] [FILE] + -g --game=GAMENAME start game GAMENAME --fg --foreground=COLOR foreground color --bg --background=COLOR background color --fn --font=FONT default font @@ -177,6 +185,12 @@ def pysol_init(app, args): wm_command = prog + " " + os.path.abspath(argv0) if filename: app.commandline.loadgame = filename + app.commandline.game = opts['game'] + if not opts['gameid'] is None: + try: + app.commandline.gameid = int(opts['gameid']) + except: + print >> sys.stderr, 'WARNING: invalide game id:', opts['gameid'] app.debug = int(opts['debug']) # init games database diff --git a/pysollib/tk/findcarddialog.py b/pysollib/tk/findcarddialog.py index 3bd9ac14..cd2115d8 100644 --- a/pysollib/tk/findcarddialog.py +++ b/pysollib/tk/findcarddialog.py @@ -41,17 +41,24 @@ from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectang # // # ************************************************************************/ -class FindCardDialog(Tkinter.Toplevel): - SUIT_IMAGES = {} # key: (suit, color) - RANK_IMAGES = {} # key: (rank, color) +LARGE_EMBLEMS_SIZE = (38, 34) +SMALL_EMBLEMS_SIZE = (31, 21) - def __init__(self, parent, game, dir): +class FindCardDialog(Tkinter.Toplevel): + CARD_IMAGES = {} # key: (rank, suit) + + def __init__(self, parent, game, dir, size='large'): Tkinter.Toplevel.__init__(self) self.title(_('Find card')) self.wm_resizable(0, 0) # - self.images_dir = dir - self.label_width, self.label_height = 38, 34 + ##self.images_dir = dir + if size == 'large': + self.images_dir = os.path.join(dir, 'large-emblems') + self.label_width, self.label_height = LARGE_EMBLEMS_SIZE + else: + self.images_dir = os.path.join(dir, 'small-emblems') + self.label_width, self.label_height = SMALL_EMBLEMS_SIZE self.canvas = MfxCanvas(self, bg='white') self.canvas.pack(expand=True, fill='both') # @@ -72,35 +79,28 @@ class FindCardDialog(Tkinter.Toplevel): dir = self.images_dir canvas = self.canvas group = MfxCanvasGroup(canvas) - s = 'cshd'[suit] - if suit >= 2: c = 'red' - else: c = 'black' - rect_width = 4 - x1, y1 = x0+dx-rect_width, y0+dy-rect_width - rect = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1, - width=rect_width, - fill='white', outline='white') - rect.addtag(group) # - fn = os.path.join(dir, c+'-'+str(rank)+'.gif') - rim = FindCardDialog.RANK_IMAGES.get((rank, c)) - if not rim: - rim = makeImage(file=fn) - FindCardDialog.RANK_IMAGES[(rank, c)] = rim - fn = os.path.join(dir, s+'.gif') - sim = FindCardDialog.SUIT_IMAGES.get((suit, c)) - if not sim: - sim = makeImage(file=fn) - FindCardDialog.SUIT_IMAGES[(suit, c)] = sim + im = FindCardDialog.CARD_IMAGES.get((rank, suit)) + if im is None: + r = '%02d' % (rank+1) + s = 'csdh'[suit] + fn = os.path.join(dir, r+s+'.gif') + im = makeImage(file=fn) + FindCardDialog.CARD_IMAGES[(rank, suit)] = im + cim = MfxCanvasImage(canvas, x0, y0, image=im, anchor='nw') + cim.addtag(group) + cim.lower() + # +## rect_width = 4 +## x1, y1 = x0+dx, y0+dy +## rect = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1, +## width=rect_width, +## fill=None, +## outline='red', +## state='hidden') +## rect.addtag(group) + rect = None # - x0 = x0+(dx-rim.width()-sim.width())/2 - x0, y0 = x0-1, y0-2 - x, y = x0, y0+(dy-rim.height())/2 - im = MfxCanvasImage(canvas, x, y, image=rim, anchor='nw') - im.addtag(group) - x, y = x0+rim.width(), y0+(dy-sim.height())/2 - im = MfxCanvasImage(canvas, x, y, image=sim, anchor='nw') - im.addtag(group) bind(group, '', lambda e, suit=suit, rank=rank, rect=rect: self.enterEvent(suit, rank, rect)) @@ -126,29 +126,31 @@ class FindCardDialog(Tkinter.Toplevel): self.createCardLabel(suit=suit, rank=rank, x0=x, y0=y) j += 1 i += 1 - w, h = dx*j, dy*i + w, h = dx*j+2, dy*i+2 self.canvas.config(width=w, height=h) def enterEvent(self, suit, rank, rect): - #print 'enterEvent', suit, rank + ##print 'enterEvent', suit, rank self.highlight_items = self.game.highlightCard(suit, rank) if not self.highlight_items: self.highlight_items = [] - rect.config(outline='red') if self.highlight_items: self.timer = after(self, self.normal_timeout, self.timeoutEvent) + return + rect.config(state='normal') def leaveEvent(self, suit, rank, rect): - #print 'leaveEvent', suit, rank + ##print 'leaveEvent', suit, rank if self.highlight_items: for i in self.highlight_items: i.delete() - rect.config(outline='white') #self.game.canvas.update_idletasks() #self.canvas.update_idletasks() if self.timer: after_cancel(self.timer) self.timer = None + return + rect.config(state='hidden') def timeoutEvent(self, *event): if self.highlight_items: