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:
parent
2a9f965042
commit
8c8bc67970
47 changed files with 802 additions and 471 deletions
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
146
pysollib/game.py
146
pysollib/game.py
|
@ -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...)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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()
|
||||
|
|
203
pysollib/tk/findcarddialog.py
Normal file
203
pysollib/tk/findcarddialog.py
Normal 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
|
||||
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue