1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

+ 7 new games

+ new file: pysollib/tk/findcarddialog.py
+ new option: `use mouse for undo/redo'
* improved Game._highlightCards
* added flash to FindCardDialog


git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@34 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2006-07-31 21:35:39 +00:00
parent 2a9f965042
commit 8c8bc67970
47 changed files with 802 additions and 471 deletions

View file

@ -138,6 +138,7 @@ class PysolMenubarActions:
splashscreen = BooleanVar(),
demo_logo = BooleanVar(),
sticky_mouse = BooleanVar(),
mouse_undo = BooleanVar(),
negative_bottom = BooleanVar(),
pause = BooleanVar(),
toolbar_vars = {},
@ -190,6 +191,7 @@ class PysolMenubarActions:
tkopt.demo_logo.set(opt.demo_logo)
tkopt.splashscreen.set(opt.splashscreen)
tkopt.sticky_mouse.set(opt.sticky_mouse)
tkopt.mouse_undo.set(opt.mouse_undo)
tkopt.negative_bottom.set(opt.negative_bottom)
for w in TOOLBAR_BUTTONS:
tkopt.toolbar_vars[w].set(opt.toolbar_vars[w])

View file

@ -68,7 +68,8 @@ from pysoltk import PysolStatusbar, HelpStatusbar
from pysoltk import SelectCardsetByTypeDialogWithPreview
from pysoltk import SelectDialogTreeData
from pysoltk import TOOLBAR_BUTTONS
from help import helpAbout
from pysoltk import destroy_find_card_dialog
from help import helpAbout, destroy_help
gettext = _
@ -171,7 +172,7 @@ class Options:
self.highlight_samerank_colors = (None, "#ffc000", None, "#0000ff")
self.hintarrow_color = "#303030"
self.highlight_not_matching_color = '#ff0000'
self.table_text_color = 0
self.table_text_color = False # `False' is mean use default
self.table_text_color_value = '#ffffff'
# delays
self.hint_sleep = 1.0
@ -194,6 +195,7 @@ class Options:
#
self.splashscreen = True
self.sticky_mouse = False
self.mouse_undo = False # use mouse for undo/redo
self.negative_bottom = False
self.randomize_place = False
self.cache_carsets = True
@ -689,6 +691,9 @@ class Application:
finally:
# hide main window
self.wm_withdraw()
#
destroy_find_card_dialog()
destroy_help()
# update options
self.opt.last_gameid = id
# save options

View file

@ -180,12 +180,28 @@ class Game:
if self.s.talon:
assert hasattr(self.s.talon, "round")
assert hasattr(self.s.talon, "max_rounds")
if self.app.debug and self.s.foundations:
ncards = 0
for stack in self.s.foundations:
ncards += stack.cap.max_cards
if ncards != self.gameinfo.ncards:
print 'WARNING: invalid sum of foundations.max_cards:', self.__class__.__name__, ncards, self.gameinfo.ncards
if self.app.debug:
class_name = self.__class__.__name__
if self.s.foundations:
ncards = 0
for stack in self.s.foundations:
ncards += stack.cap.max_cards
if ncards != self.gameinfo.ncards:
print 'WARNING: invalid sum of foundations.max_cards:', \
class_name, ncards, self.gameinfo.ncards
if self.s.rows:
from stack import AC_RowStack, SS_RowStack, RK_RowStack
r = self.s.rows[0]
for c, f in (
(AC_RowStack, (self._shallHighlightMatch_AC,
self._shallHighlightMatch_ACW)),
(SS_RowStack, (self._shallHighlightMatch_SS,
self._shallHighlightMatch_SSW)),
(RK_RowStack, (self._shallHighlightMatch_RK,
self._shallHighlightMatch_RKW)),):
if isinstance(r, c) and not self.shallHighlightMatch in f:
print 'WARNING: shallHighlightMatch is not valid:', \
class_name, r.__class__
# optimize regions
self.optimizeRegions()
# create cards
@ -739,14 +755,14 @@ class Game:
def undoHandler(self, event):
self._defaultHandler()
if not self.event_handled:
if self.app.opt.mouse_undo and not self.event_handled:
self.app.menubar.mUndo()
self.event_handled = False
return EVENT_PROPAGATE
def redoHandler(self, event):
self._defaultHandler()
if not self.event_handled:
if self.app.opt.mouse_undo and not self.event_handled:
self.app.menubar.mRedo()
self.event_handled = False
return EVENT_PROPAGATE
@ -1416,7 +1432,9 @@ for %d moves.
## for find_card_dialog
def highlightCard(self, suit, rank):
col = self.app.opt.highlight_samerank_colors[3]
if not self.app:
return None
col = self.app.opt.highlight_samerank_colors[1]
info = []
for s in self.allstacks:
for c in s.cards:
@ -1438,25 +1456,59 @@ for %d moves.
items = []
for s, c1, c2, color in info:
assert c1 in s.cards and c2 in s.cards
sy0 = s.CARD_YOFFSET[0]
if sy0 >= 0:
tkraise = False
if c1 is c2:
# highlight single card
sx0, sy0 = s.getOffsetFor(c1)
x1, y1 = s.getPositionFor(c1)
x2, y2 = x1, y1
else:
# highlight pile
if len(s.CARD_XOFFSET) > 1:
sx0 = 0
else:
sx0 = s.CARD_XOFFSET[0]
if len(s.CARD_YOFFSET) > 1:
sy0 = 0
else:
sy0 = s.CARD_YOFFSET[0]
x1, y1 = s.getPositionFor(c1)
x2, y2 = s.getPositionFor(c2)
if c2 is not s.cards[-1] and sy0 > 0:
y2 = y2 + sy0
else:
y2 = y2 + self.app.images.CARDH
else:
x1, y1 = s.getPositionFor(c2)
x2, y2 = s.getPositionFor(c1)
if sx0 != 0 and sy0 == 0:
# horizontal stack
y2 = y2 + self.app.images.CARDH
if c2 is not s.cards[-1]:
y1 = y1 + (self.app.images.CARDH + sy0)
x2 = x2 + self.app.images.CARDW
if c2 is s.cards[-1]: # top card
x2 = x2 + self.app.images.CARDW
else:
if sx0 > 0:
# left to right
x2 = x2 + sx0
else:
# right to left
x1 = x1 + self.app.images.CARDW
x2 = x2 + self.app.images.CARDW + sx0
elif sx0 == 0 and sy0 != 0:
# vertical stack
x2 = x2 + self.app.images.CARDW
if c2 is s.cards[-1]: # top card
y2 = y2 + self.app.images.CARDH
else:
if sy0 > 0:
# up to down
y2 = y2 + sy0
else:
# down to up
y1 = y1 + self.app.images.CARDH
y2 = y2 + self.app.images.CARDH + sy0
else:
x2 = x2 + self.app.images.CARDW
y2 = y2 + self.app.images.CARDH
tkraise = True
##print c1, c2, x1, y1, x2, y2
r = MfxCanvasRectangle(self.canvas, x1-1, y1-1, x2+1, y2+1,
width=4, fill=None, outline=color)
r.tkraise(c2.item)
if tkraise:
r.tkraise(c2.item)
items.append(r)
if not items:
return 0
@ -1469,6 +1521,7 @@ for %d moves.
self.canvas.update_idletasks()
return EVENT_HANDLED
else:
# remove items later
return items
def highlightNotMatching(self):
@ -1492,9 +1545,10 @@ for %d moves.
r.delete()
self.canvas.update_idletasks()
def highlightPiles(self, stackinfo, sleep=1.5):
def highlightPiles(self, sleep=1.5):
stackinfo = self.getHighlightPilesStacks()
if not stackinfo:
self.highlightNotMatching()
return 0
col = self.app.opt.highlight_piles_colors
hi = []
@ -1503,17 +1557,61 @@ for %d moves.
pile = s.getPile()
if pile and len(pile) >= si[1]:
hi.append((s, pile[0], pile[-1], col[1]))
if not hi:
self.highlightNotMatching()
return 0
return self._highlightCards(hi, sleep)
#
# highlight matching cards
#
### highlight matching cards
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return 0
def _shallHighlightMatch_AC(self, stack1, card1, stack2, card2):
# by alternate color
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
def _shallHighlightMatch_ACW(self, stack1, card1, stack2, card2):
# by alternate color with wrapping (only for france games)
return (card1.color != card2.color
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
def _shallHighlightMatch_SS(self, stack1, card1, stack2, card2):
# by same suit
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
def _shallHighlightMatch_SSW(self, stack1, card1, stack2, card2):
# by same suit with wrapping (only for france games)
return (card1.suit == card2.suit
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
def _shallHighlightMatch_RK(self, stack1, card1, stack2, card2):
# by rank
return abs(card1.rank-card2.rank) == 1
def _shallHighlightMatch_RKW(self, stack1, card1, stack2, card2):
# by rank with wrapping (only for france games)
return ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank)
#
# quick-play
#
def getQuickPlayScore(self, ncards, from_stack, to_stack):
# prefer non-empty piles in to_stack
return (len(to_stack.cards) != 0)
def _getSpiderQuickPlayScore(self, ncards, from_stack, to_stack):
# for spider-type stacks
if to_stack.cards:
# check suit
return int(from_stack.cards[-1].suit == to_stack.cards[-1].suit)+1
return 0
#
# Score (I really don't like scores in Patience games...)

View file

@ -114,10 +114,7 @@ class Carthage(Game):
self.startDealSample()
self.s.talon.dealRow(rows=self.s.reserves)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
# /***********************************************************************

View file

@ -270,8 +270,7 @@ class Interregnum(Game):
def getAutoStacks(self, event=None):
return ((), (), self.sg.dropstacks)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RKW
def _restoreGameHook(self, game):
self.base_cards = [None] * 8
@ -488,8 +487,7 @@ class Scuffle_Talon(RedealTalonStack):
def dealCards(self, sound=0, shuffle=True):
if self.cards:
return self.dealRowAvail(sound=sound)
RedealTalonStack.redealCards(self, frames=4,
shuffle=shuffle, sound=sound)
self.redealCards(frames=4, shuffle=shuffle, sound=sound)
return self.dealRowAvail(sound=sound)

View file

@ -80,8 +80,7 @@ class CastlesInSpain(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -139,8 +138,7 @@ class BakersDozen(CastlesInSpain):
def startGame(self):
CastlesInSpain.startGame(self, flip=(1, 1, 1))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -150,8 +148,7 @@ class BakersDozen(CastlesInSpain):
class SpanishPatience(BakersDozen):
Foundation_Class = AC_FoundationStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -252,8 +249,8 @@ class Cruel(CastlesInSpain):
CastlesInSpain.startGame(self, flip=(1, 1, 1))
self.s.talon.dealRow(rows=self.s.foundations)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
# // Royal Family
@ -269,8 +266,7 @@ class RoyalFamily(Cruel):
# move Kings to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == KING, c.suit))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
class Indefatigable(Cruel):
@ -282,8 +278,7 @@ class Indefatigable(Cruel):
# move Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == ACE, c.suit))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -328,8 +323,7 @@ class RippleFan(CastlesInSpain):
def startGame(self):
CastlesInSpain.startGame(self, flip=(1, 1, 1))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# register the game

View file

@ -114,9 +114,7 @@ class BakersGame(Game):
##self.s.talon.dealRow(rows=(r[0], r[1], r[6], r[7]))
self.s.talon.dealRow(rows=r[:4])
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -312,9 +310,7 @@ class Penguin(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
def _restoreGameHook(self, game):
self.base_card = self.cards[game.loadinfo.base_card_id]

View file

@ -126,8 +126,7 @@ class StreetsAndAlleys(Game):
for i in range(3):
self.s.talon.dealRowAvail()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank - card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -226,10 +225,8 @@ class Fortress(Game):
for i in range(3):
self.s.talon.dealRowAvail()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
# /***********************************************************************
# // Bastion
@ -436,8 +433,7 @@ class Zerline(Game):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank - card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
return int(to_stack in self.s.rows)
@ -559,8 +555,7 @@ class CastleOfIndolence(Game):
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank - card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -637,8 +632,7 @@ class Rittenhouse(Game):
def fillStack(self, stack):
self.fillAll()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank - card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -688,9 +682,7 @@ class CastleMount(Lightweight):
DEAL = (11, 1)
RowStack_Class = Spider_SS_RowStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % stack1.cap.mod == card2.rank or
(card2.rank + 1) % stack1.cap.mod == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack.cards:

View file

@ -90,8 +90,7 @@ class Bisley(Game):
# move Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == ACE, c.suit))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -232,15 +231,13 @@ class Realm(Game):
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
class Mancunian(Realm):
RowStack_Class = StackWrapper(UD_RK_RowStack, base_rank=NO_RANK)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# register the game

View file

@ -214,9 +214,7 @@ class Braid(Game):
# deal first card to WasteStack
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
def getHighlightPilesStacks(self):
return ()
@ -358,8 +356,7 @@ class Backbone(Game):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
class BackbonePlus(Backbone):

View file

@ -319,10 +319,7 @@ class NewYork(Dover):
self.s.talon.dealRow()
self.s.talon.fillStack()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_ACW
def _restoreGameHook(self, game):
self.base_card = self.cards[game.loadinfo.base_card_id]
@ -356,9 +353,7 @@ class Spike(Dover):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************

View file

@ -212,9 +212,7 @@ class Canfield(Game):
if stack.canFlipCard():
stack.flipMove()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_ACW
def _restoreGameHook(self, game):
self.base_card = self.cards[game.loadinfo.base_card_id]
@ -277,9 +275,7 @@ class Storehouse(Canfield):
self.s.talon.dealRow(rows=self.s.foundations[:3])
Canfield.startGame(self)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
def updateText(self):
pass
@ -297,8 +293,7 @@ class Chameleon(Canfield):
def createGame(self):
Canfield.createGame(self, rows=3, max_rounds=1, num_deal=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************
@ -345,9 +340,7 @@ class VariegatedCanfield(Canfield):
self.s.talon.dealRow(rows=self.s.foundations[:7])
Canfield.startGame(self)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) == card2.rank or (card2.rank + 1) == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
def updateText(self):
pass
@ -471,9 +464,7 @@ class Gate(Game):
if from_stack:
from_stack.moveMove(1, stack)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_AC
class LittleGate(Gate):
@ -544,8 +535,7 @@ class Doorway(LittleGate):
def fillStack(self, stack):
pass
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -574,8 +564,7 @@ class Minerva(Canfield):
self.flipMove(self.s.reserves[0])
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
def _restoreGameHook(self, game):
pass
@ -631,9 +620,7 @@ class Acme(Canfield):
self.s.talon.dealRow(reverse=1)
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_SS
def updateText(self):
pass
@ -703,9 +690,7 @@ class Duke(Game):
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************

View file

@ -122,10 +122,7 @@ class Capricieuse(Game):
def _shuffleHook(self, cards):
return self._shuffleHookMoveToBottom(cards, lambda c: (c.deck == 0 and c.rank in (0, 12), (c.rank, c.suit)), 8)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % stack1.cap.mod == card2.rank or
(card2.rank + 1) % stack1.cap.mod == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -136,6 +133,8 @@ class Nationale(Capricieuse):
Talon_Class = InitialDealTalonStack
RowStack_Class = StackWrapper(UD_SS_RowStack, mod=13)
shallHighlightMatch = Game._shallHighlightMatch_SSW
# register the game
registerGame(GameInfo(292, Capricieuse, "Capricieuse",

View file

@ -323,9 +323,7 @@ class GermanPatience(Game):
return True
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RKW
class BavarianPatience(GermanPatience):
@ -384,8 +382,7 @@ class TrustyTwelve(Game):
def isGameWon(self):
return len(self.s.talon.cards) == 0
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
class KnottyNines(TrustyTwelve):
@ -410,8 +407,7 @@ class SweetSixteen(TrustyTwelve):
y += l.YS+10*l.YOFFSET
l.defaultStackGroups()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC

View file

@ -112,8 +112,7 @@ class Diplomat(Game):
self.s.waste.moveMove(1, stack)
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************

View file

@ -121,9 +121,7 @@ class Fan(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
def getHighlightPilesStacks(self):
return ()
@ -138,8 +136,7 @@ class ScotchPatience(Fan):
RowStack_Class = StackWrapper(RK_RowStack, base_rank=NO_RANK)
def createGame(self):
Fan.createGame(self, playcards=8)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -150,8 +147,7 @@ class Shamrocks(Fan):
RowStack_Class = StackWrapper(UD_RK_RowStack, base_rank=NO_RANK, max_cards=3)
def createGame(self):
Fan.createGame(self, playcards=4)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -520,9 +516,7 @@ class CloverLeaf(Game):
(c.rank == KING and c.suit in (2,3)),
c.suit))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -556,9 +550,7 @@ class BoxFan(Fan):
# move Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == 0, c.suit))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************

View file

@ -152,9 +152,7 @@ class FortyThieves(Game):
self.s.waste.moveMove(1, stack)
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -358,8 +356,7 @@ class LittleForty(FortyThieves):
class Streets(FortyThieves):
RowStack_Class = AC_RowStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
class Maria(Streets):
@ -458,8 +455,9 @@ class Indian(FortyThieves):
FortyThieves.createGame(self, XCARDS=74)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit != card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
return (card1.suit != card2.suit
and (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank))
class Midshipman(Indian):
@ -487,8 +485,7 @@ class NapoleonsExile(FortyThieves):
DEAL = (0, 4)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank
shallHighlightMatch = Game._shallHighlightMatch_RK
class DoubleRail(NapoleonsExile):
@ -600,8 +597,7 @@ class Octave(Game):
return False
return not self.s.waste.cards
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
def _autoDeal(self, sound=1):
ncards = len(self.s.waste.cards) + sum([len(i.cards) for i in self.s.reserves])
@ -667,8 +663,7 @@ class FortunesFavor(Game):
self.s.waste.moveMove(1, stack)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -731,8 +726,7 @@ class Octagon(Game):
if self.s.waste.cards:
self.s.waste.moveMove(1, stack)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -850,8 +844,7 @@ class Junction(Game):
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -930,8 +923,7 @@ class TheSpark(Game):
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -988,8 +980,7 @@ class Unlimited(Interchange):
class Breakwater(Interchange):
RowStack_Class = RK_RowStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
class FortyNine_RowStack(AC_RowStack):
@ -1011,8 +1002,7 @@ class FortyNine(Interchange):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************

View file

@ -118,9 +118,7 @@ class FreeCell(Game):
##self.s.talon.dealRow(rows=(r[0], r[2], r[4], r[6]))
self.s.talon.dealRow(rows=r[:4])
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -539,8 +537,7 @@ class OceanTowers(TripleFreecell):
self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.reserves[1:-1])
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************

View file

@ -158,10 +158,7 @@ class Glenwood(Game):
t = RANKS[self.base_rank]
self.texts.info.config(text=t)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_ACW
def _restoreGameHook(self, game):
self.base_rank = game.loadinfo.base_rank
@ -323,10 +320,7 @@ class DoubleFives(Glenwood):
return self.dealCards(sound=sound)
return 0
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW

View file

@ -174,8 +174,7 @@ class Golf(Game):
return 0
return 1
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
def getHighlightPilesStacks(self):
return ()
@ -206,8 +205,7 @@ class DeadKingGolf(Golf):
class RelaxedGolf(Golf):
Waste_Class = StackWrapper(Golf_Waste, mod=13)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************
@ -666,8 +664,7 @@ class DiamondMine(Game):
return False
return True
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# register the game

View file

@ -125,8 +125,7 @@ class GrandfathersClock(Game):
self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.foundations)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank
shallHighlightMatch = Game._shallHighlightMatch_RK
def getHighlightPilesStacks(self):
return ()

View file

@ -82,9 +82,7 @@ class Gypsy(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -327,8 +325,7 @@ class Steve(Carlton):
Hint_Class = Spider_Hint
RowStack_Class = Spider_SS_RowStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack.cards:
@ -389,9 +386,7 @@ class Blockade(Gypsy):
self.s.talon.moveMove(1, stack)
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_SS
class PhantomBlockade(Gypsy):
@ -709,8 +704,7 @@ class Eclipse(Gypsy):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1)
shallHighlightMatch = Game._shallHighlightMatch_SS
# register the game

View file

@ -92,9 +92,7 @@ class DoubleKlondike(Game):
self.s.talon.dealRow()
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -190,8 +188,7 @@ class LadyJane(DoubleKlondike):
DoubleKlondike.createGame(self, rows=10, max_rounds=2, num_deal=3)
def startGame(self):
DoubleKlondike.startGame(self, flip=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack.cards:
return int(from_stack.cards[-1].suit == to_stack.cards[-1].suit)+1
@ -205,8 +202,7 @@ class Inquisitor(DoubleKlondike):
DoubleKlondike.createGame(self, rows=10, max_rounds=3, num_deal=3)
def startGame(self):
DoubleKlondike.startGame(self, flip=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -220,8 +216,7 @@ class Arabella(DoubleKlondike):
DoubleKlondike.createGame(self, rows=13, max_rounds=1, playcards=24)
def startGame(self):
DoubleKlondike.startGame(self, flip=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack.cards:
return int(from_stack.cards[-1].suit == to_stack.cards[-1].suit)+1
@ -276,8 +271,7 @@ class Delivery(BigDeal):
dx = self.app.images.CARDW/10
BigDeal.createGame(self, rows=12, max_rounds=1, XOFFSET=dx)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
def startGame(self):
for i in range(2):

View file

@ -129,8 +129,7 @@ class HeadsAndTails(Game):
#stack.flipMove()
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank - card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# register the game

View file

@ -122,9 +122,7 @@ class DerKatzenschwanz(Game):
i = i + 1
self.s.talon.dealRow(rows=[self.s.rows[i]], frames=4)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# must look at cards
def _getClosestStack(self, cx, cy, stacks, dragstack):

View file

@ -86,9 +86,7 @@ class Klondike(Game):
if self.s.waste:
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -150,8 +148,9 @@ class ThumbAndPouch(Klondike):
Klondike.createGame(self, max_rounds=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit != card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
return (card1.suit != card2.suit
and (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank))
# /***********************************************************************
@ -172,9 +171,7 @@ class Whitehead(Klondike):
def startGame(self):
Klondike.startGame(self, flip=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -537,8 +534,7 @@ class Brigade(Raglan):
self.s.talon.dealRow(rows=self.s.reserves)
self.s.talon.dealRow(rows=self.s.foundations)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -619,10 +615,7 @@ class Jane(Klondike):
s.cap.update(cap.__dict__)
self.saveinfo.stack_caps.append((s.id, cap))
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
def _autoDeal(self, sound=1):
return 0
@ -817,8 +810,7 @@ class ThirtySix(Klondike):
break
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -869,8 +861,7 @@ class Q_C_(Klondike):
self.s.waste.moveMove(1, stack)
self.fillAll()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -1030,8 +1021,7 @@ class BigForty(Klondike):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
class AliBaba(BigForty):
@ -1143,8 +1133,7 @@ class LuckyThirteen(Klondike):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
class LuckyPiles(LuckyThirteen):

View file

@ -222,9 +222,7 @@ class Montana(Game):
def getAutoStacks(self, event=None):
return (self.sg.dropstacks, (), self.sg.dropstacks)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if from_stack.cards:

View file

@ -164,9 +164,7 @@ class DerKleineNapoleon(Game):
self.s.talon.dealRow(rows=self.s.rows[8:])
self.s.talon.dealBaseCards(ncards=4)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SSW
#
# game extras

View file

@ -94,8 +94,7 @@ class Needle(Game):
self.s.talon.dealRow(rows=self.s.rows[:i])
self.s.talon.dealRow(rows=self.s.rows[-i:])
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack in self.s.reserves:

View file

@ -33,7 +33,7 @@
__all__ = []
# imports
import sys
import sys, time
# PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI
@ -103,7 +103,7 @@ class Numerica(Game):
# game layout
#
def createGame(self, rows=4, reserve=False):
def createGame(self, rows=4, reserve=False, max_rounds=1, waste_max_cards=1):
# create layout
l, s = Layout(self), self.s
decks = self.gameinfo.decks
@ -131,13 +131,15 @@ class Numerica(Game):
x = x + l.XS
self.setRegion(s.rows, (x0-l.XS/2, y-l.CH/2, 999999, 999999))
x, y = l.XM, l.YM+l.YS+l.YS/2*int(reserve)
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
if reserve:
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
if reserve or waste_max_cards > 1:
l.createText(s.talon, 'ne')
else:
l.createText(s.talon, 'n')
y = y + l.YS
s.waste = WasteStack(x, y, self, max_cards=1)
s.waste = WasteStack(x, y, self, max_cards=waste_max_cards)
if waste_max_cards > 1:
l.createText(s.waste, 'ne')
if reserve:
s.reserves.append(self.ReserveStack_Class(l.XM, l.YM, self))
@ -153,9 +155,7 @@ class Numerica(Game):
self.startDealSample()
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
def getHighlightPilesStacks(self):
return ()
@ -659,6 +659,62 @@ class Strategerie(Game):
self.s.talon.fillStack()
# /***********************************************************************
# // Assembly
# // Anno Domini
# ************************************************************************/
class Assembly(Numerica):
Hint_Class = DefaultHint
Foundation_Class = StackWrapper(RK_FoundationStack, suit=ANY_SUIT)
RowStack_Class = StackWrapper(RK_RowStack, max_move=1)
def createGame(self):
Numerica.createGame(self, waste_max_cards=UNLIMITED_CARDS)
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
shallHighlightMatch = Game._shallHighlightMatch_RK
class AnnoDomini_Hint(DefaultHint):
def step030(self, foundations, rows, dropstacks):
pass
class AnnoDomini(Numerica):
Hint_Class = AnnoDomini_Hint
Foundation_Class = StackWrapper(SS_FoundationStack, suit=ANY_SUIT, mod=13)
RowStack_Class = AC_RowStack
def createGame(self):
Numerica.createGame(self, max_rounds=3, waste_max_cards=UNLIMITED_CARDS)
year = str(time.localtime()[0])
i = 0
for s in self.s.foundations:
# setup base_rank & base_suit
s.cap.suit = i
s.cap.base_suit = i
d = int(year[i])
if d == 0:
d = JACK
s.cap.base_rank = d
i += 1
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game
registerGame(GameInfo(257, Numerica, "Numerica",
@ -689,4 +745,8 @@ registerGame(GameInfo(558, Numerica2Decks, "Numerica (2 decks)",
GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(589, LastChance, "Last Chance",
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(599, Assembly, "Assembly",
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(600, AnnoDomini, "Anno Domini",
GI.GT_NUMERICA, 1, 2, GI.SL_BALANCED))

View file

@ -184,10 +184,7 @@ class Foursome(Game):
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_ACW
class Quartets(Foursome):

View file

@ -337,7 +337,6 @@ class Thirteen(Pyramid):
class Thirteens(Pyramid):
def createGame(self):
# create layout
l, s = Layout(self), self.s
@ -376,6 +375,225 @@ class Thirteens(Pyramid):
self.s.talon.moveMove(1, stack)
self.leaveState(old_state)
# /***********************************************************************
# // Elevens
# // Suit Elevens
# ************************************************************************/
class Elevens_RowStack(Giza_Reserve):
ACCEPTED_SUM = 9
def acceptsCards(self, from_stack, cards):
#if self.basicIsBlocked():
# return 0
if from_stack is self or not self.cards or len(cards) != 1:
return False
c = self.cards[-1]
return (c.face_up and cards[0].face_up
and cards[0].rank + c.rank == self.ACCEPTED_SUM)
def clickHandler(self, event):
return OpenStack.clickHandler(self, event)
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
if to_stack in self.game.s.rows:
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
else:
self.game.moveMove(ncards, self, to_stack,
frames=frames, shadow=shadow)
self.fillStack()
class Elevens_Reserve(ReserveStack):
ACCEPTED_CARDS = (JACK, QUEEN, KING)
def acceptsCards(self, from_stack, cards):
if not ReserveStack.acceptsCards(self, from_stack, cards):
return False
c = cards[0]
if not c.rank in self.ACCEPTED_CARDS:
return False
for s in self.game.s.reserves:
if s.cards and s.cards[0].rank == c.rank:
return False
return True
class Elevens(Pyramid):
RowStack_Class = Elevens_RowStack
Reserve_Class = Elevens_Reserve
def createGame(self, rows=3, cols=3, reserves=3, texts=False):
l, s = Layout(self), self.s
self.setSize(l.XM+(cols+2)*l.XS, l.YM+(rows+1.5)*l.YS)
x, y = self.width-l.XS, l.YM
s.talon = TalonStack(x, y, self)
l.createText(s.talon, 's')
x, y = self.width-l.XS, self.height-l.YS
s.foundations.append(AbstractFoundationStack(x, y, self,
suit=ANY_SUIT, max_accept=0,
max_move=0, max_cards=52))
y = l.YM
for i in range(rows):
x = l.XM
for j in range(cols):
s.rows.append(self.RowStack_Class(x, y, self, max_accept=1))
x += l.XS
y += l.YS
x, y = l.XM, self.height-l.YS
for i in range(reserves):
stack = self.Reserve_Class(x, y, self)
s.reserves.append(stack)
stack.CARD_XOFFSET = l.XOFFSET # for fifteens
x += l.XS
if texts:
stack = s.reserves[0]
tx, ty, ta, tf = l.getTextAttr(stack, "n")
font = self.app.getFont("canvas_default")
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.defaultStackGroups()
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
def fillStack(self, stack):
old_state = self.enterState(self.S_FILL)
if stack in self.s.rows:
if not stack.cards and self.s.talon.cards:
self.s.talon.flipMove()
self.s.talon.moveMove(1, stack)
reserves_ncards = 0
for s in self.s.reserves:
if s.cards:
reserves_ncards += 1
if reserves_ncards == len(self.s.reserves):
if not self.demo:
self.playSample("droppair", priority=200)
for s in self.s.reserves:
s.moveMove(1, self.s.foundations[0], frames=4)
self.leaveState(old_state)
class ElevensToo(Elevens):
def fillStack(self, stack):
old_state = self.enterState(self.S_FILL)
reserves_ncards = 0
for s in self.s.reserves:
if s.cards:
reserves_ncards += 1
if reserves_ncards == 0:
for r in self.s.rows:
if not r.cards and self.s.talon.cards:
self.s.talon.flipMove()
self.s.talon.moveMove(1, r)
elif reserves_ncards == len(self.s.reserves):
if not self.demo:
self.playSample("droppair", priority=200)
for s in self.s.reserves:
s.moveMove(1, self.s.foundations[0], frames=4)
self.fillStack(stack)
self.leaveState(old_state)
class SuitElevens_RowStack(Elevens_RowStack):
def acceptsCards(self, from_stack, cards):
if not Elevens_RowStack.acceptsCards(self, from_stack, cards):
return False
return cards[0].suit == self.cards[0].suit
class SuitElevens_Reserve(Elevens_Reserve):
def acceptsCards(self, from_stack, cards):
if not Elevens_Reserve.acceptsCards(self, from_stack, cards):
return False
for r in self.game.s.reserves:
if r.cards and r.cards[0].suit != cards[0].suit:
return False
return True
class SuitElevens(Elevens):
RowStack_Class = SuitElevens_RowStack
Reserve_Class = SuitElevens_Reserve
def createGame(self):
Elevens.createGame(self, rows=3, cols=5)
# /***********************************************************************
# // Fifteens
# ************************************************************************/
class Fifteens_RowStack(Elevens_RowStack):
ACCEPTED_SUM = 13
def acceptsCards(self, from_stack, cards):
if not Elevens_RowStack.acceptsCards(self, from_stack, cards):
return False
return cards[0].rank < 9 and self.cards[0] < 9
class Fifteens_Reserve(ReserveStack):
def updateText(self):
if self.game.preview > 1 or self.texts.misc is None:
return
t = ''
if self.cards:
ranks = [c.rank for c in self.cards]
for r in (9, JACK, QUEEN, KING):
if r in ranks:
break
else:
n = sum([i+1 for i in ranks])
t = str(n)
self.texts.misc.config(text=t)
class Fifteens(Elevens):
Hint_Class = None
RowStack_Class = Fifteens_RowStack
Reserve_Class = StackWrapper(Fifteens_Reserve, max_cards=UNLIMITED_CARDS)
def createGame(self):
Elevens.createGame(self, rows=4, cols=4, reserves=1, texts=True)
def _dropReserve(self):
reserve = self.s.reserves[0]
if not self.demo:
self.playSample("droppair", priority=200)
while reserve.cards:
reserve.moveMove(1, self.s.foundations[0], frames=4)
self.fillStack()
def fillStack(self, stack=None):
old_state = self.enterState(self.S_FILL)
reserve = self.s.reserves[0]
if len(reserve.cards) == 0:
for r in self.s.rows:
if not r.cards and self.s.talon.cards:
self.s.talon.flipMove()
self.s.talon.moveMove(1, r)
else:
reserve_ranks = [c.rank for c in reserve.cards]
reserve_ranks.sort()
if (9 in reserve_ranks or JACK in reserve_ranks
or QUEEN in reserve_ranks or KING in reserve_ranks):
if reserve_ranks == [9, JACK, QUEEN, KING]:
self._dropReserve()
else:
reserve_sum = sum([c.rank+1 for c in reserve.cards])
if reserve_sum == 15:
self._dropReserve()
self.leaveState(old_state)
# register the game
@ -389,6 +607,14 @@ registerGame(GameInfo(592, Giza, "Giza",
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(593, Thirteens, "Thirteens",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK))
registerGame(GameInfo(594, Elevens, "Elevens",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK))
registerGame(GameInfo(595, ElevensToo, "Elevens Too",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK))
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))

View file

@ -582,8 +582,7 @@ class ThreePirates(Game):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS

View file

@ -149,9 +149,7 @@ class RelaxedSpider(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % stack1.cap.mod == card2.rank or
(card2.rank + 1) % stack1.cap.mod == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack.cards:
@ -226,6 +224,8 @@ class GroundForADivorce(RelaxedSpider):
self.startDealSample()
self.s.talon.dealRow()
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************
# // Grandmother's Game
@ -336,8 +336,7 @@ class Scorpion(RelaxedSpider):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
def getHighlightPilesStacks(self):
return ()
@ -350,8 +349,7 @@ class ScorpionTail(Scorpion):
Foundation_Class = Spider_AC_Foundation
RowStack_Class = StackWrapper(ScorpionTail_RowStack, base_rank=KING)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
class DoubleScorpion(Scorpion):
@ -613,8 +611,7 @@ class Trillium(Game):
self.startDealSample()
self.s.talon.dealRow()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
def isGameWon(self):
for s in self.s.rows:
@ -641,9 +638,7 @@ class WakeRobin(Trillium):
return False
return True
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
class TripleWakeRobin(WakeRobin):
@ -703,8 +698,7 @@ class Chelicera(Game):
def getHighlightPilesStacks(self):
return ()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
def isGameWon(self):
for s in self.s.rows:
@ -859,10 +853,7 @@ class Applegate(Game):
def getHighlightPilesStacks(self):
return ()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % stack1.cap.mod == card2.rank or
(card2.rank + 1) % stack1.cap.mod == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************
@ -903,6 +894,7 @@ class GroundForADivorce3Decks(BigSpider):
RowStack_Class = StackWrapper(Spider_RowStack, mod=13)
def canDealCards(self):
return Game.canDealCards(self)
shallHighlightMatch = Game._shallHighlightMatch_RKW
class Spider4Decks(BigSpider):
@ -942,6 +934,7 @@ class GroundForADivorce4Decks(Spider4Decks):
Spider4Decks.createGame(self, rows=12)
def canDealCards(self):
return Game.canDealCards(self)
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************

View file

@ -491,12 +491,13 @@ class Matrimony(Game):
# /***********************************************************************
# // Picture Patience
# // Patriarchs
# ************************************************************************/
class Patriarchs(Game):
class PicturePatience(Game):
def createGame(self, max_rounds=2):
def createGame(self, max_rounds=1):
l, s = Layout(self), self.s
self.setSize(3*l.XM+5*l.XS, l.YM+4*l.YS)
@ -528,14 +529,7 @@ class Patriarchs(Game):
l.defaultStackGroups()
def _shuffleHook(self, cards):
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)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
@ -549,6 +543,22 @@ class Patriarchs(Game):
self.s.waste.moveMove(1, stack)
class Patriarchs(PicturePatience):
def createGame(self):
PicturePatience.createGame(self, max_rounds=2)
def _shuffleHook(self, cards):
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)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
# /***********************************************************************
# // Simplicity
# ************************************************************************/
@ -602,10 +612,7 @@ class Simplicity(Game):
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_ACW
def _restoreGameHook(self, game):
@ -727,8 +734,7 @@ class CornerSuite(Game):
self.startDealSample()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
@ -785,9 +791,7 @@ class Marshal(Game):
self.moveMove(1, self.s.talon, stack)
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(abs(card1.rank-card2.rank) == 1))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -855,9 +859,7 @@ class RoyalAids(Game):
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(abs(card1.rank-card2.rank) == 1))
shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game
@ -892,3 +894,5 @@ registerGame(GameInfo(559, Marshal, "Marshal",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(565, RoyalAids, "Royal Aids",
GI.GT_2DECK_TYPE, 2, UNLIMITED_REDEALS, GI.SL_BALANCED))
registerGame(GameInfo(598, PicturePatience, "Picture Patience",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))

View file

@ -229,8 +229,7 @@ class KingsdownEights(Game):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game

View file

@ -138,9 +138,7 @@ class UnionSquare(Game):
self.s.talon.dealRow()
self.s.talon.dealCards() # deal first card to WasteStack
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
def getHighlightPilesStacks(self):
return ()

View file

@ -91,8 +91,7 @@ class WaveMotion(Game):
return False
return True
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# register the game

View file

@ -143,8 +143,7 @@ class Windmill(Game):
elif stack in self.s.rows and self.s.waste.cards:
self.s.waste.moveMove(1, stack)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RK
def getHighlightPilesStacks(self):
return ()
@ -357,9 +356,7 @@ class Czarina(Corners):
def _shuffleHook(self, cards):
return cards
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank)
shallHighlightMatch = Game._shallHighlightMatch_RKW
def _restoreGameHook(self, game):
self.base_card = self.cards[game.loadinfo.base_card_id]

View file

@ -115,9 +115,7 @@ class Yukon(Game):
def getHighlightPilesStacks(self):
return ()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_AC
# /***********************************************************************
@ -127,9 +125,7 @@ class Yukon(Game):
class RussianSolitaire(Yukon):
RowStack_Class = StackWrapper(Yukon_SS_RowStack, base_rank=KING)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -367,9 +363,7 @@ class DoubleYukon(Yukon):
class DoubleRussianSolitaire(DoubleYukon):
RowStack_Class = StackWrapper(Yukon_SS_RowStack, base_rank=KING)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -392,9 +386,7 @@ class TripleYukon(Yukon):
class TripleRussianSolitaire(TripleYukon):
RowStack_Class = StackWrapper(Yukon_SS_RowStack, base_rank=KING)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -443,9 +435,7 @@ class TenAcross(Yukon):
self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.reserves)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -538,8 +528,7 @@ class Geoffrey(Yukon):
self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.rows[:4])
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -562,8 +551,7 @@ class Queensland(Yukon):
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************
@ -593,8 +581,7 @@ class OutbackPatience(Yukon):
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# /***********************************************************************

View file

@ -117,8 +117,7 @@ class Zodiac(Game):
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
shallHighlightMatch = Game._shallHighlightMatch_SS
# register the game

View file

@ -169,3 +169,9 @@ def helpHTML(app, document, dir_, top=None):
help_html_viewer = viewer
return viewer
def destroy_help():
try:
help_html_viewer.destroy()
except:
pass

View file

@ -32,6 +32,7 @@ from tk.soundoptionsdialog import *
from tk.timeoutsdialog import *
from tk.colorsdialog import *
from tk.fontsdialog import *
from tk.findcarddialog import *
from tk.gameinfodialog import *
from tk.toolbar import *
from tk.statusbar import *

View file

@ -706,6 +706,14 @@ class Stack:
iy = (iy + 1) % ly
return (x, y)
def getOffsetFor(self, card):
model, view = self, self
if view.can_hide_cards:
return 0, 0
lx, ly = len(view.CARD_XOFFSET), len(view.CARD_YOFFSET)
i = list(model.cards).index(card)
return view.CARD_XOFFSET[i%lx], view.CARD_YOFFSET[i%ly]
# Fully update the view of a stack - updates
# hiding, card positions and stacking order.
# Avoid calling this as it is rather slow.
@ -895,7 +903,7 @@ class Stack:
#
def __defaultClickEventHandler(self, event, handler, start_drag=0, cancel_drag=1):
self.game.event_handled = True # for Game.clickHandler
self.game.event_handled = True # for Game.undoHandler
if self.game.demo:
self.game.stopDemo(event)
self.game.interruptSleep()

View file

@ -0,0 +1,203 @@
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; see the file COPYING.
## If not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
##---------------------------------------------------------------------------##
__all__ = ['create_find_card_dialog',
'connect_game_find_card_dialog',
'destroy_find_card_dialog',
]
# imports
import os
import Tkinter
import traceback
# PySol imports
# Toolkit imports
from tkutil import after, after_cancel
from tkutil import bind, unbind_destroy, makeImage
from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle
# /***********************************************************************
# //
# ************************************************************************/
class FindCardDialog(Tkinter.Toplevel):
SUIT_IMAGES = {} # key: (suit, color)
RANK_IMAGES = {} # key: (rank, color)
def __init__(self, parent, game, dir):
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.canvas = MfxCanvas(self, bg='white')
self.canvas.pack(expand=True, fill='both')
#
self.groups = []
self.highlight_items = None
self.connectGame(game)
#
bind(self, "WM_DELETE_WINDOW", self.destroy)
bind(self, "<Escape>", self.destroy)
#
##self.normal_timeout = 400 # in milliseconds
self.normal_timeout = int(1000*game.app.opt.highlight_samerank_sleep)
self.hidden_timeout = 200
self.timer = None
def createCardLabel(self, suit, rank, x0, y0):
dx, dy = self.label_width, self.label_height
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
#
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, '<Enter>',
lambda e, suit=suit, rank=rank, rect=rect:
self.enterEvent(suit, rank, rect))
bind(group, '<Leave>',
lambda e, suit=suit, rank=rank, rect=rect:
self.leaveEvent(suit, rank, rect))
self.groups.append(group)
def connectGame(self, game):
self.game = game
suits = game.gameinfo.suits
ranks = game.gameinfo.ranks
dx, dy = self.label_width, self.label_height
uniq_suits = []
i = 0
for suit in suits:
if suit in uniq_suits:
continue
uniq_suits.append(suit)
j = 0
for rank in ranks:
x, y = dx*j+2, dy*i+2
self.createCardLabel(suit=suit, rank=rank, x0=x, y0=y)
j += 1
i += 1
w, h = dx*j, dy*i
self.canvas.config(width=w, height=h)
def enterEvent(self, suit, rank, rect):
#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)
def leaveEvent(self, suit, rank, rect):
#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
def timeoutEvent(self, *event):
if self.highlight_items:
state = self.highlight_items[0].cget('state')
if state in ('', 'normal'):
state = 'hidden'
self.timer = after(self, self.hidden_timeout,
self.timeoutEvent)
else:
state = 'normal'
self.timer = after(self, self.normal_timeout,
self.timeoutEvent)
for item in self.highlight_items:
item.config(state=state)
def destroy(self, *args):
for l in self.groups:
unbind_destroy(l)
unbind_destroy(self)
if self.timer:
after_cancel(self.timer)
self.timer = None
self.wm_withdraw()
Tkinter.Toplevel.destroy(self)
find_card_dialog = None
def create_find_card_dialog(parent, game, dir):
global find_card_dialog
try:
find_card_dialog.tkraise()
except:
##traceback.print_exc()
find_card_dialog = FindCardDialog(parent, game, dir)
def connect_game_find_card_dialog(game):
try:
find_card_dialog.connectGame(game)
except:
pass
def destroy_find_card_dialog():
global find_card_dialog
try:
find_card_dialog.destroy()
except:
##traceback.print_exc()
pass
find_card_dialog = None

View file

@ -320,7 +320,7 @@ class PysolMenubar(PysolMenubarActions):
menu.add_command(label=n_("&Demo"), command=self.mDemo, accelerator=m+"D")
menu.add_command(label=n_("Demo (&all games)"), command=self.mMixedDemo)
menu.add_separator()
menu.add_command(label=n_("Show descriptions od piles"), command=self.mStackDesk, accelerator="F2")
menu.add_command(label=n_("Piles description"), command=self.mStackDesk, accelerator="F2")
menu = MfxMenu(self.__menubar, label=n_("&Options"))
menu.add_command(label=n_("&Player options..."), command=self.mOptPlayerOptions)
submenu = MfxMenu(menu, label=n_("&Automatic play"))
@ -365,6 +365,7 @@ class PysolMenubar(PysolMenubarActions):
submenu.add_radiobutton(label=n_("&Slow"), variable=self.tkopt.animations, value=3, command=self.mOptAnimations)
submenu.add_radiobutton(label=n_("&Very slow"), variable=self.tkopt.animations, value=4, command=self.mOptAnimations)
menu.add_checkbutton(label=n_("Stick&y mouse"), variable=self.tkopt.sticky_mouse, command=self.mOptStickyMouse)
menu.add_checkbutton(label=n_("Use mouse for undo/redo"), variable=self.tkopt.mouse_undo, command=self.mOptMouseUndo)
menu.add_separator()
menu.add_command(label=n_("&Fonts..."), command=self.mOptFontsOptions)
menu.add_command(label=n_("&Colors..."), command=self.mOptColorsOptions)
@ -408,6 +409,7 @@ class PysolMenubar(PysolMenubarActions):
self._bindKey(ctrl, "q", self.mQuit)
self._bindKey("", "z", self.mUndo)
self._bindKey("", "BackSpace", self.mUndo) # undocumented
self._bindKey("", "KP_Enter", self.mUndo) # undocumented
self._bindKey("", "r", self.mRedo)
self._bindKey(ctrl, "g", self.mRestart)
self._bindKey("", "space", self.mDeal) # undocumented
@ -1004,6 +1006,10 @@ class PysolMenubar(PysolMenubarActions):
if self._cancelDrag(break_pause=False): return
self.app.opt.sticky_mouse = self.tkopt.sticky_mouse.get()
def mOptMouseUndo(self, *event):
if self._cancelDrag(break_pause=False): return
self.app.opt.mouse_undo = self.tkopt.mouse_undo.get()
def mOptNegativeBottom(self, *event):
if self._cancelDrag(): return
n = self.tkopt.negative_bottom.get()

View file

@ -39,13 +39,11 @@ __all__ = ['MfxMessageDialog',
'MfxTooltip',
'MfxScrolledCanvas',
'StackDesc',
'create_find_card_dialog',
'connect_game_find_card_dialog',
'destroy_find_card_dialog',
]
# imports
import os, sys, time, types, Tkinter
import os, sys, time, types
import Tkinter
import traceback
# PySol imports
@ -53,12 +51,11 @@ from pysollib.mfxutil import destruct, kwdefault, KwStruct
from pysollib.mfxutil import win32api
# Toolkit imports
from tkconst import tkversion
from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
from tkutil import after, after_idle, after_cancel
from tkutil import bind, unbind_destroy, makeImage
from tkutil import bind, unbind_destroy
from tkutil import makeToplevel, setTransient
from tkcanvas import MfxCanvas, MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle
from tkcanvas import MfxCanvas
# /***********************************************************************
@ -719,139 +716,3 @@ class StackDesc:
for b in self.bindings:
self.label.unbind('<ButtonPress>', b)
# /***********************************************************************
# //
# ************************************************************************/
class FindCardDialog(Tkinter.Toplevel):
SUIT_IMAGES = {} # key: (suit, color)
RANK_IMAGES = {} # key: (rank, color)
def __init__(self, parent, game, dir, title='Find card'):
Tkinter.Toplevel.__init__(self)
self.title(title)
self.wm_resizable(0, 0)
#
self.images_dir = dir
self.label_width, self.label_height = 38, 34
self.canvas = MfxCanvas(self, bg='white')
self.canvas.pack(expand=True, fill='both')
#
self.groups = []
self.highlight_items = None
self.connectGame(game)
#
bind(self, "WM_DELETE_WINDOW", self.destroy)
bind(self, "<Escape>", self.destroy)
def createCardLabel(self, suit, rank, x0, y0):
dx, dy = self.label_width, self.label_height
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
#
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, '<Enter>',
lambda e, suit=suit, rank=rank, rect=rect:
self.enterEvent(suit, rank, rect))
bind(group, '<Leave>',
lambda e, suit=suit, rank=rank, rect=rect:
self.leaveEvent(suit, rank, rect))
self.groups.append(group)
def connectGame(self, game):
self.game = game
suits = game.gameinfo.suits
ranks = game.gameinfo.ranks
dx, dy = self.label_width, self.label_height
i = 0
for suit in suits:
j = 0
for rank in ranks:
x, y = dx*j+2, dy*i+2
self.createCardLabel(suit=suit, rank=rank, x0=x, y0=y)
j += 1
i += 1
w, h = dx*j, dy*i
self.canvas.config(width=w, height=h)
def enterEvent(self, suit, rank, rect):
#print 'enterEvent', suit, rank
self.last_card = (suit, rank)
self.highlight_items = self.game.highlightCard(suit, rank)
if not self.highlight_items:
self.highlight_items = []
rect.config(outline='red')
def leaveEvent(self, suit, rank, rect):
#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()
self.last_card = None
def destroy(self, *args):
for l in self.groups:
unbind_destroy(l)
unbind_destroy(self)
self.wm_withdraw()
Tkinter.Toplevel.destroy(self)
find_card_dialog = None
def create_find_card_dialog(parent, game, dir):
global find_card_dialog
try:
find_card_dialog.tkraise()
except:
##traceback.print_exc()
find_card_dialog = FindCardDialog(parent, game, dir)
def connect_game_find_card_dialog(game):
try:
find_card_dialog.connectGame(game)
except:
pass
def destroy_find_card_dialog():
global find_card_dialog
try:
find_card_dialog.destroy()
except:
##traceback.print_exc()
pass
find_card_dialog = None