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

+ 2 new games

+ new Layout method: createRoundText
+ added showing `Round #' for many games
* minor improvement of SelectTileDialogWithPreview
* improved `select random game'
* fixed setting bg image


git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@193 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2007-08-15 21:44:20 +00:00
parent 6cd1ce5197
commit ccf656ba52
47 changed files with 535 additions and 331 deletions

View file

@ -339,32 +339,29 @@ class PysolMenubarActions:
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Select random game")): return if not self.game.areYouSure(_("Select random game")): return
game_id = None game_id = None
for i in range(1000): # just in case, don't loop forever games = []
gi = self.app.getGameInfo(self.app.getRandomGameId()) for g in self.app.gdb.getGamesIdSortedById():
if gi is None: gi = self.app.getGameInfo(g)
continue
if 1 and gi.id == self.game.id: if 1 and gi.id == self.game.id:
# force change of game # force change of game
continue continue
if 1 and gi.category != self.game.gameinfo.category: if 1 and gi.category != self.game.gameinfo.category:
# don't change game category # don't change game category
continue continue
if type == 'all':
game_id = gi.id
break
won, lost = self.app.stats.getStats(self.app.opt.player, gi.id) won, lost = self.app.stats.getStats(self.app.opt.player, gi.id)
if type == 'won' and won > 0: if type == 'all':
game_id = gi.id games.append(gi.id)
break elif type == 'won' and won > 0:
if type == 'not won' and won == 0 and lost > 0: games.append(gi.id)
game_id = gi.id elif type == 'not won' and won == 0 and lost > 0:
break games.append(gi.id)
if type == 'not played' and won+lost == 0: elif type == 'not played' and won+lost == 0:
game_id = gi.id games.append(gi.id)
break if games:
game_id = self.app.getRandomGameId(games)
if game_id and game_id != self.game.id: if game_id and game_id != self.game.id:
self.game.endGame() self.game.endGame()
self.game.quitGame(gi.id) self.game.quitGame(game_id)
def _mSelectNextGameFromList(self, gl, step): def _mSelectNextGameFromList(self, gl, step):
if self._cancelDrag(): return if self._cancelDrag(): return

View file

@ -1218,8 +1218,10 @@ Please select a %s type %s.
n = re.sub(r"[^\w]", "", n) n = re.sub(r"[^\w]", "", n)
return n return n
def getRandomGameId(self): def getRandomGameId(self, games=None):
if games is None:
return self.miscrandom.choice(self.gdb.getGamesIdSortedById()) return self.miscrandom.choice(self.gdb.getGamesIdSortedById())
return self.miscrandom.choice(games)
def getAllUserNames(self): def getAllUserNames(self):
names = [] names = []

View file

@ -249,6 +249,14 @@ class Game:
print 'WARNING: shallHighlightMatch is not valid (wrap):', \ print 'WARNING: shallHighlightMatch is not valid (wrap):', \
class_name, r.__class__ class_name, r.__class__
break break
if self.s.talon.max_rounds > 1 and \
self.s.talon.texts.rounds is None:
print 'WARNING: max_rounds > 1, but talon.texts.rounds is None:', \
class_name
elif self.s.talon.max_rounds <= 1 and \
self.s.talon.texts.rounds is not None:
print 'WARNING: max_rounds <= 1, but talon.texts.rounds is not None:', \
class_name
def initBindings(self): def initBindings(self):
@ -2071,7 +2079,8 @@ Congratulations, you did it !
def getQuickPlayScore(self, ncards, from_stack, to_stack): def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack in self.s.reserves: if to_stack in self.s.reserves:
# if to_stack in reserves prefer empty stack # if to_stack in reserves prefer empty stack
return 1000-len(to_stack.cards) ##return 1000 - len(to_stack.cards)
return 1000 - int(len(to_stack.cards) != 0)
# prefer non-empty piles in to_stack # prefer non-empty piles in to_stack
return 1001 + int(len(to_stack.cards) != 0) return 1001 + int(len(to_stack.cards) != 0)

View file

@ -72,10 +72,7 @@ class TamOShanter(Game):
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, "s") l.createText(s.talon, "s")
if texts: if texts:
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') l.createRoundText(s.talon, 'nn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = l.XM+2*l.XS, l.YM x, y = l.XM+2*l.XS, l.YM
for i in range(4*self.gameinfo.decks): for i in range(4*self.gameinfo.decks):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i%4)) s.foundations.append(self.Foundation_Class(x, y, self, suit=i%4))
@ -273,10 +270,7 @@ class Interregnum(Game):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
s.talon = self.Talon_Class(self.width-l.XS, self.height-l.YS, self) s.talon = self.Talon_Class(self.width-l.XS, self.height-l.YS, self)
if texts: if texts:
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
else: else:
l.createText(s.talon, "n") l.createText(s.talon, "n")
@ -404,12 +398,12 @@ class Colorado(Game):
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=i, max_move=0)) suit=i, max_move=0))
x = x + l.XS x += l.XS
x += 2*l.XM x += 2*l.XM
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=i, max_move=0, base_rank=KING, dir=-1)) suit=i, max_move=0, base_rank=KING, dir=-1))
x = x + l.XS x += l.XS
y = l.YM+l.YS y = l.YM+l.YS
for i in range(2): for i in range(2):
@ -422,9 +416,9 @@ class Colorado(Game):
x += l.XS x += l.XS
y += l.YS y += l.YS
x, y = l.XM+9*l.XS, l.YM+3*l.YS x, y = l.XM + 9*l.XS, self.height - l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=1) s.talon = WasteTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, "s") l.createText(s.talon, "n")
x -= l.XS x -= l.XS
s.waste = WasteStack(x, y, self, max_cards=1) s.waste = WasteStack(x, y, self, max_cards=1)

View file

@ -75,6 +75,7 @@ class CastlesInSpain(Game):
s.rows.append(self.RowStack_Class(r.x, r.y, self)) s.rows.append(self.RowStack_Class(r.x, r.y, self))
# default # default
l.defaultAll() l.defaultAll()
return l
def startGame(self, flip=(0, 0, 0)): def startGame(self, flip=(0, 0, 0)):
for f in flip: for f in flip:
@ -252,7 +253,7 @@ class Cruel(CastlesInSpain):
Solver_Class = None Solver_Class = None
def createGame(self): def createGame(self):
CastlesInSpain.createGame(self, rows=12) return CastlesInSpain.createGame(self, rows=12)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # move Aces to bottom of the Talon (i.e. last cards to be dealt)
@ -275,6 +276,11 @@ class RoyalFamily(Cruel):
Talon_Class = StackWrapper(Cruel_Talon, max_rounds=2) Talon_Class = StackWrapper(Cruel_Talon, max_rounds=2)
RowStack_Class = UD_AC_RowStack RowStack_Class = UD_AC_RowStack
def createGame(self):
l = Cruel.createGame(self)
l.createRoundText(self.s.talon, 'sw')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Kings to bottom of the Talon (i.e. last cards to be dealt) # 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)) return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == KING, c.suit))
@ -287,6 +293,10 @@ class Indefatigable(Cruel):
Talon_Class = StackWrapper(Cruel_Talon, max_rounds=3) Talon_Class = StackWrapper(Cruel_Talon, max_rounds=3)
RowStack_Class = UD_SS_RowStack RowStack_Class = UD_SS_RowStack
def createGame(self):
l = Cruel.createGame(self)
l.createRoundText(self.s.talon, 'sw')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # 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)) return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == ACE, c.suit))
@ -300,9 +310,15 @@ class Indefatigable(Cruel):
class Perseverance(Cruel, BakersDozen): class Perseverance(Cruel, BakersDozen):
Talon_Class = StackWrapper(Cruel_Talon, max_rounds=3) Talon_Class = StackWrapper(Cruel_Talon, max_rounds=3)
RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK, dir=-1, max_move=UNLIMITED_MOVES, max_accept=UNLIMITED_ACCEPTS) RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK, dir=-1,
max_move=UNLIMITED_MOVES,
max_accept=UNLIMITED_ACCEPTS)
Solver_Class = None Solver_Class = None
def createGame(self):
l = Cruel.createGame(self)
l.createRoundText(self.s.talon, 'sw')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Kings to bottom of each stack (???) # move Kings to bottom of each stack (???)
#cards = BakersDozen._shuffleHook(self, cards) #cards = BakersDozen._shuffleHook(self, cards)

View file

@ -608,11 +608,11 @@ class CastleOfIndolence(Game):
# create stacks # create stacks
x, y = l.XM, l.YM+4*l.YS x, y = l.XM, l.YM+4*l.YS
s.talon = InitialDealTalonStack(x, y, self) s.talon = InitialDealTalonStack(x, y, self)
x, y = l.XM+w-l.XS, l.YM+4*l.YS x, y = l.XM+w-l.XS, self.height-l.YS
for i in range(4): for i in range(4):
stack = OpenStack(x, y, self, max_accept=0) stack = OpenStack(x, y, self, max_accept=0)
s.reserves.append(stack) s.reserves.append(stack)
l.createText(stack, 's') l.createText(stack, 'n')
x += l.XS x += l.XS
x = l.XM + w x = l.XM + w

View file

@ -159,10 +159,8 @@ class Braid(Game):
x, y = l.XM + 7 * l.XS, l.YM + l.YS * 3/2 x, y = l.XM + 7 * l.XS, l.YM + l.YS * 3/2
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "s") l.createText(s.talon, "s")
s.talon.texts.rounds = MfxCanvasText(self.canvas, l.createRoundText(s.talon, 'nn')
x + l.CW / 2, y - l.TEXT_MARGIN, x -= l.XS
anchor="s", font=font)
x = x - l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
y = l.YM y = l.YM

View file

@ -235,7 +235,7 @@ class BetsyRoss(Calculation):
stack = BetsyRoss_Foundation(x, y, self, base_rank=i, stack = BetsyRoss_Foundation(x, y, self, base_rank=i,
max_cards=1, max_move=0, max_accept=0) max_cards=1, max_move=0, max_accept=0)
s.foundations.append(stack) s.foundations.append(stack)
x = x + l.XS x += l.XS
x = x0 x = x0
y = l.YM + l.YS y = l.YM + l.YS
for i in range(4): for i in range(4):
@ -247,13 +247,15 @@ class BetsyRoss(Calculation):
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty, stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font) anchor=ta, font=font)
s.foundations.append(stack) s.foundations.append(stack)
x = x + l.XS x += l.XS
self.texts.help = MfxCanvasText(self.canvas, x + l.XM, y + l.CH / 2, text=help, self.texts.help = MfxCanvasText(self.canvas, x + l.XM, y + l.CH / 2,
anchor="w", font=self.app.getFont("canvas_fixed")) text=help, anchor="w",
font=self.app.getFont("canvas_fixed"))
x = l.XM x = l.XM
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "n") l.createText(s.talon, "n")
y = y + l.YS l.createRoundText(s.talon, 'nnn')
y += l.YS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
@ -411,10 +413,7 @@ class SeniorWrangler(Game):
x += l.XS x += l.XS
x, y = l.XM, l.YM+l.YS x, y = l.XM, l.YM+l.YS
s.talon = SeniorWrangler_Talon(x, y, self, max_rounds=9) s.talon = SeniorWrangler_Talon(x, y, self, max_rounds=9)
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -162,10 +162,12 @@ class Camelot(Game):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, 's')
x, y = l.XM + w + 4*l.XS + w, l.YM x, y = l.XM + w + 4*l.XS + w, l.YM
s.foundations.append(Camelot_Foundation(x, y, self, s.foundations.append(Camelot_Foundation(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_accept=0, max_move=0, max_cards=52)) max_accept=0, max_move=0, max_cards=52))
l.createText(s.foundations[0], 's')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
return l return l

View file

