mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
- removed 5 duplicated games (Rock Hopper)
* improved images shadowing (mahjongg and filled stacks) - need PIL * bugs fixes git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@109 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
7bcf031dce
commit
00aa3488e4
9 changed files with 98 additions and 244 deletions
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, "<Control-1>", 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue