diff --git a/pysollib/games/mahjongg/mahjongg.py b/pysollib/games/mahjongg/mahjongg.py index 379be556..082b0cb5 100644 --- a/pysollib/games/mahjongg/mahjongg.py +++ b/pysollib/games/mahjongg/mahjongg.py @@ -242,6 +242,7 @@ class Mahjongg_RowStack(OpenStack): # checks if not self.cards: return 1 + card = self.cards[-1] from_stack = drag.stack if from_stack is self: # remove selection @@ -261,21 +262,20 @@ class Mahjongg_RowStack(OpenStack): return 1 drag.stack = self self.game.playSample("startdrag") - # move or create the shade image (see stack.py, _updateShade) + # create the shade image (see stack.py, _updateShade) if drag.shade_img: - img = drag.shade_img - img.dtag(drag.shade_stack.group) - img.moveTo(self.x, self.y) - img.addtag(self.group) - else: - img = game.app.images.getShade() - if img is None: - return 1 - img = MfxCanvasImage(game.canvas, self.x, self.y, image=img, - anchor=ANCHOR_NW, group=self.group) - drag.shade_img = img + #drag.shade_img.dtag(drag.shade_stack.group) + drag.shade_img.delete() + #game.canvas.delete(drag.shade_img) + drag.shade_img = None + img = game.app.images.getShadowCard(card.suit, card.rank) + if img is None: + return 1 + img = MfxCanvasImage(game.canvas, self.x, self.y, image=img, + anchor=ANCHOR_NW, group=self.group) + drag.shade_img = img # raise/lower the shade image to the correct stacking order - img.tkraise(self.cards[-1].item) + img.tkraise(card.item) drag.shade_stack = self return 1 @@ -288,6 +288,9 @@ class Mahjongg_RowStack(OpenStack): # the tile (from Tk's stacking view) return len(self.cards) - 1 + def getBottomImage(self): + return None + # /*********************************************************************** # // diff --git a/pysollib/games/special/pegged.py b/pysollib/games/special/pegged.py index 6a674ced..55a6b66d 100644 --- a/pysollib/games/special/pegged.py +++ b/pysollib/games/special/pegged.py @@ -162,6 +162,13 @@ class Pegged(Game): # game overrides # + def shuffle(self): + cards = list(self.cards) + cards.reverse() + for card in cards: + self.s.talon.addCard(card, update=0) + card.showBack(unhide=0) + def startGame(self): n = len(self.cards) - len(self.s.rows) + 1 if n > 0: @@ -176,7 +183,7 @@ class Pegged(Game): c = 0 for s in self.s.foundations: c = c + len(s.cards) - return c + 2 == self.gameinfo.si.ncards + return c + 1 == self.gameinfo.si.ncards def getAutoStacks(self, event=None): return ((), (), ()) @@ -235,17 +242,21 @@ class PeggedTriangle2(PeggedTriangle1): ROWS = (1, 2, 3, 4, 5, 6) + # /*********************************************************************** # // register the games # ************************************************************************/ def r(id, gameclass, name): - si_ncards = 0 + ncards = 0 for n in gameclass.ROWS: - si_ncards = si_ncards + n + ncards += n + ncards -= 1 gi = GameInfo(id, gameclass, name, GI.GT_PUZZLE_TYPE, 1, 0, GI.SL_SKILL, - si={"ncards": si_ncards}, + category=GI.GC_TRUMP_ONLY, + suits=(), ranks=(), trumps=range(ncards), + si = {"decks": 1, "ncards": ncards}, rules_filename = "pegged.html") registerGame(gi) return gi diff --git a/pysollib/games/ultra/matrix.py b/pysollib/games/ultra/matrix.py index 0b9e7fa6..0a81dca2 100644 --- a/pysollib/games/ultra/matrix.py +++ b/pysollib/games/ultra/matrix.py @@ -40,34 +40,6 @@ from pysollib.layout import Layout from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.pysoltk import MfxCanvasText, MfxCanvasImage, bind, ANCHOR_NW -from pysollib.games.special.pegged import Pegged_RowStack, WasteTalonStack, \ - Pegged, PeggedCross1, PeggedCross2, Pegged6x6, Pegged7x7 - - -## Matrix_RowStack -## NewTower_RowStack -## RockHopper_RowStack -## ThreePeaks_TalonStack -## ThreePeaks_RowStack -## Matrix3 -## Matrix4 -## Matrix5 -## Matrix6 -## Matrix7 -## Matrix8 -## Matrix9 -## Matrix10 -## Matrix20 -## NewTowerofHanoi -## RockHopper -## RockHopperCross1 -## RockHopperCross2 -## RockHopper6x6 -## RockHopper7x7 -## ThreePeaks -## ThreePeaksNoScore -## LeGrandeTeton - # /*********************************************************************** # // Matrix Row Stack @@ -150,131 +122,6 @@ class Matrix_RowStack(OpenStack): return 1 - -# /*********************************************************************** -# // New Tower Row Stack -# ************************************************************************/ - -class NewTower_RowStack(Matrix_RowStack): - - def __init__(self, x, y, game, **cap): - kwdefault(cap, max_move=1, max_accept=1, max_cards=99, - base_rank=ANY_RANK) - apply(OpenStack.__init__, (self, x, y, game), cap) - self.CARD_YOFFSET = -max(self.game.app.images.CARD_YOFFSET, 20) - - def acceptsCards(self, from_stack, cards): - if not OpenStack.acceptsCards(self, from_stack, cards): - return 0 - if self.cards: - return self.cards[-1].rank > cards[0].rank - return 1 - - def getBottomImage(self): - # None doesn't recognize clicks. - return self.game.app.images.getLetter(0) - - def basicIsBlocked(self): - return 0 - - def clickHandler(self, event): - game = self.game - drag = game.drag - from_stack = drag.stack - if from_stack is self: - # remove selection - self._stopDrag() - return 1 - # possible move - if from_stack: - if self.acceptsCards(from_stack, from_stack.cards[-1:]): - self._stopDrag() - # this code actually moves the tiles - from_stack.playMoveMove(1, self, frames=3, sound=0) - return 1 - drag.stack = self - # move or create the shade image (see stack.py, _updateShade) - if drag.shade_img: - img = drag.shade_img - img.dtag(drag.shade_stack.group) - img.moveTo(self.x, self.y) - elif self.cards: - img = game.app.images.getShade() - if img is None: - return 1 - img = MfxCanvasImage(game.canvas, self.x, - self.y + self.CARD_YOFFSET[0] * (len(self.cards) - 1), - image=img, anchor=ANCHOR_NW) - drag.shade_img = img - if self.cards: - img.tkraise(self.cards[-1].item) - img.addtag(self.group) - drag.shade_stack = self - return 1 - - - -# /*********************************************************************** -# // Rock Hopper Row Stack -# ************************************************************************/ - -class RockHopper_RowStack(Pegged_RowStack): - - def canFlipCard(self): - return 0 - - def cancelDrag(self, event=None): - if event is None: - self._stopDrag() - - def _findCard(self, event): - # we need to override this because the shade may be hiding - # the tile (from Tk's stacking view) - return len(self.cards) - 1 - - def initBindings(self): - bind(self.group, "<1>", self._Stack__clickEventHandler) - bind(self.group, "", self._Stack__controlclickEventHandler) - - def getBottomImage(self): - # None doesn't recognize clicks. - return self.game.app.images.getReserveBottom() - - def clickHandler(self, event): - game = self.game - drag = game.drag - from_stack = drag.stack - if from_stack is self: - # remove selection - self._stopDrag() - return 1 - # possible move - if from_stack and not self.cards and self._getMiddleStack(from_stack) is not None: - self._stopDrag() - # this code actually moves the tiles - from_stack.moveMove(1, self, frames=3) - return 1 - drag.stack = self - # move or create the shade image (see stack.py, _updateShade) - if drag.shade_img and self.cards: - img = drag.shade_img - img.dtag(drag.shade_stack.group) - img.moveTo(self.x, self.y) - elif self.cards: - img = game.app.images.getShade() - if img is None: - return 1 - img = MfxCanvasImage(game.canvas, self.x, self.y, - image=img, anchor=ANCHOR_NW) - drag.shade_img = img - if self.cards: - img.tkraise(self.cards[-1].item) - img.addtag(self.group) - drag.shade_stack = self - return 1 - - - # /*********************************************************************** # // Matrix Game # ************************************************************************/ @@ -362,59 +209,30 @@ class Matrix3(Game): # ************************************************************************/ class Matrix4(Matrix3): - pass class Matrix5(Matrix3): - pass class Matrix6(Matrix3): - pass class Matrix7(Matrix3): - pass class Matrix8(Matrix3): - pass class Matrix9(Matrix3): - pass class Matrix10(Matrix3): - pass class Matrix20(Matrix3): - pass -# /*********************************************************************** -# // Rock Hopper -# ************************************************************************/ - -class RockHopper(Pegged): - STACK = RockHopper_RowStack - -class RockHopperCross1(PeggedCross1): - STACK = RockHopper_RowStack - -class RockHopperCross2(PeggedCross2): - STACK = RockHopper_RowStack - -class RockHopper6x6(Pegged6x6): - STACK = RockHopper_RowStack - -class RockHopper7x7(Pegged7x7): - STACK = RockHopper_RowStack - - - # /*********************************************************************** # // Register a Matrix game # ************************************************************************/ @@ -444,24 +262,3 @@ r(22230, Matrix10, "10x10 Matrix") del r -def r(id, gameclass, short_name): - name = short_name - ncards = 0 - for n in gameclass.ROWS: - ncards = ncards + n - gi = GameInfo(id, gameclass, name, GI.GT_MATRIX, 1, 0, GI.SL_SKILL, - category=GI.GC_TRUMP_ONLY, short_name=short_name, - suits=(), ranks=(), trumps=range(ncards), - si={"decks": 1, "ncards": ncards}) - gi.ncards = ncards - gi.rules_filename = "pegged.html" - registerGame(gi) - return gi - -r(22221, RockHopper, "Rock Hopper") -r(22220, RockHopperCross1, "Rock Hopper Cross 1") -r(22219, RockHopperCross2, "Rock Hopper Cross 2") -r(22218, RockHopper6x6, "Rock Hopper 6x6") -r(22217, RockHopper7x7, "Rock Hopper 7x7") - -del r diff --git a/pysollib/images.py b/pysollib/images.py index 940dbd6f..a833052a 100644 --- a/pysollib/images.py +++ b/pysollib/images.py @@ -42,7 +42,7 @@ from mfxutil import Pickler, Unpickler, UnpicklingError from mfxutil import Struct, EnvError # Toolkit imports -from pysoltk import tkversion, loadImage, copyImage, createImage +from pysoltk import tkversion, loadImage, copyImage, createImage, shadowImage try: import Image @@ -93,6 +93,7 @@ class Images: self._shadow = [] self._xshadow = [] self._shade = [] + self._shadow_cards = {} # key: (suit, rank) def destruct(self): pass @@ -127,22 +128,23 @@ class Images: self.cs.backnames = tuple(self.cs.backnames) + (name,) # bottoms / letters bottom = None + neg_bottom = None while len(self._bottom_positive) < 7: if bottom is None: bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#000000") self._bottom_positive.append(bottom) while len(self._bottom_negative) < 7: - if bottom is None: - bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#ffffff") - self._bottom_negative.append(bottom) + if neg_bottom is None: + neg_bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#ffffff") + self._bottom_negative.append(neg_bottom) while len(self._letter_positive) < 4: if bottom is None: bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#000000") self._letter_positive.append(bottom) while len(self._letter_negative) < 4: - if bottom is None: - bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#ffffff") - self._letter_negative.append(bottom) + if neg_bottom is None: + neg_bottom = createImage(self.CARDW, self.CARDH, fill=None, outline="#ffffff") + self._letter_negative.append(neg_bottom) self._blank_bottom = createImage(self.CARDW, self.CARDH, fill=None, outline=None) def load(self, app, progress=None, fast=0): @@ -292,6 +294,17 @@ class Images: def getShade(self): return self._shade[self._shade_index] + def getShadowCard(self, suit, rank): + if self._shadow_cards.has_key((suit, rank)): + shade = self._shadow_cards[(suit, rank)] + else: + image = self.getFace(0, suit, rank) + shade = shadowImage(image) + self._shadow_cards[(suit, rank)] = shade + if not shade: + return self.getShade() + return shade + def getCardbacks(self): return self._back diff --git a/pysollib/pysolgtk/tkutil.py b/pysollib/pysolgtk/tkutil.py index 6b35135d..d96258ed 100644 --- a/pysollib/pysolgtk/tkutil.py +++ b/pysollib/pysolgtk/tkutil.py @@ -164,6 +164,10 @@ def createImage(width, height, fill, outline=None): # FIXME return _PysolPixmap(width=width, height=height, fill=fill, outline=outline) +def shadowImage(image): + # FIXME + return None + # /*********************************************************************** # // event wrapper diff --git a/pysollib/stack.py b/pysollib/stack.py index cbbb2936..afaab54d 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -1259,16 +1259,12 @@ class Stack: ## if (self.CARD_XOFFSET != (0,) or ## self.CARD_YOFFSET != (0,)): ## return - if not self.images.shade_img: - img = self.game.app.images.getShade() - self.images.shade_img = img - else: - img = self.images.shade_img + card = self.cards[-1] + img = self.game.app.images.getShadowCard(card.suit, card.rank) if img is None: return - if not self.items.shade_item: + if 1: ##not self.items.shade_item: #self.game.canvas.update_idletasks() - card = self.cards[-1] item = MfxCanvasImage(self.game.canvas, card.x, card.y, image=img, anchor=ANCHOR_NW, group=self.group) diff --git a/pysollib/tile/Tile.py b/pysollib/tile/Tile.py index 78bb9918..22d529b2 100644 --- a/pysollib/tile/Tile.py +++ b/pysollib/tile/Tile.py @@ -1,4 +1,5 @@ +import os import Tkinter from Tkconstants import * @@ -322,6 +323,11 @@ class Scrollbar(Widget, Tkinter.Scrollbar): def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, "ttk::scrollbar", cnf, kw) +# from http://tkinter.unpythonic.net/wiki/PyLocateTile : +# standard Tk scrollbars work on OS X, but Tile ones look weird +if os.name == "mac": + Scrollbar = Tkinter.Scrollbar + class Separator(Widget): def __init__(self, master=None, cnf={}, **kw): diff --git a/pysollib/tile/tkutil.py b/pysollib/tile/tkutil.py index aa0a918c..9cc2102a 100644 --- a/pysollib/tile/tkutil.py +++ b/pysollib/tile/tkutil.py @@ -51,6 +51,7 @@ __all__ = ['wm_withdraw', 'loadImage', #'fillImage', 'createImage', + 'shadowImage', 'get_text_width', #'init_tile', #'load_theme', @@ -316,15 +317,17 @@ def after_cancel(t): if Image: class PIL_Image(ImageTk.PhotoImage): - def __init__(self, file): - im = Image.open(file).convert('RGBA') - ImageTk.PhotoImage.__init__(self, im) - self._pil_image = im + def __init__(self, file=None, image=None): + if file: + image = Image.open(file).convert('RGBA') + ImageTk.PhotoImage.__init__(self, image) + self._pil_image = image def subsample(self, r): im = self._pil_image w, h = im.size w, h = int(float(w)/r), int(float(h)/r) - im = ImageTk.PhotoImage(im.resize((w, h))) + im = im.resize((w, h)) + im = PIL_Image(image=im) return im @@ -400,6 +403,15 @@ def createImage(width, height, fill, outline=None): fillImage(image, fill, outline) return image +def shadowImage(image): + if not hasattr(image, '_pil_image'): + return None + im = image._pil_image + sh = Image.new('RGBA', im.size, 'black') + tmp = Image.blend(im, sh, 0.2) + out = Image.composite(tmp, im, im) + return PIL_Image(image=out) + # /*********************************************************************** # // font utils diff --git a/pysollib/tk/tkutil.py b/pysollib/tk/tkutil.py index 08664547..b7859a80 100644 --- a/pysollib/tk/tkutil.py +++ b/pysollib/tk/tkutil.py @@ -51,6 +51,7 @@ __all__ = ['wm_withdraw', 'loadImage', #'fillImage', 'createImage', + 'shadowImage', 'get_text_width', ] @@ -312,15 +313,17 @@ def after_cancel(t): if Image: class PIL_Image(ImageTk.PhotoImage): - def __init__(self, file): - im = Image.open(file).convert('RGBA') - ImageTk.PhotoImage.__init__(self, im) - self._pil_image = im + def __init__(self, file=None, image=None): + if file: + image = Image.open(file).convert('RGBA') + ImageTk.PhotoImage.__init__(self, image) + self._pil_image = image def subsample(self, r): im = self._pil_image w, h = im.size w, h = int(float(w)/r), int(float(h)/r) - im = ImageTk.PhotoImage(im.resize((w, h))) + im = im.resize((w, h)) + im = PIL_Image(image=im) return im @@ -396,6 +399,15 @@ def createImage(width, height, fill, outline=None): fillImage(image, fill, outline) return image +def shadowImage(image): + if not hasattr(image, '_pil_image'): + return None + im = image._pil_image + sh = Image.new('RGBA', im.size, 'black') + tmp = Image.blend(im, sh, 0.2) + out = Image.composite(tmp, im, im) + return PIL_Image(image=out) + # /*********************************************************************** # // font utils