@ -106,7 +106,8 @@ class Canfield(Game):
# game layout # game layout
# #
def createGame(self, rows=4, max_rounds=-1, num_deal=3, text=True): def createGame(self, rows=4, max_rounds=-1, num_deal=3,
text=True, round_text=False):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
decks = self.gameinfo.decks decks = self.gameinfo.decks
@ -120,6 +121,8 @@ class Canfield(Game):
yoffset = 5 yoffset = 5
# (piles up to 20 cards are playable in default window size) # (piles up to 20 cards are playable in default window size)
h = max(3*l.YS, l.YS+self.INITIAL_RESERVE_CARDS*yoffset) h = max(3*l.YS, l.YS+self.INITIAL_RESERVE_CARDS*yoffset)
if round_text:
h += l.TEXT_HEIGHT
self.setSize(l.XM + (2+max(rows, 4*decks))*l.XS + l.XM, l.YM + l.YS + l.TEXT_HEIGHT + h) self.setSize(l.XM + (2+max(rows, 4*decks))*l.XS + l.XM, l.YM + l.YS + l.TEXT_HEIGHT + h)
# extra settings # extra settings
@ -127,16 +130,21 @@ class Canfield(Game):
# create stacks # create stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self, max_rounds=max_rounds, num_deal=num_deal) s.talon = self.Talon_Class(x, y, self,
max_rounds=max_rounds, num_deal=num_deal)
l.createText(s.talon, "s") l.createText(s.talon, "s")
x = x + l.XS if round_text:
l.createRoundText(s.talon, 'sss')
x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
x = x + l.XM x += l.XM
y = l.YM
for i in range(4): for i in range(4):
for j in range(decks): for j in range(decks):
x = x + l.XS x += l.XS
s.foundations.append(self.Foundation_Class(x, y, self, i, mod=13, max_move=0)) s.foundations.append(self.Foundation_Class(x, y, self, i,
mod=13, max_move=0))
if text: if text:
if rows > 4 * decks: if rows > 4 * decks:
tx, ty, ta, tf = l.getTextAttr(None, "se") tx, ty, ta, tf = l.getTextAttr(None, "se")
@ -148,12 +156,16 @@ class Canfield(Game):
self.texts.info = MfxCanvasText(self.canvas, tx, ty, self.texts.info = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font) anchor=ta, font=font)
x, y = l.XM, l.YM + l.YS + l.TEXT_HEIGHT x, y = l.XM, l.YM + l.YS + l.TEXT_HEIGHT
if round_text:
y += l.TEXT_HEIGHT
s.reserves.append(self.ReserveStack_Class(x, y, self)) s.reserves.append(self.ReserveStack_Class(x, y, self))
s.reserves[0].CARD_YOFFSET = yoffset s.reserves[0].CARD_YOFFSET = yoffset
x = l.XM + 2 * l.XS + l.XM x, y = l.XM + 2 * l.XS + l.XM, l.YM + l.YS
if text:
y += l.TEXT_HEIGHT
for i in range(rows): for i in range(rows):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS x += l.XS
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -240,7 +252,7 @@ class SuperiorCanfield(Canfield):
class Rainfall(Canfield): class Rainfall(Canfield):
def createGame(self): def createGame(self):
Canfield.createGame(self, max_rounds=3, num_deal=1) Canfield.createGame(self, max_rounds=3, num_deal=1, round_text=True)
# /*********************************************************************** # /***********************************************************************
@ -263,7 +275,7 @@ class Storehouse(Canfield):
RowStack_Class = StackWrapper(Canfield_SS_RowStack, mod=13) RowStack_Class = StackWrapper(Canfield_SS_RowStack, mod=13)
def createGame(self): def createGame(self):
Canfield.createGame(self, max_rounds=3, num_deal=1) Canfield.createGame(self, max_rounds=3, num_deal=1, round_text=True)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Twos to top of the Talon (i.e. first cards to be dealt) # move Twos to top of the Talon (i.e. first cards to be dealt)
@ -315,7 +327,8 @@ class AmericanToad(Canfield):
INITIAL_RESERVE_FACEUP = 1 INITIAL_RESERVE_FACEUP = 1
def createGame(self): def createGame(self):
Canfield.createGame(self, rows=8, max_rounds=2, num_deal=1) Canfield.createGame(self, rows=8, max_rounds=2, num_deal=1,
round_text=True)
shallHighlightMatch = Game._shallHighlightMatch_SSW shallHighlightMatch = Game._shallHighlightMatch_SSW
@ -330,7 +343,8 @@ class VariegatedCanfield(Canfield):
INITIAL_RESERVE_FACEUP = 1 INITIAL_RESERVE_FACEUP = 1
def createGame(self): def createGame(self):
Canfield.createGame(self, rows=5, max_rounds=3) Canfield.createGame(self, rows=5, max_rounds=3,
text=False, round_text=True)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt) # move Aces to top of the Talon (i.e. first cards to be dealt)
@ -375,7 +389,8 @@ class EagleWing(Canfield):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=3, num_deal=1) s.talon = WasteTalonStack(x, y, self, max_rounds=3, num_deal=1)
l.createText(s.talon, "s") l.createText(s.talon, "s")
x = x + l.XS l.createRoundText(s.talon, 'ne', dx=l.XS)
x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
for i in range(4): for i in range(4):
@ -521,14 +536,19 @@ class Doorway(LittleGate):
def createGame(self): def createGame(self):
l = LittleGate.createGame(self, rows=5) l = LittleGate.createGame(self, rows=5)
tx, ty, ta, tf = l.getTextAttr(self.s.reserves[0], "s") king_stack, queen_stack = self.s.reserves
tx, ty, ta, tf = l.getTextAttr(king_stack, "s")
font = self.app.getFont("canvas_default") font = self.app.getFont("canvas_default")
MfxCanvasText(self.canvas, tx, ty, anchor=ta, font=font, text=_('King')) king_stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
tx, ty, ta, tf = l.getTextAttr(self.s.reserves[1], "s") anchor=ta, font=font,
text=_('King'))
tx, ty, ta, tf = l.getTextAttr(queen_stack, "s")
font = self.app.getFont("canvas_default") font = self.app.getFont("canvas_default")
MfxCanvasText(self.canvas, tx, ty, anchor=ta, font=font, text=_('Queen')) queen_stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
self.s.reserves[0].cap.base_rank = KING anchor=ta, font=font,
self.s.reserves[1].cap.base_rank = QUEEN text=_('Queen'))
king_stack.cap.base_rank = KING
queen_stack.cap.base_rank = QUEEN
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
@ -554,7 +574,8 @@ class Minerva(Canfield):
INITIAL_RESERVE_CARDS = 11 INITIAL_RESERVE_CARDS = 11
def createGame(self): def createGame(self):
Canfield.createGame(self, rows=7, max_rounds=2, num_deal=1, text=False) Canfield.createGame(self, rows=7, max_rounds=2, num_deal=1,
text=False, round_text=True)
def startGame(self): def startGame(self):
self.s.talon.dealRow(frames=0, flip=0) self.s.talon.dealRow(frames=0, flip=0)
@ -608,7 +629,7 @@ class Acme(Canfield):
Hint_Class = Canfield_Hint Hint_Class = Canfield_Hint
def createGame(self): def createGame(self):
Canfield.createGame(self, max_rounds=2, num_deal=1) Canfield.createGame(self, max_rounds=2, num_deal=1, round_text=True)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt) # move Aces to top of the Talon (i.e. first cards to be dealt)
@ -644,43 +665,34 @@ class Duke(Game):
ReserveStack_Class = OpenStack ReserveStack_Class = OpenStack
RowStack_Class = AC_RowStack RowStack_Class = AC_RowStack
def createGame(self, max_rounds=3, texts=False): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
w, h = l.XM+6*l.XS+4*l.XOFFSET, l.YM+2*l.YS+12*l.YOFFSET w, h = l.XM + 6*l.XS + 4*l.XOFFSET, l.YM + l.TEXT_HEIGHT + 2*l.YS + 12*l.YOFFSET
if texts:
h += l.TEXT_HEIGHT
self.setSize(w, h) self.setSize(w, h)
self.base_card = None
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 's') l.createText(s.talon, 's')
l.createRoundText(s.talon, 'ne', dx=l.XS)
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 's') l.createText(s.waste, 's')
x += l.XS+4*l.XOFFSET x += l.XS+4*l.XOFFSET
y = l.YM
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i)) s.foundations.append(self.Foundation_Class(x, y, self, suit=i))
x += l.XS x += l.XS
x0, y0, w = l.XM, l.YM+l.YS+l.TEXT_HEIGHT, l.XS+2*l.XOFFSET x0, y0, w = l.XM, l.YM+l.YS+2*l.TEXT_HEIGHT, l.XS+2*l.XOFFSET
for i, j in ((0,0), (0,1), (1,0), (1,1)): for i, j in ((0,0), (0,1), (1,0), (1,1)):
x, y = x0+i*w, y0+j*l.YS x, y = x0+i*w, y0+j*l.YS
stack = self.ReserveStack_Class(x, y, self, max_accept=0) stack = self.ReserveStack_Class(x, y, self, max_accept=0)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
s.reserves.append(stack) s.reserves.append(stack)
x, y = l.XM+2*l.XS+4*l.XOFFSET, l.YM+l.YS x, y = l.XM+2*l.XS+4*l.XOFFSET, l.YM+l.YS
if texts:
y += l.TEXT_HEIGHT
for i in range(4): for i in range(4):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x += l.XS x += l.XS
if texts:
tx, ty, ta, tf = l.getTextAttr(s.foundations[-1], "ss")
font = self.app.getFont("canvas_default")
self.texts.info = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.defaultStackGroups() l.defaultStackGroups()
@ -720,7 +732,7 @@ class CanfieldRush(Canfield):
Talon_Class = CanfieldRush_Talon Talon_Class = CanfieldRush_Talon
#RowStack_Class = StackWrapper(AC_RowStack, mod=13) #RowStack_Class = StackWrapper(AC_RowStack, mod=13)
def createGame(self): def createGame(self):
Canfield.createGame(self, max_rounds=3) Canfield.createGame(self, max_rounds=3, round_text=True)
# /*********************************************************************** # /***********************************************************************

View file

@ -48,7 +48,7 @@ class Capricieuse(Game):
# game layout # game layout
# #
def createGame(self, rows=12): def createGame(self, rows=12, round_text=True):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
@ -60,20 +60,22 @@ class Capricieuse(Game):
x, y, = l.XM+(rows-8)*l.XS/2, l.YM x, y, = l.XM+(rows-8)*l.XS/2, l.YM
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x = x + l.XS x += l.XS
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i, s.foundations.append(SS_FoundationStack(x, y, self, suit=i,
base_rank=KING, dir=-1)) base_rank=KING, dir=-1))
x = x + l.XS x += l.XS
x, y, = l.XM, y + l.YS x, y, = l.XM, y + l.YS
for i in range(rows): for i in range(rows):
s.rows.append(self.RowStack_Class(x, y, self, s.rows.append(self.RowStack_Class(x, y, self,
max_move=1, max_accept=1)) max_move=1, max_accept=1))
x = x + l.XS x += l.XS
s.talon = self.Talon_Class(l.XM, l.YM, self) s.talon = self.Talon_Class(l.XM, l.YM, self)
if round_text:
l.createRoundText(self.s.talon, 'ne')
# default # define stack-groups
l.defaultAll() l.defaultStackGroups()
# #
# game overrides # game overrides
@ -105,6 +107,9 @@ class Nationale(Capricieuse):
Talon_Class = InitialDealTalonStack Talon_Class = InitialDealTalonStack
RowStack_Class = StackWrapper(UD_SS_RowStack, mod=13) RowStack_Class = StackWrapper(UD_SS_RowStack, mod=13)
def createGame(self):
Capricieuse.createGame(self, round_text=False)
shallHighlightMatch = Game._shallHighlightMatch_SSW shallHighlightMatch = Game._shallHighlightMatch_SSW
@ -129,11 +134,12 @@ class Strata(Game):
s.foundations.append(DieRussische_Foundation(x, y, self, s.foundations.append(DieRussische_Foundation(x, y, self,
suit=i%4, max_cards=8)) suit=i%4, max_cards=8))
x = x + l.XS x = x + l.XS
x, y, = l.XM+l.XS/2, l.YM+l.YS x, y, = l.XM+l.XS, l.YM+l.YS
for i in range(8): for i in range(8):
s.rows.append(AC_RowStack(x, y, self, max_move=1, max_accept=1)) s.rows.append(AC_RowStack(x, y, self, max_move=1, max_accept=1))
x = x + l.XS x = x + l.XS
s.talon = RedealTalonStack(l.XM, l.YM, self, max_rounds=3) s.talon = RedealTalonStack(l.XM, l.YM+l.YS/2, self, max_rounds=3)
l.createRoundText(s.talon, 'nn')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -159,7 +165,7 @@ class Fifteen(Capricieuse):
Talon_Class = InitialDealTalonStack Talon_Class = InitialDealTalonStack
def createGame(self): def createGame(self):
Capricieuse.createGame(self, rows=15) Capricieuse.createGame(self, rows=15, round_text=False)
def startGame(self): def startGame(self):
for i in range(6): for i in range(6):

View file

@ -467,10 +467,7 @@ class FourPacks(Game):
x, y = self.width-l.XS, self.height-l.YS x, y = self.width-l.XS, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nnn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
x -= l.XS x -= l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)

View file

@ -103,7 +103,8 @@ class DieBoeseSieben(Game):
x, y, = l.XM + (2*i+8-rows)*l.XS/2, l.YM + l.YS x, y, = l.XM + (2*i+8-rows)*l.XS/2, l.YM + l.YS
s.rows.append(AC_RowStack(x, y, self)) s.rows.append(AC_RowStack(x, y, self))
s.talon = DieBoeseSieben_Talon(l.XM, self.height-l.YS, self, max_rounds=2) s.talon = DieBoeseSieben_Talon(l.XM, self.height-l.YS, self, max_rounds=2)
l.createText(s.talon, "se") l.createText(s.talon, 'ne')
l.createRoundText(s.talon, 'se')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -82,6 +82,8 @@ class Diplomat(Game):
x, y, = l.XM, self.height - l.YS x, y, = l.XM, self.height - l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds) s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
l.createText(s.talon, "n") l.createText(s.talon, "n")
if max_rounds > 1:
l.createRoundText(self.s.talon, 'nnn')
x = x + l.XS x = x + l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "n") l.createText(s.waste, "n")
@ -166,10 +168,7 @@ class Congress(Diplomat):
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
if max_rounds > 1: if max_rounds > 1:
tx, ty, ta, tf = l.getTextAttr(s.waste, "ne") l.createRoundText(s.talon, 'ne', dx=l.XS)
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -90,6 +90,7 @@ class Doublets(Game):
x = x + l.XS x = x + l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
l.createRoundText(s.talon, 'nn')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -108,11 +108,7 @@ class Fan(Game):
x, y = self.width - l.XS, self.height - l.YS x, y = self.width - l.XS, self.height - l.YS
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
if texts: if texts:
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -238,6 +234,8 @@ class LaBelleLucie_Talon(TalonStack):
class LaBelleLucie(Fan): class LaBelleLucie(Fan):
Talon_Class = StackWrapper(LaBelleLucie_Talon, max_rounds=3) Talon_Class = StackWrapper(LaBelleLucie_Talon, max_rounds=3)
RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK) RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK)
def createGame(self):
return Fan.createGame(self, texts=True)
# /*********************************************************************** # /***********************************************************************
@ -356,7 +354,7 @@ class Trefoil(LaBelleLucie):
Foundation_Classes = [StackWrapper(SS_FoundationStack, min_cards=1)] Foundation_Classes = [StackWrapper(SS_FoundationStack, min_cards=1)]
def createGame(self): def createGame(self):
return Fan.createGame(self, rows=(5,5,5,1)) return Fan.createGame(self, rows=(5,5,5,1), texts=True)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # move Aces to bottom of the Talon (i.e. last cards to be dealt)
@ -434,6 +432,7 @@ class Intelligence(Fan):
x, y = s.talon.x - l.XS, s.talon.y x, y = s.talon.x - l.XS, s.talon.y
s.reserves.append(Intelligence_ReserveStack(x, y, self, max_move=0, max_accept=0, max_cards=UNLIMITED_CARDS)) s.reserves.append(Intelligence_ReserveStack(x, y, self, max_move=0, max_accept=0, max_cards=UNLIMITED_CARDS))
l.createText(s.reserves[0], "sw") l.createText(s.reserves[0], "sw")
l.createRoundText(s.talon, 'nn')
# redefine the stack-groups # redefine the stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -713,10 +712,7 @@ class Crescent(Game):
self.setSize(w, h) self.setSize(w, h)
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = Crescent_Talon(x, y, self, max_rounds=4) s.talon = Crescent_Talon(x, y, self, max_rounds=4)
tx, ty, ta, tf = l.getTextAttr(s.talon, 'ne') l.createRoundText(s.talon, 'ne')
font=self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = w-8*l.XS, l.YM x, y = w-8*l.XS, l.YM
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
@ -765,7 +761,7 @@ class School(Fan):
RowStack_Class = StackWrapper(RK_RowStack, dir=0, base_rank=NO_RANK) RowStack_Class = StackWrapper(RK_RowStack, dir=0, base_rank=NO_RANK)
def createGame(self): def createGame(self):
Fan.createGame(self, rows=(4, 4, 4, 4), playcards=10) Fan.createGame(self, rows=(4, 4, 4, 4), playcards=10, texts=True)
def startGame(self): def startGame(self):
for i in range(2): for i in range(2):
@ -895,10 +891,7 @@ class ForestGlade(Game):
x, y = l.XM, self.height - l.YS x, y = l.XM, self.height - l.YS
s.talon = ForestGlade_Talon(x, y, self, max_rounds=3) s.talon = ForestGlade_Talon(x, y, self, max_rounds=3)
l.createText(s.talon, 'ne') l.createText(s.talon, 'ne')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'se') l.createRoundText(s.talon, 'se')
font=self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -115,13 +115,8 @@ class FortyThieves(Game):
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
l.createText(s.talon, "n") l.createText(s.talon, "n")
if max_rounds > 1: if max_rounds > 1:
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nnn')
font = self.app.getFont("canvas_default") x -= l.XS
s.talon.texts.rounds = MfxCanvasText(self.canvas,
tx, ty-l.TEXT_MARGIN,
anchor=ta,
font=font)
x = x - l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
s.waste.CARD_XOFFSET = -l.XOFFSET s.waste.CARD_XOFFSET = -l.XOFFSET
l.createText(s.waste, "n") l.createText(s.waste, "n")
@ -711,33 +706,34 @@ class Octagon(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
w1 = l.XS+12*l.XOFFSET w1 = l.XS+12*l.XOFFSET
w, h = l.XM+2*l.XS+2*w1, l.YM+3*l.YS w, h = l.XM+2*l.XS+2*w1, l.YM+4*l.YS
self.setSize(w, h) self.setSize(w, h)
for x, y in ((l.XM, l.YM), for x, y in ((l.XM, l.YM),
(l.XM+w1+2*l.XS+l.XM, l.YM), (l.XM+w1+2*l.XS+l.XM, l.YM),
(l.XM, l.YM+2*l.YS), (l.XM, l.YM+3*l.YS),
(l.XM+w1+2*l.XS+l.XM, l.YM+2*l.YS),): (l.XM+w1+2*l.XS+l.XM, l.YM+3*l.YS),):
stack = SS_RowStack(x, y, self, max_move=1) stack = SS_RowStack(x, y, self, max_move=1)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
s.rows.append(stack) s.rows.append(stack)
i = 0 i = 0
for x, y in ((l.XM+w1, l.YM), for x, y in ((l.XM+w1, l.YM),
(l.XM+w1+l.XS, l.YM), (l.XM+w1+l.XS, l.YM),
(l.XM+w1-2*l.XS-l.XS/2-l.XM, l.YM+l.YS), (l.XM+w1-2*l.XS-l.XS/2-l.XM, l.YM+1.5*l.YS),
(l.XM+w1-l.XS-l.XS/2-l.XM, l.YM+l.YS), (l.XM+w1-l.XS-l.XS/2-l.XM, l.YM+1.5*l.YS),
(l.XM+w1+2*l.XS+l.XS/2+l.XM, l.YM+l.YS), (l.XM+w1+2*l.XS+l.XS/2+l.XM, l.YM+1.5*l.YS),
(l.XM+w1+3*l.XS+l.XS/2+l.XM, l.YM+l.YS), (l.XM+w1+3*l.XS+l.XS/2+l.XM, l.YM+1.5*l.YS),
(l.XM+w1, l.YM+2*l.YS), (l.XM+w1, l.YM+3*l.YS),
(l.XM+w1+l.XS, l.YM+2*l.YS),): (l.XM+w1+l.XS, l.YM+3*l.YS),):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4)) s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4))
i += 1 i += 1
x, y = l.XM+w1, l.YM+l.YS x, y = l.XM+w1, l.YM+1.5*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=4) s.talon = WasteTalonStack(x, y, self, max_rounds=4)
l.createText(s.talon, 'nw') l.createText(s.talon, 's')
l.createRoundText(s.talon, 'nn')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'ne') l.createText(s.waste, 's')
l.defaultStackGroups() l.defaultStackGroups()
@ -1154,6 +1150,82 @@ class Floradora(Game):
shallHighlightMatch = Game._shallHighlightMatch_RK shallHighlightMatch = Game._shallHighlightMatch_RK
# /***********************************************************************
# // Blind Patience
# ************************************************************************/
class BlindPatience_Hint(DefaultHint):
SCORE_FLIP = 80000
def shallMovePile(self, from_stack, to_stack, pile, rpile):
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
return False
#
if len(rpile) == 0:
return True
# now check for loops
rr = self.ClonedStack(from_stack, stackcards=rpile)
if self.level < 2:
# hint
if to_stack.cards and not to_stack.cards[-1].face_up:
if rr.cards and not rr.cards[-1].face_up:
return True
if rr.cards and not rr.cards[-1].face_up:
return True
if not to_stack.cards:
return True
else:
# demo mode
if rr.cards and not rr.cards[-1].face_up:
if len(rr.cards) < len(to_stack.cards):
return True
if rr.acceptsCards(to_stack, pile):
# the pile we are going to move could be moved back -
# this is dangerous as we can create endless loops...
return False
return True
class BlindPatience_RowStack(AC_RowStack):
def acceptsCards(self, from_stack, cards):
if self.cards and not self.cards[-1].face_up:
return True
return AC_RowStack.acceptsCards(self, from_stack, cards)
class BlindPatience(FortyThieves):
Hint_Class = BlindPatience_Hint
RowStack_Class = BlindPatience_RowStack
def startGame(self):
for i in range(3):
self.s.talon.dealRow(flip=0, frames=0)
self.startDealSample()
self.s.talon.dealRow(flip=0)
self.s.talon.dealCards() # deal first card to WasteStack
def getAutoStacks(self, event=None):
if event is None:
# do not auto flip
return ([], self.sg.dropstacks, self.sg.dropstacks)
return (self.sg.dropstacks, self.sg.dropstacks, self.sg.dropstacks)
def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack in self.s.rows:
if to_stack.cards:
if to_stack.cards[-1].face_up:
# top card is face up
return 1001
else:
return 1000
else:
return 999
# prefer non-empty piles in to_stack
return 1001 + int(len(to_stack.cards) != 0)
shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game # register the game
registerGame(GameInfo(13, FortyThieves, "Forty Thieves", registerGame(GameInfo(13, FortyThieves, "Forty Thieves",
@ -1271,4 +1343,6 @@ registerGame(GameInfo(679, TripleInterchange, "Triple Interchange",
GI.GT_FORTY_THIEVES, 3, -1, GI.SL_MOSTLY_SKILL)) GI.GT_FORTY_THIEVES, 3, -1, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(683, FamousFifty, "Famous Fifty", registerGame(GameInfo(683, FamousFifty, "Famous Fifty",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(751, BlindPatience, "Blind Patience",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -104,16 +104,17 @@ class Glenwood(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
self.setSize(2*l.XM + 6*l.XS, l.YM + l.TEXT_HEIGHT + 5*l.YS) self.setSize(l.XM + 7*l.XS, l.YM + l.TEXT_HEIGHT + 5*l.YS)
# create stacks # create stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = Glenwood_Talon(x, y, self, max_rounds=2, num_deal=1) s.talon = Glenwood_Talon(x, y, self, max_rounds=2, num_deal=1)
l.createText(s.talon, "s") l.createText(s.talon, "s")
l.createRoundText(s.talon, 'ne', dx=l.XS)
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
x += l.XS+l.XM x += 2*l.XS
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, i, dir=1, s.foundations.append(self.Foundation_Class(x, y, self, i, dir=1,
mod=13, base_rank=ANY_RANK, max_move=0)) mod=13, base_rank=ANY_RANK, max_move=0))
@ -126,7 +127,7 @@ class Glenwood(Game):
anchor=ta, font=font) anchor=ta, font=font)
for i in range(4): for i in range(4):
x = 2*l.XM + (i+2)*l.XS x = l.XM + (i+3)*l.XS
y = l.YM+l.TEXT_HEIGHT+l.YS y = l.YM+l.TEXT_HEIGHT+l.YS
s.rows.append(self.RowStack_Class(x, y, self, mod=13)) s.rows.append(self.RowStack_Class(x, y, self, mod=13))
for i in range(4): for i in range(4):
@ -269,6 +270,7 @@ class DoubleFives(Glenwood):
x, y = l.XM, self.height-l.YS x, y = l.XM, self.height-l.YS
s.talon = DoubleFives_Talon(x, y, self, max_rounds=2, num_deal=1) s.talon = DoubleFives_Talon(x, y, self, max_rounds=2, num_deal=1)
l.createText(s.talon, "n") l.createText(s.talon, "n")
l.createRoundText(self.s.talon, 'nnn')
x += l.XS x += l.XS
for i in range(5): for i in range(5):
s.reserves.append(DoubleFives_WasteStack(x, y, self)) s.reserves.append(DoubleFives_WasteStack(x, y, self))

View file

@ -493,10 +493,11 @@ class Robert(Game):
s.foundations.append(BlackHole_Foundation(x, y, self, ANY_SUIT, dir=0, mod=13, max_move=0, max_cards=52)) s.foundations.append(BlackHole_Foundation(x, y, self, ANY_SUIT, dir=0, mod=13, max_move=0, max_cards=52))
x, y = l.XM+l.XS, l.YM+l.YS x, y = l.XM+l.XS, l.YM+l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'sw') l.createText(s.talon, 'nw')
l.createRoundText(self.s.talon, 'se', dx=l.XS)
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'se') l.createText(s.waste, 'ne')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -581,6 +582,7 @@ class Dolphin(Game):
max_cards = 52*self.gameinfo.decks max_cards = 52*self.gameinfo.decks
s.foundations.append(RK_FoundationStack(x, y, self, s.foundations.append(RK_FoundationStack(x, y, self,
base_rank=ANY_RANK, mod=13, max_cards=max_cards)) base_rank=ANY_RANK, mod=13, max_cards=max_cards))
l.createText(s.foundations[0], 'ne')
x, y = l.XM, l.YM+l.YS x, y = l.XM, l.YM+l.YS
for i in range(rows): for i in range(rows):
s.rows.append(BasicRowStack(x, y, self)) s.rows.append(BasicRowStack(x, y, self))
@ -817,11 +819,7 @@ class DevilsSolitaire(Game):
x, y = l.XM+4.5*l.XS, self.height-l.YS x, y = l.XM+4.5*l.XS, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') l.createRoundText(s.talon, 'nnn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
x -= l.XS x -= l.XS
s.waste = DevilsSolitaire_WasteStack(x, y, self) s.waste = DevilsSolitaire_WasteStack(x, y, self)
l.createText(s.waste, 'n') l.createText(s.waste, 'n')
@ -970,11 +968,7 @@ class NapoleonTakesMoscow(Game, FirTree_GameMethods):
x, y = l.XM, self.height-l.YS x, y = l.XM, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') l.createRoundText(s.talon, 'nnn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'n') l.createText(s.waste, 'n')

View file

@ -91,10 +91,7 @@ class GrandDuchess(Game):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = GrandDuchess_Talon(x, y, self, max_rounds=4) s.talon = GrandDuchess_Talon(x, y, self, max_rounds=4)
l.createText(s.talon, 'se') l.createText(s.talon, 'se')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'ne') l.createRoundText(s.talon, 'ne')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x += 2*l.XS x += 2*l.XS
for i in range(4): for i in range(4):

View file

@ -170,6 +170,7 @@ class Dial(Game):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, 's') l.createText(s.talon, 's')
l.createRoundText(s.talon, 'sss')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 's') l.createText(s.waste, 's')

View file

@ -860,10 +860,7 @@ class LockedCards(Game):
x, y = self.width-l.XS, self.height-l.YS x, y = self.width-l.XS, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') l.createRoundText(s.talon, 'nnn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
x -= l.XS x -= l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)

View file

@ -77,13 +77,10 @@ class DoubleKlondike(Game):
l.defaultAll() l.defaultAll()
# extra # extra
if max_rounds > 1: if max_rounds > 1:
assert s.talon.texts.rounds is None anchor = 'nn'
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
if layout.get("texts"): if layout.get("texts"):
ty = ty - l.TEXT_MARGIN anchor = 'nnn'
font = self.app.getFont("canvas_default") l.createRoundText(s.talon, anchor)
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
return l return l
def startGame(self, flip=0): def startGame(self, flip=0):
@ -249,12 +246,9 @@ class BigDeal(DoubleKlondike):
s.waste.CARD_XOFFSET = XOFFSET s.waste.CARD_XOFFSET = XOFFSET
l.createText(s.waste, 'n') l.createText(s.waste, 'n')
if max_rounds > 1: if max_rounds > 1:
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') l.createRoundText(s.talon, 'nnn')
ty -= l.TEXT_MARGIN self.setRegion(s.rows, (-999, -999, l.XM+rows*l.XS-l.CW/2, 999999),
font = self.app.getFont('canvas_default') priority=1)
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
self.setRegion(s.rows, (-999, -999, l.XM+rows*l.XS-l.CW/2, 999999), priority=1)
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -99,10 +99,11 @@ class VegasKlondike(Klondike):
getGameBalance = Game.getGameScoreCasino getGameBalance = Game.getGameScoreCasino
def createGame(self, max_rounds=1): def createGame(self, max_rounds=1):
Klondike.createGame(self, max_rounds=max_rounds) l = Klondike.createGame(self, max_rounds=max_rounds)
self.texts.score = MfxCanvasText(self.canvas, self.texts.score = MfxCanvasText(self.canvas,
8, self.height - 8, anchor="sw", 8, self.height - 8, anchor="sw",
font=self.app.getFont("canvas_large")) font=self.app.getFont("canvas_large"))
return l
def updateText(self): def updateText(self):
if self.preview > 1: if self.preview > 1:
@ -123,7 +124,8 @@ class VegasKlondike(Klondike):
class CasinoKlondike(VegasKlondike): class CasinoKlondike(VegasKlondike):
def createGame(self): def createGame(self):
VegasKlondike.createGame(self, max_rounds=3) l = VegasKlondike.createGame(self, max_rounds=3)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
# /*********************************************************************** # /***********************************************************************
@ -156,7 +158,9 @@ class Chinaman(ThumbAndPouch):
RowStack_Class = StackWrapper(BO_RowStack, base_rank=KING) RowStack_Class = StackWrapper(BO_RowStack, base_rank=KING)
def createGame(self): def createGame(self):
Klondike.createGame(self, num_deal=3, max_rounds=2) l = Klondike.createGame(self, num_deal=3,
max_rounds=2, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
# /*********************************************************************** # /***********************************************************************
@ -271,7 +275,8 @@ class PasSeul(Eastcliff):
class BlindAlleys(Eastcliff): class BlindAlleys(Eastcliff):
def createGame(self): def createGame(self):
Klondike.createGame(self, max_rounds=2, rows=6) l = Klondike.createGame(self, max_rounds=2, rows=6, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt) # move Aces to top of the Talon (i.e. first cards to be dealt)
@ -317,7 +322,9 @@ class Usk(Somerset):
Solver_Class = None Solver_Class = None
def createGame(self): def createGame(self):
Klondike.createGame(self, max_rounds=2, rows=10, waste=0, texts=0) l = Klondike.createGame(self, max_rounds=2, rows=10,
waste=False, texts=False, round_text=True)
l.createRoundText(self.s.talon, 'ne')
def redealCards(self): def redealCards(self):
n = 0 n = 0
@ -403,12 +410,8 @@ class EightTimesEight(Klondike):
class AchtmalAcht(EightTimesEight): class AchtmalAcht(EightTimesEight):
def createGame(self): def createGame(self):
l = Klondike.createGame(self, rows=8, max_rounds=3) l = Klondike.createGame(self, rows=8, max_rounds=3, round_text=True)
s = self.s l.createRoundText(self.s.talon, 'sw', dx=-l.XS)
x, y = s.waste.x - l.XM, s.waste.y
s.talon.texts.rounds = MfxCanvasText(self.canvas, x, y,
anchor="ne",
font=self.app.getFont("canvas_default"))
class EightByEight_RowStack(RK_RowStack): class EightByEight_RowStack(RK_RowStack):
@ -425,7 +428,8 @@ class EightByEight(EightTimesEight):
RowStack_Class = EightByEight_RowStack RowStack_Class = EightByEight_RowStack
def createGame(self): def createGame(self):
Klondike.createGame(self, rows=8, max_rounds=3) l = Klondike.createGame(self, rows=8, max_rounds=3, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
shallHighlightMatch = Game._shallHighlightMatch_RK shallHighlightMatch = Game._shallHighlightMatch_RK
@ -447,12 +451,16 @@ class Batsford_ReserveStack(ReserveStack):
class Batsford(Klondike): class Batsford(Klondike):
def createGame(self, **layout): def createGame(self, **layout):
kwdefault(layout, rows=10, max_rounds=1, playcards=22) kwdefault(layout, rows=10, max_rounds=1, playcards=22)
round_text = (layout['max_rounds'] > 1)
layout['round_text'] = round_text
l = Klondike.createGame(self, **layout) l = Klondike.createGame(self, **layout)
s = self.s s = self.s
x, y = l.XM, self.height - l.YS x, y = l.XM, self.height - l.YS
s.reserves.append(Batsford_ReserveStack(x, y, self, max_cards=3)) s.reserves.append(Batsford_ReserveStack(x, y, self, max_cards=3))
self.setRegion(s.reserves, (-999, y - l.YM, x + l.XS, 999999), priority=1) self.setRegion(s.reserves, (-999, y - l.YM - l.CH/2, x + l.XS - l.CW/2, 999999), priority=1)
l.createText(s.reserves[0], "se") l.createText(s.reserves[0], "se")
if round_text:
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
l.defaultStackGroups() l.defaultStackGroups()
@ -467,7 +475,8 @@ class BatsfordAgain(Batsford):
class Jumbo(Klondike): class Jumbo(Klondike):
def createGame(self): def createGame(self):
Klondike.createGame(self, rows=9, max_rounds=2) l = Klondike.createGame(self, rows=9, max_rounds=2, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
def startGame(self, flip=0): def startGame(self, flip=0):
for i in range(9): for i in range(9):
@ -805,7 +814,8 @@ class Lanes(Klondike):
RowStack_Class = StackWrapper(AC_RowStack, base_rank=ANY_RANK, max_move=1) RowStack_Class = StackWrapper(AC_RowStack, base_rank=ANY_RANK, max_move=1)
def createGame(self): def createGame(self):
Klondike.createGame(self, rows=6, max_rounds=2) l = Klondike.createGame(self, rows=6, max_rounds=2, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt) # move Aces to top of the Talon (i.e. first cards to be dealt)
@ -866,7 +876,8 @@ class Q_C_(Klondike):
RowStack_Class = StackWrapper(SS_RowStack, base_rank=ANY_RANK, max_move=1) RowStack_Class = StackWrapper(SS_RowStack, base_rank=ANY_RANK, max_move=1)
def createGame(self): def createGame(self):
Klondike.createGame(self, rows=6, max_rounds=2) l = Klondike.createGame(self, rows=6, max_rounds=2)
l.createRoundText(self.s.talon, 'sss')
def startGame(self): def startGame(self):
for i in range(3): for i in range(3):
@ -1044,7 +1055,9 @@ class MovingLeft(Klondike):
class Souter(MovingLeft): class Souter(MovingLeft):
def createGame(self): def createGame(self):
Klondike.createGame(self, max_rounds=2, rows=10, playcards=24) l = Klondike.createGame(self, max_rounds=2, rows=10,
playcards=24, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
# /*********************************************************************** # /***********************************************************************
@ -1127,7 +1140,8 @@ class Whitehorse(Klondike):
class Boost(Klondike): class Boost(Klondike):
def createGame(self): def createGame(self):
Klondike.createGame(self, rows=4, max_rounds=3) l = Klondike.createGame(self, rows=4, max_rounds=3, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
# /*********************************************************************** # /***********************************************************************
@ -1137,7 +1151,8 @@ class Boost(Klondike):
class GoldRush(Klondike): class GoldRush(Klondike):
Talon_Class = CanfieldRush_Talon Talon_Class = CanfieldRush_Talon
def createGame(self): def createGame(self):
Klondike.createGame(self, max_rounds=3) l = Klondike.createGame(self, max_rounds=3, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
# /*********************************************************************** # /***********************************************************************
@ -1344,7 +1359,9 @@ class EightSages(Klondike):
RowStack_Class = EightSages_Row RowStack_Class = EightSages_Row
def createGame(self): def createGame(self):
Klondike.createGame(self, max_rounds=2, rows=8, playcards=12) l = Klondike.createGame(self, max_rounds=2, rows=8,
playcards=12, round_text=True)
l.createRoundText(self.s.talon, 'ne', dx=l.XS)
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()

View file

@ -247,11 +247,8 @@ class LarasGame(Game):
x, y = l.XM + l.XS * (ROW_LENGTH + 2), h - l.YM - l.YS * 3 x, y = l.XM + l.XS * (ROW_LENGTH + 2), h - l.YM - l.YS * 3
s.talon = self.Talon_Class(x, y, self, max_rounds=self.MAX_ROUNDS) s.talon = self.Talon_Class(x, y, self, max_rounds=self.MAX_ROUNDS)
l.createText(s.talon, "s") l.createText(s.talon, "s")
if self.MAX_ROUNDS - 1: if self.MAX_ROUNDS > 1:
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
s.talon.texts.rounds = MfxCanvasText(self.canvas,
tx, ty, anchor=ta,
font=self.app.getFont("canvas_default"))
y = h - l.YS * 2 y = h - l.YS * 2
s.rows.append(LarasGame_RowStack(x, y, self, yoffset=0)) s.rows.append(LarasGame_RowStack(x, y, self, yoffset=0))

View file

@ -192,9 +192,7 @@ class Matriarchy(Game):
y = c2 + l.CH / 2 y = c2 + l.CH / 2
s.talon = Matriarchy_Talon(x, y, self, max_rounds=VARIABLE_REDEALS) s.talon = Matriarchy_Talon(x, y, self, max_rounds=VARIABLE_REDEALS)
l.createText(s.talon, "n") l.createText(s.talon, "n")
s.talon.texts.rounds = MfxCanvasText(self.canvas, l.createRoundText(s.talon, 'ss')
tx, y + l.YS, anchor="n",
font=self.app.getFont("canvas_default"))
s.talon.texts.misc = MfxCanvasText(self.canvas, s.talon.texts.misc = MfxCanvasText(self.canvas,
tx, center, anchor="center", tx, center, anchor="center",
font=self.app.getFont("canvas_large")) font=self.app.getFont("canvas_large"))

View file

@ -168,7 +168,7 @@ class Montana(Game):
RLEN, RSTEP, RBASE = 52, 13, 1 RLEN, RSTEP, RBASE = 52, 13, 1
def createGame(self): def createGame(self, round_text=True):
# create layout # create layout
l, s = Layout(self, card_x_space=4), self.s l, s = Layout(self, card_x_space=4), self.s
@ -183,6 +183,8 @@ class Montana(Game):
x = x + l.XS x = x + l.XS
x = l.XM + (self.RSTEP-1)*l.XS/2 x = l.XM + (self.RSTEP-1)*l.XS/2
s.talon = self.Talon_Class(x, self.height-l.YS, self) s.talon = self.Talon_Class(x, self.height-l.YS, self)
if round_text:
l.createRoundText(s.talon, 'se')
if self.RBASE: if self.RBASE:
# create an invisible stack to hold the four Aces # create an invisible stack to hold the four Aces
s.internals.append(InvisibleStack(self)) s.internals.append(InvisibleStack(self))
@ -387,6 +389,8 @@ class SpacesAndAces(BlueMoon):
Talon_Class = InitialDealTalonStack Talon_Class = InitialDealTalonStack
RowStack_Class = SpacesAndAces_RowStack RowStack_Class = SpacesAndAces_RowStack
def createGame(self):
Montana.createGame(self, round_text=False)
# /*********************************************************************** # /***********************************************************************
# // Paganini # // Paganini

View file

@ -148,6 +148,8 @@ class Numerica(Game):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
return l
# #
# game overrides # game overrides
@ -280,26 +282,27 @@ class PussInTheCorner(Numerica):
def createGame(self, rows=4): def createGame(self, rows=4):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM+4*l.XS, l.YM+4*l.YS) self.setSize(l.XM+5*l.XS, l.YM+4*l.YS)
for x, y in ((l.XM, l.YM ), for x, y in ((l.XM, l.YM ),
(l.XM+3*l.XS, l.YM ), (l.XM+4*l.XS, l.YM ),
(l.XM, l.YM+3*l.YS), (l.XM, l.YM+3*l.YS),
(l.XM+3*l.XS, l.YM+3*l.YS), (l.XM+4*l.XS, l.YM+3*l.YS),
): ):
stack = PussInTheCorner_RowStack(x, y, self, stack = PussInTheCorner_RowStack(x, y, self,
max_accept=1, max_move=1) max_accept=1, max_move=1)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
s.rows.append(stack) s.rows.append(stack)
for x, y in ((l.XM+ l.XS, l.YM+ l.YS), for x, y in ((l.XM+1.5*l.XS, l.YM+ l.YS),
(l.XM+ l.XS, l.YM+2*l.YS), (l.XM+1.5*l.XS, l.YM+2*l.YS),
(l.XM+2*l.XS, l.YM+ l.YS), (l.XM+2.5*l.XS, l.YM+ l.YS),
(l.XM+2*l.XS, l.YM+2*l.YS), (l.XM+2.5*l.XS, l.YM+2*l.YS),
): ):
s.foundations.append(PussInTheCorner_Foundation(x, y, self, s.foundations.append(PussInTheCorner_Foundation(x, y, self,
max_move=0)) max_move=0))
x, y = l.XM+3*l.XS/2, l.YM x, y = l.XM + 2*l.XS, l.YM
s.waste = s.talon = PussInTheCorner_Talon(x, y, self, max_rounds=2) s.waste = s.talon = PussInTheCorner_Talon(x, y, self, max_rounds=2)
l.createText(s.talon, 'se') l.createText(s.talon, 'se')
l.createRoundText(self.s.talon, 'ne')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -744,7 +747,7 @@ class AnnoDomini(Numerica):
RowStack_Class = StackWrapper(AC_RowStack, mod=13) RowStack_Class = StackWrapper(AC_RowStack, mod=13)
def createGame(self): def createGame(self):
Numerica.createGame(self, max_rounds=3, waste_max_cards=UNLIMITED_CARDS) l = Numerica.createGame(self, max_rounds=3, waste_max_cards=UNLIMITED_CARDS)
year = str(time.localtime()[0]) year = str(time.localtime()[0])
i = 0 i = 0
for s in self.s.foundations: for s in self.s.foundations:
@ -756,6 +759,7 @@ class AnnoDomini(Numerica):
d = JACK d = JACK
s.cap.base_rank = d s.cap.base_rank = d
i += 1 i += 1
l.createRoundText(self.s.talon, 'nn')
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()

View file

@ -174,11 +174,8 @@ class PasDeDeux(Game):
x, y = self.width - 2*l.XS, self.height - l.YS x, y = self.width - 2*l.XS, self.height - l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, "se") l.createText(s.talon, "se")
s.talon.texts.rounds = MfxCanvasText(self.canvas, l.createRoundText(s.talon, 'ne')
x + l.XS, y, x -= l.XS
anchor="nw",
font=self.app.getFont("canvas_default"))
x = x - l.XS
s.waste = PasDeDeux_Waste(x, y, self, max_move=0) s.waste = PasDeDeux_Waste(x, y, self, max_move=0)
l.createText(s.waste, "sw") l.createText(s.waste, "sw")
s.internals.append(InvisibleStack(self)) # for _swapPairMove() s.internals.append(InvisibleStack(self)) # for _swapPairMove()

View file

@ -157,6 +157,7 @@ class Foursome(Game):
x = l.XM+(max_rows-1)*l.XS x = l.XM+(max_rows-1)*l.XS
s.foundations.append(AbstractFoundationStack(x, y, self, s.foundations.append(AbstractFoundationStack(x, y, self,
suit=ANY_SUIT, max_cards=52, max_accept=0)) suit=ANY_SUIT, max_cards=52, max_accept=0))
l.createText(s.foundations[0], 'nw')
x, y = l.XM+l.XS*(max_rows-rows)/2, l.YM+l.YS x, y = l.XM+l.XS*(max_rows-rows)/2, l.YM+l.YS
for i in range(rows): for i in range(rows):
s.rows.append(UD_AC_RowStack(x, y, self, mod=13)) s.rows.append(UD_AC_RowStack(x, y, self, mod=13))

View file

@ -240,10 +240,7 @@ class Pyramid(Game):
if texts: if texts:
l.createText(s.talon, "se") l.createText(s.talon, "se")
if s.talon.max_rounds > 1: if s.talon.max_rounds > 1:
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font=self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
if waste: if waste:
y = y + l.YS y = y + l.YS
s.waste = self.WasteStack_Class(x, y, self, max_accept=1) s.waste = self.WasteStack_Class(x, y, self, max_accept=1)
@ -252,6 +249,7 @@ class Pyramid(Game):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=52*decks)) max_move=0, max_cards=52*decks))
l.createText(s.foundations[0], 's')
if reserves: if reserves:
x, y = l.XM+(max_rows-reserves)*l.XS/2, l.YM+4*l.YS x, y = l.XM+(max_rows-reserves)*l.XS/2, l.YM+4*l.YS
for i in range(reserves): for i in range(reserves):
@ -402,6 +400,7 @@ class Thirteens(Pyramid):
s.foundations.append(Pyramid_Foundation(x, y, self, s.foundations.append(Pyramid_Foundation(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=52)) max_move=0, max_cards=52))
l.createText(s.foundations[0], 'n')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -480,6 +479,7 @@ class Elevens(Pyramid):
s.foundations.append(AbstractFoundationStack(x, y, self, s.foundations.append(AbstractFoundationStack(x, y, self,
suit=ANY_SUIT, max_accept=0, suit=ANY_SUIT, max_accept=0,
max_move=0, max_cards=52)) max_move=0, max_cards=52))
l.createText(s.foundations[0], 'n')
y = l.YM y = l.YM
for i in range(rows): for i in range(rows):
x = l.XM x = l.XM
@ -684,6 +684,7 @@ class TripleAlliance(Game):
x, y = self.width-l.XS, l.YM x, y = self.width-l.XS, l.YM
s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT, s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT,
max_move=0, max_accept=0, max_cards=52)) max_move=0, max_accept=0, max_cards=52))
l.createText(s.foundations[0], 'nw')
y = l.YM+l.YS y = l.YM+l.YS
nstacks = 0 nstacks = 0
for i in range(4): for i in range(4):
@ -836,6 +837,7 @@ class Baroness(Pyramid):
s.foundations.append(Pyramid_Foundation(x, y, self, s.foundations.append(Pyramid_Foundation(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=52)) max_move=0, max_cards=52))
l.createText(s.foundations[0], 's')
x, y = l.XM, self.height-l.YS x, y = l.XM, self.height-l.YS
s.reserves.append(Giza_Reserve(x, y, self, max_accept=1)) s.reserves.append(Giza_Reserve(x, y, self, max_accept=1))
y -= l.YS y -= l.YS
@ -899,10 +901,8 @@ class Apophis(Pharaohs):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = DealReserveRedealTalonStack(x, y, self, max_rounds=3) s.talon = DealReserveRedealTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'se') l.createText(s.talon, 'se')
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
y += l.YS y += l.YS
for i in range(3): for i in range(3):
stack = Pyramid_Waste(x, y, self, max_accept=1) stack = Pyramid_Waste(x, y, self, max_accept=1)
@ -913,6 +913,7 @@ class Apophis(Pharaohs):
s.foundations.append(Pyramid_Foundation(x, y, self, s.foundations.append(Pyramid_Foundation(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=52)) max_move=0, max_cards=52))
l.createText(s.foundations[0], 'nw')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -1087,10 +1088,8 @@ class TwoPyramids(Pyramid):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, "se") l.createText(s.talon, "se")
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
y += l.YS y += l.YS
s.waste = self.WasteStack_Class(x, y, self, max_accept=1) s.waste = self.WasteStack_Class(x, y, self, max_accept=1)
l.createText(s.waste, "se") l.createText(s.waste, "se")
@ -1098,6 +1097,7 @@ class TwoPyramids(Pyramid):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=104)) max_move=0, max_cards=104))
l.createText(s.foundations[0], 'nw')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
self.sg.openstacks.append(s.talon) self.sg.openstacks.append(s.talon)
@ -1133,6 +1133,7 @@ class KingTut(RelaxedPyramid):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=52)) max_move=0, max_cards=52))
l.createText(s.foundations[0], 'nw')
l.defaultStackGroups() l.defaultStackGroups()
self.sg.openstacks.append(s.waste) self.sg.openstacks.append(s.waste)
@ -1169,10 +1170,8 @@ class Triangle(Pyramid):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, "se") l.createText(s.talon, "se")
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font=self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
y += l.YS y += l.YS
s.waste = self.WasteStack_Class(x, y, self, max_accept=1) s.waste = self.WasteStack_Class(x, y, self, max_accept=1)
l.createText(s.waste, "se") l.createText(s.waste, "se")
@ -1212,10 +1211,8 @@ class UpAndDown(Pyramid):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, "se") l.createText(s.talon, "se")
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font=self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
y += l.YS y += l.YS
s.waste = self.WasteStack_Class(x, y, self, max_accept=1) s.waste = self.WasteStack_Class(x, y, self, max_accept=1)
l.createText(s.waste, "se") l.createText(s.waste, "se")
@ -1223,6 +1220,7 @@ class UpAndDown(Pyramid):
s.foundations.append(self.Foundation_Class(x, y, self, s.foundations.append(self.Foundation_Class(x, y, self,
suit=ANY_SUIT, dir=0, base_rank=ANY_RANK, suit=ANY_SUIT, dir=0, base_rank=ANY_RANK,
max_move=0, max_cards=104)) max_move=0, max_cards=104))
l.createText(s.foundations[0], 'sw')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -41,6 +41,7 @@ from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText
from unionsquare import UnionSquare_Foundation from unionsquare import UnionSquare_Foundation
@ -153,6 +154,7 @@ class OddAndEven(RoyalCotillion):
x, y = l.XM, self.height - l.YS x, y = l.XM, self.height - l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, "n") l.createText(s.talon, "n")
l.createRoundText(s.talon, 'nnn')
x = x + l.XS x = x + l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "n") l.createText(s.waste, "n")
@ -189,15 +191,15 @@ class Kingdom(RoyalCotillion):
x, y, = l.XM, l.YM x, y, = l.XM, l.YM
for i in range(8): for i in range(8):
s.foundations.append(self.Foundation_Class(x, y, self, ANY_SUIT)) s.foundations.append(self.Foundation_Class(x, y, self, ANY_SUIT))
x = x + l.XS x += l.XS
x, y, = l.XM, y + l.YS x, y, = l.XM, y + l.YS
for i in range(8): for i in range(8):
s.reserves.append(ReserveStack(x, y, self, max_accept=0)) s.reserves.append(ReserveStack(x, y, self, max_accept=0))
x = x + l.XS x += l.XS
x, y = l.XM + 3*l.XS, y + 3*l.YS/2 x, y = l.XM + 3*l.XS, l.YM + 3*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=1) s.talon = WasteTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, "sw") l.createText(s.talon, "sw")
x = x + l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "se") l.createText(s.waste, "se")
@ -223,6 +225,7 @@ class Kingdom(RoyalCotillion):
# /*********************************************************************** # /***********************************************************************
# // Alhambra # // Alhambra
# // Granada # // Granada
# // Reserves
# // Grant's Reinforcement # // Grant's Reinforcement
# ************************************************************************/ # ************************************************************************/
@ -233,6 +236,8 @@ class Alhambra_Hint(CautiousDefaultHint):
class Alhambra_RowStack(UD_SS_RowStack): class Alhambra_RowStack(UD_SS_RowStack):
getBottomImage = Stack._getReserveBottomImage getBottomImage = Stack._getReserveBottomImage
def getHelp(self):
return _('Waste. Build up or down by suit.')
class Alhambra_Talon(DealRowTalonStack): class Alhambra_Talon(DealRowTalonStack):
@ -244,6 +249,13 @@ class Alhambra_Talon(DealRowTalonStack):
return True return True
return False return False
def _deal(self):
num_cards = 0
for r in self.game.s.rows:
if self.cards:
self.game.flipAndMoveMove(self, r)
num_cards += 1
def dealCards(self, sound=False): def dealCards(self, sound=False):
old_state = self.game.enterState(self.game.S_DEAL) old_state = self.game.enterState(self.game.S_DEAL)
num_cards = 0 num_cards = 0
@ -252,7 +264,10 @@ class Alhambra_Talon(DealRowTalonStack):
if self.cards: if self.cards:
if sound and not self.game.demo: if sound and not self.game.demo:
self.game.playSample("dealwaste") self.game.playSample("dealwaste")
if len(self.game.s.rows) > 1:
num_cards = self.dealRowAvail(sound=False, frames=4) num_cards = self.dealRowAvail(sound=False, frames=4)
else:
num_cards = self._deal()
elif r_cards and self.round != self.max_rounds: elif r_cards and self.round != self.max_rounds:
if sound: if sound:
self.game.playSample("turnwaste", priority=20) self.game.playSample("turnwaste", priority=20)
@ -260,7 +275,10 @@ class Alhambra_Talon(DealRowTalonStack):
for i in range(len(r.cards)): for i in range(len(r.cards)):
self.game.moveMove(1, r, self, frames=0) self.game.moveMove(1, r, self, frames=0)
self.game.flipMove(self) self.game.flipMove(self)
if len(self.game.s.rows) > 1:
num_cards = self.dealRowAvail(sound=False, frames=4) num_cards = self.dealRowAvail(sound=False, frames=4)
else:
num_cards = self._deal()
self.game.nextRoundMove(self) self.game.nextRoundMove(self)
self.game.leaveState(old_state) self.game.leaveState(old_state)
return num_cards return num_cards
@ -276,7 +294,9 @@ class Alhambra(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
self.setSize(l.XM+8*l.XS, l.YM+3.5*l.YS+playcards*l.YOFFSET) w, h = l.XM+8*l.XS, l.YM+3.5*l.YS+playcards*l.YOFFSET
h += l.TEXT_HEIGHT
self.setSize(w, h)
# create stacks # create stacks
x, y, = l.XM, l.YM x, y, = l.XM, l.YM
@ -296,7 +316,15 @@ class Alhambra(Game):
x = x + l.XS x = x + l.XS
x, y = l.XM+(8-1-rows)*l.XS/2, self.height-l.YS x, y = l.XM+(8-1-rows)*l.XS/2, self.height-l.YS
s.talon = Alhambra_Talon(x, y, self, max_rounds=3) s.talon = Alhambra_Talon(x, y, self, max_rounds=3)
l.createText(s.talon, "sw") if rows == 1:
l.createText(s.talon, 'sw')
else:
l.createText(s.talon, 'n')
anchor = 'nn'
if rows > 1:
anchor = 'nnn'
l.createRoundText(s.talon, anchor)
x += l.XS x += l.XS
for i in range(rows): for i in range(rows):
stack = self.RowStack_Class(x, y, self, mod=13, max_accept=1) stack = self.RowStack_Class(x, y, self, mod=13, max_accept=1)
@ -305,6 +333,8 @@ class Alhambra(Game):
x += l.XS x += l.XS
if rows == 1: if rows == 1:
l.createText(stack, 'se') l.createText(stack, 'se')
else:
l.createText(stack, 'n')
# define stack-groups (non default) # define stack-groups (non default)
l.defaultStackGroups() l.defaultStackGroups()
@ -333,8 +363,13 @@ class Granada(Alhambra):
Alhambra.createGame(self, rows=4) Alhambra.createGame(self, rows=4)
class GrantsReinforcement(Alhambra): class Reserves_RowStack(UD_RK_RowStack):
RowStack_Class = StackWrapper(Alhambra_RowStack, base_rank=NO_RANK) getBottomImage = Stack._getReserveBottomImage
def getHelp(self):
return _('Waste. Build up or down regardless of suit.')
class Reserves(Alhambra):
RowStack_Class = StackWrapper(Reserves_RowStack, base_rank=NO_RANK)
def createGame(self): def createGame(self):
Alhambra.createGame(self, reserves=4, playcards=11) Alhambra.createGame(self, reserves=4, playcards=11)
@ -347,6 +382,12 @@ class GrantsReinforcement(Alhambra):
self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow(rows=self.s.reserves)
self.s.talon.dealCards() self.s.talon.dealCards()
shallHighlightMatch = Game._shallHighlightMatch_RKW
class GrantsReinforcement(Reserves):
RowStack_Class = StackWrapper(Alhambra_RowStack, base_rank=NO_RANK)
def fillStack(self, stack): def fillStack(self, stack):
for r in self.s.reserves: for r in self.s.reserves:
if r.cards: if r.cards:
@ -357,6 +398,8 @@ class GrantsReinforcement(Alhambra):
self.s.talon.moveMove(1, r) self.s.talon.moveMove(1, r)
self.leaveState(old_state) self.leaveState(old_state)
shallHighlightMatch = Game._shallHighlightMatch_SSW
# /*********************************************************************** # /***********************************************************************
# // Carpet # // Carpet
@ -512,6 +555,8 @@ class BritishConstitution(Game):
class NewBritishConstitution(BritishConstitution): class NewBritishConstitution(BritishConstitution):
RowStack_Class = StackWrapper(NewBritishConstitution_RowStack, base_rank=JACK) RowStack_Class = StackWrapper(NewBritishConstitution_RowStack, base_rank=JACK)
shallHighlightMatch = Game._shallHighlightMatch_RK
# /*********************************************************************** # /***********************************************************************
# // Twenty # // Twenty
@ -970,10 +1015,11 @@ class FourWinds(Game):
# talon & waste # talon & waste
x, y = l.XM+3.5*l.XS, l.YM+2.5*l.YS x, y = l.XM+3.5*l.XS, l.YM+2.5*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, 'n') l.createText(s.talon, 's')
l.createRoundText(self.s.talon, 'nn')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'n') l.createText(s.waste, 's')
l.defaultStackGroups() l.defaultStackGroups()
@ -1244,9 +1290,10 @@ class TwilightZone(Game):
x += l.XS x += l.XS
x, y = l.XM, l.YM x, y = l.XM, l.YM+l.YS/2
s.talon = TwilightZone_Talon(x, y, self, max_move=1, max_rounds=2) s.talon = TwilightZone_Talon(x, y, self, max_move=1, max_rounds=2)
l.createText(s.talon, 's') l.createText(s.talon, 's')
l.createRoundText(s.talon, 'nn')
x += l.XS x += l.XS
s.waste = TwilightZone_Waste(x, y, self, max_accept=1) s.waste = TwilightZone_Waste(x, y, self, max_accept=1)
l.createText(s.waste, 's') l.createText(s.waste, 's')
@ -1315,7 +1362,7 @@ registerGame(GameInfo(579, ThreePirates, "Three Pirates",
registerGame(GameInfo(608, Frames, "Frames", registerGame(GameInfo(608, Frames, "Frames",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(609, GrantsReinforcement, "Grant's Reinforcement", registerGame(GameInfo(609, GrantsReinforcement, "Grant's Reinforcement",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
registerGame(GameInfo(638, RoyalRendezvous, "Royal Rendezvous", registerGame(GameInfo(638, RoyalRendezvous, "Royal Rendezvous",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(639, ShadyLanes, "Shady Lanes", registerGame(GameInfo(639, ShadyLanes, "Shady Lanes",
@ -1330,4 +1377,6 @@ registerGame(GameInfo(695, TheRedAndTheBlack, "The Red and the Black",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(748, TwilightZone, "Twilight Zone", registerGame(GameInfo(748, TwilightZone, "Twilight Zone",
GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED))
registerGame(GameInfo(752, Reserves, "Reserves",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))

View file

@ -72,21 +72,23 @@ class Simplex(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
w, h = l.XM+10*l.XS, l.YM+2*l.YS+9*l.YOFFSET w, h = l.XM+10*l.XS, l.YM+2*l.YS+4*l.YOFFSET+l.TEXT_HEIGHT
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=1) s.talon = WasteTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, 's')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 's')
x += l.XS x += l.XS
stack = Simplex_Foundation(x, y, self, stack = Simplex_Foundation(x, y, self,
suit=ANY_SUIT, base_rank=ANY_RANK, max_cards=52) suit=ANY_SUIT, base_rank=ANY_RANK, max_cards=52)
xoffset = (self.width-3*l.XS)/51 xoffset = (self.width-3*l.XS)/51
stack.CARD_XOFFSET, stack.CARD_YOFFSET = xoffset, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = xoffset, 0
s.foundations.append(stack) s.foundations.append(stack)
x, y = l.XM, l.YM+l.YS x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT
for i in range(9): for i in range(9):
s.rows.append(Simplex_RowStack(x, y, self)) s.rows.append(Simplex_RowStack(x, y, self))
x += l.XS x += l.XS

View file

@ -249,10 +249,7 @@ class LesQuatreCoins(Game):
x, y = l.XM, l.YM+2*l.YS x, y = l.XM, l.YM+2*l.YS
s.talon = LesQuatreCoins_Talon(x, y, self, max_rounds=3) s.talon = LesQuatreCoins_Talon(x, y, self, max_rounds=3)
l.createText(s.talon, 's') l.createText(s.talon, 's')
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -49,7 +49,7 @@ class Sultan(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
w, h = 3*l.XM+5*l.XS, l.YM+4*l.YS+l.TEXT_HEIGHT w, h = 3*l.XM+5*l.XS, l.YM+4*l.YS+l.TEXT_HEIGHT+l.TEXT_MARGIN
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
@ -82,6 +82,7 @@ class Sultan(Game):
x, y = 2*l.XM+1.5*l.XS, l.YM+3*l.YS x, y = 2*l.XM+1.5*l.XS, l.YM+3*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "s") l.createText(s.talon, "s")
l.createRoundText(self.s.talon, 'sss')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
@ -128,11 +129,8 @@ class Boudoir(Game):
x, y = l.XM, l.YM+l.YS x, y = l.XM, l.YM+l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
font=self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.createText(s.talon, 'ne') l.createText(s.talon, 'ne')
l.createRoundText(s.talon, 'nn')
y += l.YS y += l.YS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'ne') l.createText(s.waste, 'ne')
@ -194,10 +192,7 @@ class CaptiveQueens(Game):
x, y = l.XM, l.YM+l.YS/2 x, y = l.XM, l.YM+l.YS/2
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "se") l.createText(s.talon, "se")
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
y += l.YS y += l.YS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "se") l.createText(s.waste, "se")
@ -210,7 +205,7 @@ class CaptiveQueens(Game):
x, y = l.XM+1.5*l.XS, l.YM+l.YS x, y = l.XM+1.5*l.XS, l.YM+l.YS
for i in range(4): for i in range(4):
s.rows.append(AbstractFoundationStack(x, y, self, suit=i, s.foundations.append(AbstractFoundationStack(x, y, self, suit=i,
max_cards=1, max_move=0, base_rank=QUEEN)) max_cards=1, max_move=0, base_rank=QUEEN))
x += l.XS x += l.XS
@ -255,6 +250,7 @@ class Contradance(Game):
x, y = l.XM+3*l.XS, l.YM+3*l.YS x, y = l.XM+3*l.XS, l.YM+3*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
l.createRoundText(self.s.talon, 'nnn')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'n') l.createText(s.waste, 'n')
@ -294,6 +290,7 @@ class IdleAces(Game):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 's') l.createText(s.talon, 's')
l.createRoundText(s.talon, 'ne', dx=l.XS)
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 's') l.createText(s.waste, 's')
@ -452,10 +449,7 @@ class Matrimony(Game):
s.talon = Matrimony_Talon(l.XM, l.YM, self, max_rounds=17) s.talon = Matrimony_Talon(l.XM, l.YM, self, max_rounds=17)
l.createText(s.talon, 'se') l.createText(s.talon, 'se')
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = l.XM+2*l.XS, l.YM x, y = l.XM+2*l.XS, l.YM
for i in range(4): for i in range(4):
@ -503,7 +497,10 @@ class PicturePatience(Game):
def createGame(self, max_rounds=1): def createGame(self, max_rounds=1):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(3*l.XM+5*l.XS, l.YM+4*l.YS) w, h = 3*l.XM+5*l.XS, l.YM+4*l.YS
if max_rounds > 1:
h += l.TEXT_HEIGHT+l.TEXT_MARGIN
self.setSize(w, h)
x, y = l.XM, l.YM x, y = l.XM, l.YM
for i in range(4): for i in range(4):
@ -524,9 +521,14 @@ class PicturePatience(Game):
y += l.YS y += l.YS
x, y = 2*l.XM+l.XS+l.XS/2, l.YM+3*l.YS x, y = 2*l.XM+l.XS+l.XS/2, l.YM+3*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds) s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
l.createText(s.talon, 'sw')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
if max_rounds > 1:
l.createText(s.talon, 's')
l.createRoundText(s.talon, 'sss')
l.createText(s.waste, 's')
else:
l.createText(s.talon, 'sw')
l.createText(s.waste, 'se') l.createText(s.waste, 'se')
l.defaultStackGroups() l.defaultStackGroups()
@ -660,7 +662,8 @@ class TwoRings(Game):
x += l.XS x += l.XS
s.talon = DealRowRedealTalonStack(x, y, self, max_rounds=2) s.talon = DealRowRedealTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, 'sw') l.createText(s.talon, 'nw')
l.createRoundText(s.talon, 'sw')
l.defaultStackGroups() l.defaultStackGroups()
@ -859,25 +862,26 @@ class CircleEight(Game):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM+5*l.XS, l.YM+3*l.YS) self.setSize(l.XM+5*l.XS, l.YM+4*l.YS)
for i, j in ((1,0), for i, j in ((1,0),
(2,0), (2,0),
(3,0), (3,0),
(4,1), (4,1.5),
(3,2), (3,3),
(2,2), (2,3),
(1,2), (1,3),
(0,1), (0,1.5),
): ):
x, y = l.XM+i*l.XS, l.YM+j*l.YS x, y = l.XM+i*l.XS, l.YM+j*l.YS
stack = RK_RowStack(x, y, self, dir=1, mod=13, max_move=0) stack = RK_RowStack(x, y, self, dir=1, mod=13, max_move=0)
s.rows.append(stack) s.rows.append(stack)
stack.CARD_YOFFSET = 0 stack.CARD_YOFFSET = 0
x, y = l.XM+1.5*l.XS, l.YM+l.YS x, y = l.XM+1.5*l.XS, l.YM+1.5*l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, 'nw') l.createText(s.talon, 'nw')
l.createRoundText(self.s.talon, 'nn')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'ne') l.createText(s.waste, 'ne')
@ -994,10 +998,7 @@ class Toni(Game):
x, y = l.XM, l.YM x, y = l.XM, l.YM
s.talon = DealRowRedealTalonStack(x, y, self, max_rounds=3) s.talon = DealRowRedealTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'se') l.createText(s.talon, 'se')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'ne') l.createRoundText(s.talon, 'ne')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -101,10 +101,7 @@ class Tournament(Game):
s.talon = Tournament_Talon(l.XM, l.YM, self, max_rounds=3) s.talon = Tournament_Talon(l.XM, l.YM, self, max_rounds=3)
l.createText(s.talon, "se") l.createText(s.talon, "se")
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne") l.createRoundText(s.talon, 'ne')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()

View file

@ -273,6 +273,8 @@ class Corners(Game):
x, y = l.XM+1.5*l.XS, l.YM x, y = l.XM+1.5*l.XS, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds) s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
l.createText(s.talon, "sw") l.createText(s.talon, "sw")
if max_rounds > 1:
l.createRoundText(self.s.talon, 'nw')
x += l.XS x += l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "se") l.createText(s.waste, "se")

View file

@ -147,6 +147,10 @@ class Grandfather_Talon(RedealTalonStack):
class Grandfather(RussianSolitaire): class Grandfather(RussianSolitaire):
Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3) Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3)
def createGame(self):
l = Yukon.createGame(self)
l.createRoundText(self.s.talon, 'nn')
def startGame(self): def startGame(self):
for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)): for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)):
self.s.talon.dealRowAvail(rows=self.s.rows[i:j], flip=0, frames=0) self.s.talon.dealRowAvail(rows=self.s.rows[i:j], flip=0, frames=0)

View file

@ -176,10 +176,7 @@ class TwelveSleepingMaids(Game):
x, y = self.width-l.XS, self.height-l.YS x, y = self.width-l.XS, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn") l.createRoundText(s.talon, 'nnn')
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
x -= l.XS x -= l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)

View file

@ -156,7 +156,7 @@ class AbstractHint(HintInterface):
self.hints.append(ah) self.hints.append(ah)
# clean up and return hints sorted by score # clean up and return hints sorted by score
def __returnHints(self): def _returnHints(self):
hints = self.hints hints = self.hints
self.reset() self.reset()
hints.sort() hints.sort()
@ -189,14 +189,14 @@ class AbstractHint(HintInterface):
if r.canFlipCard(): if r.canFlipCard():
self.addHint(self.SCORE_FLIP, 1, r, r) self.addHint(self.SCORE_FLIP, 1, r, r)
if self.SCORE_FLIP >= 90000: if self.SCORE_FLIP >= 90000:
return self.__returnHints() return self._returnHints()
# 3) ask subclass to do something useful # 3) ask subclass to do something useful
self.computeHints() self.computeHints()
# 4) try if we can deal cards # 4) try if we can deal cards
if self.level >= 2: if self.level >= 2:
if game.canDealCards(): if game.canDealCards():
self.addHint(self.SCORE_DEAL, 0, game.s.talon, None) self.addHint(self.SCORE_DEAL, 0, game.s.talon, None)
return self.__returnHints() return self._returnHints()
# subclass # subclass
def computeHints(self): def computeHints(self):

View file

@ -235,6 +235,24 @@ class Layout:
anchor=ta, font=font) anchor=ta, font=font)
stack.texts.ncards.text_format = text_format or tf stack.texts.ncards.text_format = text_format or tf
def createRoundText(self, stack, anchor, dx=0, dy=0):
if self.canvas.preview > 1:
return
assert stack.texts.rounds is None
delta_x, delta_y = 0, 0
if anchor == 'nnn':
anchor = 'nn'
delta_y = -self.TEXT_MARGIN
elif anchor == 'sss':
anchor = 'ss'
delta_y = self.TEXT_MARGIN
tx, ty, ta, tf = self.getTextAttr(stack, anchor)
tx += delta_x + dx
ty += delta_y + dy
font = self.game.app.getFont("canvas_default")
stack.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
def setRegion(self, stacks, rects): def setRegion(self, stacks, rects):
self.regions.append((stacks, rects)) self.regions.append((stacks, rects))
@ -416,7 +434,8 @@ class Layout:
# #
def gypsyLayout(self, rows, waste=0, reserves=0, def gypsyLayout(self, rows, waste=0, reserves=0,
texts=1, reserve_texts=False, playcards=25): texts=1, reserve_texts=False, round_text=False,
playcards=25):
S = self.__createStack S = self.__createStack
CW, CH = self.CW, self.CH CW, CH = self.CW, self.CH
XM, YM = self.XM, self.YM XM, YM = self.XM, self.YM
@ -458,15 +477,18 @@ class Layout:
if texts: if texts:
x -= XS/2 x -= XS/2
self.s.talon = s = S(x, y) self.s.talon = s = S(x, y)
anchor = 's'
if round_text:
anchor = 'n'
if texts: if texts:
# place text right of stack # place text right of stack
self._setText(s, anchor="se") self._setText(s, anchor=anchor+"e")
if waste: if waste:
x -= XS x -= XS
self.s.waste = s = S(x, y) self.s.waste = s = S(x, y)
if texts: if texts:
# place text left of stack # place text left of stack
self._setText(s, anchor="sw") self._setText(s, anchor=anchor+"w")
# create reserves # create reserves
x, y = XM, h-YS x, y = XM, h-YS
for i in range(reserves): for i in range(reserves):
@ -564,7 +586,7 @@ class Layout:
# #
def klondikeLayout(self, rows, waste, reserves=0, def klondikeLayout(self, rows, waste, reserves=0,
texts=1, reserve_texts=False, texts=1, reserve_texts=False, round_text=False,
playcards=16, center=1, text_height=0): playcards=16, center=1, text_height=0):
S = self.__createStack S = self.__createStack
CW, CH = self.CW, self.CH CW, CH = self.CW, self.CH
@ -576,8 +598,11 @@ class Layout:
foundrows = 1 + (suits > 5) foundrows = 1 + (suits > 5)
frows = decks * suits / foundrows frows = decks * suits / foundrows
toprows = 1 + waste + frows toprows = 1 + waste + frows
if round_text:
toprows += 1
maxrows = max(rows, toprows, reserves) maxrows = max(rows, toprows, reserves)
w = XM + maxrows * XS
# set size so that at least 2/3 of a card is visible with 16 cards # set size so that at least 2/3 of a card is visible with 16 cards
h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET
h = max(h, 2 * YS) h = max(h, 2 * YS)
@ -606,7 +631,7 @@ class Layout:
text_height = self.TEXT_HEIGHT text_height = self.TEXT_HEIGHT
for row in range(foundrows): for row in range(foundrows):
x = XM + (maxrows - frows) * XS x = w - frows * XS
if center and frows + 2 * (1 + waste + 1) <= maxrows: if center and frows + 2 * (1 + waste + 1) <= maxrows:
# center the foundations # center the foundations
x = XM + (maxrows - frows) * XS / 2 x = XM + (maxrows - frows) * XS / 2
@ -618,7 +643,8 @@ class Layout:
# below # below
x = XM x = XM
if rows < maxrows: x += (maxrows-rows) * XS/2 if rows < maxrows:
x += (maxrows-rows) * XS/2
##y += YM * (3 - foundrows) ##y += YM * (3 - foundrows)
y += text_height y += text_height
for i in range(rows): for i in range(rows):
@ -643,7 +669,7 @@ class Layout:
self._setText(s, anchor="n") self._setText(s, anchor="n")
# set window # set window
self.size = (XM + maxrows * XS, h) self.size = (w, h)
# #

View file

@ -36,6 +36,7 @@
# imports # imports
import Tkinter import Tkinter
import Tile
import tkColorChooser import tkColorChooser
# PySol imports # PySol imports
@ -129,13 +130,17 @@ class SelectTileDialogWithPreview(MfxDialog):
else: else:
w1, w2 = 200, 300 w1, w2 = 200, 300
font = app.getFont("default") font = app.getFont("default")
self.tree = self.Tree_Class(self, top_frame, key=key, padx, pady = 4, 4
default=kw.default, frame = Tile.Frame(top_frame)
frame.pack(fill='both', expand=True,
padx=kw.padx-padx, pady=kw.pady-pady)
self.tree = self.Tree_Class(self, frame, key=key, default=kw.default,
font=font, width=w1) font=font, width=w1)
self.tree.frame.pack(side="left", fill='both', expand=False, padx=kw.padx, pady=kw.pady) self.tree.frame.pack(side="left", fill='both', expand=False,
self.preview = MfxScrolledCanvas(top_frame, width=w2, hbar=0, vbar=0) padx=padx, pady=pady)
self.preview = MfxScrolledCanvas(frame, width=w2, hbar=0, vbar=0)
self.preview.pack(side="right", fill='both', expand=True, self.preview.pack(side="right", fill='both', expand=True,
padx=kw.padx, pady=kw.pady) padx=padx, pady=pady)
self.preview.canvas.preview = 1 self.preview.canvas.preview = 1
# create a preview of the current state # create a preview of the current state
self.preview_key = -1 self.preview_key = -1
@ -158,6 +163,7 @@ class SelectTileDialogWithPreview(MfxDialog):
default=0, default=0,
resizable=True, resizable=True,
font=None, font=None,
padx=10, pady=10,
) )
return MfxDialog.initKw(self, kw) return MfxDialog.initKw(self, kw)

View file

@ -153,8 +153,7 @@ class MfxCanvas(Tkinter.Canvas):
stretch = self._stretch_bg_image stretch = self._stretch_bg_image
if Image: if Image:
if stretch: if stretch:
w = max(self.winfo_width(), int(self.cget('width'))) w, h = self._geometry()
h = max(self.winfo_height(), int(self.cget('height')))
im = self._bg_img.resize((w, h)) im = self._bg_img.resize((w, h))
image = ImageTk.PhotoImage(im) image = ImageTk.PhotoImage(im)
else: else:
@ -179,10 +178,7 @@ class MfxCanvas(Tkinter.Canvas):
self.__tiles.append(id) self.__tiles.append(id)
else: else:
iw, ih = image.width(), image.height() iw, ih = image.width(), image.height()
#sw = max(self.winfo_screenwidth(), 1024) sw, sh = self._geometry()
#sh = max(self.winfo_screenheight(), 768)
sw = max(self.winfo_width(), int(self.cget('width')))
sh = max(self.winfo_height(), int(self.cget('height')))
for x in range(-self.xmargin, sw, iw): for x in range(-self.xmargin, sw, iw):
for y in range(-self.ymargin, sh, ih): for y in range(-self.ymargin, sh, ih):
id = self._x_create("image", x, y, image=image, anchor="nw") id = self._x_create("image", x, y, image=image, anchor="nw")
@ -190,6 +186,19 @@ class MfxCanvas(Tkinter.Canvas):
self.__tiles.append(id) self.__tiles.append(id)
return 1 return 1
def _geometry(self):
w = max(self.winfo_width(), int(self.cget('width')))
h = max(self.winfo_height(), int(self.cget('height')))
scrollregion = self.cget('scrollregion')
if not scrollregion:
return w, h
x, y, sw, sh = [int(i) for i in scrollregion.split()]
sw -= x
sh -= y
w = max(w, sw)
h = max(h, sh)
return w, h
# #
# top-image support # top-image support

View file

@ -197,7 +197,7 @@ __mfx_bindings = {}
__mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF") __mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF")
def bind(widget, sequence, func, add=None): def bind(widget, sequence, func, add=None):
assert callable(func) ##assert callable(func) # XXX: removed in py3k
if sequence in __mfx_wm_protocols: if sequence in __mfx_wm_protocols:
funcid = widget._register(func) funcid = widget._register(func)
widget.tk.call("wm", "protocol", widget._w, sequence, funcid) widget.tk.call("wm", "protocol", widget._w, sequence, funcid)

View file

@ -128,14 +128,18 @@ class SelectTileDialogWithPreview(MfxDialog):
else: else:
w1, w2 = 200, 300 w1, w2 = 200, 300
font = app.getFont("default") font = app.getFont("default")
self.tree = self.Tree_Class(self, top_frame, key=key, padx, pady = 4, 4
frame = Tkinter.Frame(top_frame)
frame.pack(fill='both', expand=True,
padx=kw.padx-padx, pady=kw.pady-pady)
self.tree = self.Tree_Class(self, frame, key=key,
default=kw.default, default=kw.default,
font=font, width=w1) font=font, width=w1)
self.tree.frame.pack(side="left", fill='both', expand=False, self.tree.frame.pack(side="left", fill='both', expand=False,
padx=kw.padx, pady=kw.pady) padx=padx, pady=pady)
self.preview = MfxScrolledCanvas(top_frame, width=w2, hbar=0, vbar=0) self.preview = MfxScrolledCanvas(frame, width=w2, hbar=0, vbar=0)
self.preview.pack(side="right", fill='both', expand=True, self.preview.pack(side="right", fill='both', expand=True,
padx=kw.padx, pady=kw.pady) padx=padx, pady=pady)
self.preview.canvas.preview = 1 self.preview.canvas.preview = 1
# create a preview of the current state # create a preview of the current state
self.preview_key = -1 self.preview_key = -1

View file

@ -152,8 +152,7 @@ class MfxCanvas(Tkinter.Canvas):
stretch = self._stretch_bg_image stretch = self._stretch_bg_image
if Image: if Image:
if stretch: if stretch:
w = max(self.winfo_width(), int(self.cget('width'))) w, h = self._geometry()
h = max(self.winfo_height(), int(self.cget('height')))
im = self._bg_img.resize((w, h)) im = self._bg_img.resize((w, h))
image = ImageTk.PhotoImage(im) image = ImageTk.PhotoImage(im)
else: else:
@ -178,10 +177,7 @@ class MfxCanvas(Tkinter.Canvas):
self.__tiles.append(id) self.__tiles.append(id)
else: else:
iw, ih = image.width(), image.height() iw, ih = image.width(), image.height()
#sw = max(self.winfo_screenwidth(), 1024) sw, sh = self._geometry()
#sh = max(self.winfo_screenheight(), 768)
sw = max(self.winfo_width(), int(self.cget('width')))
sh = max(self.winfo_height(), int(self.cget('height')))
for x in range(-self.xmargin, sw, iw): for x in range(-self.xmargin, sw, iw):
for y in range(-self.ymargin, sh, ih): for y in range(-self.ymargin, sh, ih):
id = self._x_create("image", x, y, image=image, anchor="nw") id = self._x_create("image", x, y, image=image, anchor="nw")
@ -189,6 +185,19 @@ class MfxCanvas(Tkinter.Canvas):
self.__tiles.append(id) self.__tiles.append(id)
return 1 return 1
def _geometry(self):
w = max(self.winfo_width(), int(self.cget('width')))
h = max(self.winfo_height(), int(self.cget('height')))
scrollregion = self.cget('scrollregion')
if not scrollregion:
return w, h
x, y, sw, sh = [int(i) for i in scrollregion.split()]
sw -= x
sh -= y
w = max(w, sw)
h = max(h, sh)
return w, h
# #
# top-image support # top-image support

View file

@ -197,7 +197,7 @@ __mfx_bindings = {}
__mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF") __mfx_wm_protocols = ("WM_DELETE_WINDOW", "WM_TAKE_FOCUS", "WM_SAVE_YOURSELF")
def bind(widget, sequence, func, add=None): def bind(widget, sequence, func, add=None):
assert callable(func) ##assert callable(func) # XXX: removed in py3k
if sequence in __mfx_wm_protocols: if sequence in __mfx_wm_protocols:
funcid = widget._register(func) funcid = widget._register(func)
widget.tk.call("wm", "protocol", widget._w, sequence, funcid) widget.tk.call("wm", "protocol", widget._w, sequence, funcid)