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

+ 6 new games

+ new tk util `_getHelpText'


git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@27 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2006-07-25 21:13:43 +00:00
parent d91ba30ac8
commit 082c64597a
10 changed files with 366 additions and 68 deletions

View file

@ -197,6 +197,9 @@ class Game:
# update display properties # update display properties
self.top.wm_geometry("") # cancel user-specified geometry self.top.wm_geometry("") # cancel user-specified geometry
self.canvas.setInitialSize(self.width, self.height) self.canvas.setInitialSize(self.width, self.height)
if self.app.debug >= 2:
MfxCanvasRectangle(self.canvas, 0, 0, self.width, self.height,
width=2, fill=None, outline='green')
# restore game geometry # restore game geometry
if self.app.opt.save_games_geometry: if self.app.opt.save_games_geometry:
w, h = self.app.opt.games_geometry.get(self.id, (0, 0)) w, h = self.app.opt.games_geometry.get(self.id, (0, 0))
@ -1025,8 +1028,9 @@ class Game:
def setRegion(self, stacks, rect, priority=0): def setRegion(self, stacks, rect, priority=0):
assert len(stacks) > 0 assert len(stacks) > 0
assert len(rect) == 4 and rect[0] < rect[2] and rect[1] < rect[3] assert len(rect) == 4 and rect[0] < rect[2] and rect[1] < rect[3]
##MfxCanvasRectangle(self.canvas, rect[0], rect[1], rect[2], rect[3], if self.app.debug >= 2:
## width=2, fill=None, outline='red') MfxCanvasRectangle(self.canvas, rect[0], rect[1], rect[2], rect[3],
width=2, fill=None, outline='red')
for s in stacks: for s in stacks:
assert s and s in self.allstacks assert s and s in self.allstacks
# verify that the stack lies within the rectangle # verify that the stack lies within the rectangle

View file

@ -244,17 +244,17 @@ class GI:
## 41, 42, 43, 58, 59, 92, 93, 94, 95, 96, ## 41, 42, 43, 58, 59, 92, 93, 94, 95, 96,
## 100, 105, 111, 112, 113, 130, 200, 201, ## 100, 105, 111, 112, 113, 130, 200, 201,
##)), ##)),
# Gnome AisleRiot 2.2.0 (we have 57 out of 73 games) # Gnome AisleRiot 2.2.0 (we have 60 out of 70 games)
# still missing: # still missing:
# Clock, Cover, Diamond mine, Gay gordons, Helsinki # Clock, Gay gordons, Helsinki,
# Isabel, Labyrinth (!), Quatorze, Scuffle, Thieves, # Isabel, Labyrinth, Quatorze, Thieves,
# Treize, Valentine, Yeld, ??? # Treize, Valentine, Yeld.
("Gnome AisleRiot", ( ("Gnome AisleRiot", (
1, 2, 8, 9, 11, 12, 19, 24, 27, 29, 31, 33, 34, 35, 36, 40, 1, 2, 8, 9, 11, 12, 19, 24, 27, 29, 31, 33, 34, 35, 36, 40,
41, 42, 43, 45, 48, 58, 59, 67, 89, 91, 92, 93, 94, 95, 96, 41, 42, 43, 45, 48, 58, 59, 67, 89, 91, 92, 93, 94, 95, 96,
100, 105, 111, 112, 113, 130, 139, 144, 146, 147, 148, 200, 100, 105, 111, 112, 113, 130, 139, 144, 146, 147, 148, 200,
201, 206, 224, 225, 229, 230, 233, 257, 258, 280, 281, 282, 201, 206, 224, 225, 229, 230, 233, 257, 258, 280, 281, 282,
283, 284, 283, 284, 551, 552, 553,
)), )),
## KDE Patience 0.7.3 from KDE 1.1.2 (we have 6 out of 9 games) ## KDE Patience 0.7.3 from KDE 1.1.2 (we have 6 out of 9 games)

View file

@ -42,6 +42,9 @@ 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 montecarlo import MonteCarlo_RowStack
# /*********************************************************************** # /***********************************************************************
# // Aces Up # // Aces Up
# ************************************************************************/ # ************************************************************************/
@ -69,6 +72,7 @@ class AcesUp_RowStack(BasicRowStack):
class AcesUp(Game): class AcesUp(Game):
Foundation_Class = AcesUp_Foundation
Talon_Class = DealRowTalonStack Talon_Class = DealRowTalonStack
RowStack_Class = StackWrapper(AcesUp_RowStack, max_accept=1) RowStack_Class = StackWrapper(AcesUp_RowStack, max_accept=1)
@ -92,8 +96,8 @@ class AcesUp(Game):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS x = x + l.XS
x = x + l.XS/2 x = x + l.XS/2
stack = AcesUp_Foundation(x, y, self, ANY_SUIT, max_move=0, stack = self.Foundation_Class(x, y, self, suit=ANY_SUIT, max_move=0,
dir=0, base_rank=ANY_RANK, max_cards=48) dir=0, base_rank=ANY_RANK, max_cards=48)
l.createText(stack, "ss") l.createText(stack, "ss")
s.foundations.append(stack) s.foundations.append(stack)
@ -250,6 +254,39 @@ class AcesUp5(AcesUp):
return len(self.s.foundations[0].cards) == 48 return len(self.s.foundations[0].cards) == 48
# /***********************************************************************
# // Cover
# ************************************************************************/
class Cover_RowStack(MonteCarlo_RowStack):
def acceptsCards(self, from_stack, cards):
if not OpenStack.acceptsCards(self, from_stack, cards):
return False
return self.cards[-1].suit == cards[0].suit
class Cover(AcesUp):
Foundation_Class = StackWrapper(AbstractFoundationStack, max_accept=0)
Talon_Class = TalonStack
RowStack_Class = StackWrapper(Cover_RowStack, max_accept=1)
FILL_STACKS_AFTER_DROP = 0 # for MonteCarlo_RowStack
def fillStack(self, stack):
if not self.s.talon.cards:
return
self.startDealSample()
for r in self.s.rows:
if not r.cards:
self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, r)
self.stopSamples()
def isGameWon(self):
return len(self.s.foundations[0].cards) == 48
# register the game # register the game
registerGame(GameInfo(903, AcesUp, "Aces Up", # was: 52 registerGame(GameInfo(903, AcesUp, "Aces Up", # was: 52
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK, GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK,
@ -263,3 +300,5 @@ registerGame(GameInfo(130, PerpetualMotion, "Perpetual Motion",
altnames="First Law")) altnames="First Law"))
registerGame(GameInfo(353, AcesUp5, "Aces Up 5", registerGame(GameInfo(353, AcesUp5, "Aces Up 5",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))
registerGame(GameInfo(552, Cover, "Cover",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))

View file

@ -109,6 +109,8 @@ class StreetsAndAlleys(Game):
s.talon = InitialDealTalonStack(x, y, self) s.talon = InitialDealTalonStack(x, y, self)
if reserves: if reserves:
l.setRegion(s.rows[:4], (-999, l.YM+l.YS-l.CH/2, x1-l.CW/2, 999999)) l.setRegion(s.rows[:4], (-999, l.YM+l.YS-l.CH/2, x1-l.CW/2, 999999))
else:
l.setRegion(s.rows[:4], (-999, -999, x1-l.CW/2, 999999))
# default # default
l.defaultAll() l.defaultAll()

View file

@ -41,7 +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 pysollib.pysoltk import MfxCanvasText, getTextWidth
# /*********************************************************************** # /***********************************************************************
# // # //
@ -68,13 +68,16 @@ class Calculation_Hint(DefaultHint):
# ************************************************************************/ # ************************************************************************/
class BetsyRoss_Foundation(RK_FoundationStack): class BetsyRoss_Foundation(RK_FoundationStack):
def updateText(self): def updateText(self, update_empty=True):
if self.game.preview > 1: if self.game.preview > 1:
return return
if self.texts.misc: if self.texts.misc:
if len(self.cards) == 0: if len(self.cards) == 0:
rank = self.cap.base_rank if update_empty:
self.texts.misc.config(text=RANKS[rank]) rank = self.cap.base_rank
self.texts.misc.config(text=RANKS[rank])
else:
self.texts.misc.config(text="")
elif len(self.cards) == self.cap.max_cards: elif len(self.cards) == self.cap.max_cards:
self.texts.misc.config(text="") self.texts.misc.config(text="")
else: else:
@ -107,42 +110,57 @@ class Calculation_RowStack(BasicRowStack):
class Calculation(Game): class Calculation(Game):
Hint_Class = Calculation_Hint Hint_Class = Calculation_Hint
Foundation_Class = Calculation_Foundation
RowStack_Class = StackWrapper(Calculation_RowStack, max_move=1, max_accept=1)
# #
# game layout # game layout
# #
def createGame(self): def _getHelpText(self):
# create layout
l, s = Layout(self, TEXT_HEIGHT=40), self.s
# set window
# (piles up to 20 cards are playable in default window size)
h = max(2*l.YS, 20*l.YOFFSET)
self.setSize(5.5*l.XS+l.XM+200, l.YM + l.YS + l.TEXT_HEIGHT + h)
# create stacks
x0 = l.XM + l.XS * 3 / 2
x, y = x0, l.YM
for i in range(4):
stack = Calculation_Foundation(x, y, self, base_rank=i, mod=13, dir=i+1)
s.foundations.append(stack)
stack.texts.misc = MfxCanvasText(self.canvas,
x + l.CW / 2, y + l.YS,
anchor="n",
font=self.app.getFont("canvas_default"))
x = x + l.XS
help = (_('''\ help = (_('''\
1: 2 3 4 5 6 7 8 9 T J Q K 1: 2 3 4 5 6 7 8 9 T J Q K
2: 4 6 8 T Q A 3 5 7 9 J K 2: 4 6 8 T Q A 3 5 7 9 J K
3: 6 9 Q 2 5 8 J A 4 7 T K 3: 6 9 Q 2 5 8 J A 4 7 T K
4: 8 Q 3 7 J 2 6 T A 5 9 K''')) 4: 8 Q 3 7 J 2 6 T A 5 9 K'''))
# calculate text_width
lines = help.split('\n')
lines.sort(lambda a, b: cmp(len(a), len(b)))
max_line = lines[-1]
text_width = getTextWidth(max_line,
font=self.app.getFont("canvas_fixed"))
return help, text_width
def createGame(self):
# create layout
l, s = Layout(self, TEXT_HEIGHT=40), self.s
help, text_width = self._getHelpText()
text_width += 2*l.XM
# set window
w = l.XM+5.5*l.XS+text_width
h = max(2*l.YS, 20*l.YOFFSET)
self.setSize(w, l.YM + l.YS + l.TEXT_HEIGHT + h)
# create stacks
x0 = l.XM + l.XS * 3 / 2
x, y = x0, l.YM
for i in range(4):
stack = self.Foundation_Class(x, y, self,
mod=13, dir=i+1, base_rank=i)
s.foundations.append(stack)
tx, ty, ta, tf = l.getTextAttr(stack, "s")
font = self.app.getFont("canvas_default")
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x = 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, text=help,
anchor="w", font=self.app.getFont("canvas_fixed")) anchor="w", font=self.app.getFont("canvas_fixed"))
x = x0 x = x0
y = l.YM + l.YS + l.TEXT_HEIGHT y = l.YM + l.YS + l.TEXT_HEIGHT
for i in range(4): for i in range(4):
s.rows.append(Calculation_RowStack(x, y, self, max_move=1, max_accept=1)) s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS x = x + l.XS
self.setRegion(s.rows, (-999, y, 999999, 999999)) self.setRegion(s.rows, (-999, y, 999999, 999999))
x = l.XM x = l.XM
@ -205,10 +223,12 @@ class BetsyRoss(Calculation):
def createGame(self): def createGame(self):
# create layout # create layout
l, s = Layout(self, TEXT_HEIGHT=40), self.s l, s = Layout(self), self.s
help, text_width = self._getHelpText()
text_width += 2*l.XM
# set window # set window
self.setSize(5.5*l.XS+l.XM+200, l.YM + l.YS + l.TEXT_HEIGHT + 3*l.YS) self.setSize(5.5*l.XS+l.XM+text_width, l.YM+3*l.YS+l.TEXT_HEIGHT)
# create stacks # create stacks
x0 = l.XM + l.XS * 3 / 2 x0 = l.XM + l.XS * 3 / 2
@ -219,19 +239,17 @@ class BetsyRoss(Calculation):
s.foundations.append(stack) s.foundations.append(stack)
x = x + l.XS x = x + l.XS
x = x0 x = x0
y = l.YM + l.YS + l.TEXT_HEIGHT y = l.YM + l.YS
for i in range(4): for i in range(4):
stack = BetsyRoss_Foundation(x, y, self, base_rank=2*i+1, mod=13, dir=i+1, stack = BetsyRoss_Foundation(x, y, self, base_rank=2*i+1,
max_cards=12, max_move=0) mod=13, dir=i+1,
stack.texts.misc = MfxCanvasText(self.canvas, x + l.CW / 2, y - l.YM, max_cards=12, max_move=0)
anchor="s", font=self.app.getFont("canvas_default")) tx, ty, ta, tf = l.getTextAttr(stack, "s")
font = self.app.getFont("canvas_default")
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
s.foundations.append(stack) s.foundations.append(stack)
x = x + l.XS x = x + l.XS
help = (_('''\
1: 2 3 4 5 6 7 8 9 T J Q K
2: 4 6 8 T Q A 3 5 7 9 J K
3: 6 9 Q 2 5 8 J A 4 7 T K
4: 8 Q 3 7 J 2 6 T A 5 9 K'''))
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, text=help,
anchor="w", font=self.app.getFont("canvas_fixed")) anchor="w", font=self.app.getFont("canvas_fixed"))
x = l.XM x = l.XM
@ -265,6 +283,76 @@ class BetsyRoss(Calculation):
return cards + topcards return cards + topcards
# /***********************************************************************
# // One234
# ************************************************************************/
class One234_Foundation(BetsyRoss_Foundation):
def canMoveCards(self, cards):
if not BetsyRoss_Foundation.canMoveCards(self, cards):
return False
return len(self.cards) > 1
def updateText(self):
BetsyRoss_Foundation.updateText(self, update_empty=False)
class One234_RowStack(BasicRowStack):
##clickHandler = BasicRowStack.doubleclickHandler
pass
class One234(Calculation):
Foundation_Class = One234_Foundation
RowStack_Class = StackWrapper(One234_RowStack, max_move=1, max_accept=0)
def createGame(self):
# create layout
l, s = Layout(self, TEXT_HEIGHT=40), self.s
help, text_width = self._getHelpText()
text_width += 2*l.XM
# set window
# (piles up to 20 cards are playable in default window size)
w = l.XM+max(4*l.XS+text_width, 8*l.XS)
h = l.YM+2*l.YS+5*l.YOFFSET+l.TEXT_HEIGHT+l.YS
self.setSize(w, h)
# create stacks
x, y = l.XM, l.YM
for i in range(4):
stack = self.Foundation_Class(x, y, self,
mod=13, dir=i+1, base_rank=i)
s.foundations.append(stack)
tx, ty, ta, tf = l.getTextAttr(stack, "s")
font = self.app.getFont("canvas_default")
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x = x + l.XS
self.texts.help = MfxCanvasText(self.canvas, x + l.XM, y + l.CH / 2, text=help,
anchor="w", font=self.app.getFont("canvas_fixed"))
x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT
for i in range(8):
s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS
s.talon = InitialDealTalonStack(l.XM, self.height-l.YS, self)
# define stack-groups
l.defaultStackGroups()
def _shuffleHook(self, cards):
return cards
def startGame(self):
for i in range(4):
self.s.talon.dealRow(frames=0)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.foundations)
# register the game # register the game
registerGame(GameInfo(256, Calculation, "Calculation", registerGame(GameInfo(256, Calculation, "Calculation",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL, GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL,
@ -275,4 +363,6 @@ registerGame(GameInfo(134, BetsyRoss, "Betsy Ross",
GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK, GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK,
altnames=("Fairest", "Four Kings", "Musical Patience", altnames=("Fairest", "Four Kings", "Musical Patience",
"Quadruple Alliance", "Plus Belle") )) "Quadruple Alliance", "Plus Belle") ))
registerGame(GameInfo(550, One234, "One234",
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))

View file

@ -125,12 +125,15 @@ class LadyPalk(Diplomat):
# /*********************************************************************** # /***********************************************************************
# // Congress # // Congress
# // Parliament
# ************************************************************************/ # ************************************************************************/
class Congress(Diplomat): class Congress(Diplomat):
DEAL = (0, 1) DEAL = (0, 1)
FILL_EMPTY_ROWS = 1 FILL_EMPTY_ROWS = 1
Foundation_Classes = [SS_FoundationStack, SS_FoundationStack]
# #
# game layout (just rearrange the stacks a little bit) # game layout (just rearrange the stacks a little bit)
# #
@ -143,10 +146,13 @@ class Congress(Diplomat):
self.setSize(l.XM + 7*l.XS, l.YM + 4*l.YS) self.setSize(l.XM + 7*l.XS, l.YM + 4*l.YS)
# create stacks # create stacks
for i in range(4): x = l.XM+4*l.XS
for j in range(2): for fnd_cls in self.Foundation_Classes:
x, y = l.XM + (4+j)*l.XS, l.YM + i*l.YS y = l.YM
s.foundations.append(self.Foundation_Class(x, y, self, suit=i)) for i in range(4):
s.foundations.append(fnd_cls(x, y, self, suit=i))
y += l.YS
x += l.XS
for i in range(4): for i in range(4):
for j in range(2): for j in range(2):
x, y = l.XM + (3+3*j)*l.XS, l.YM + i*l.YS x, y = l.XM + (3+3*j)*l.XS, l.YM + i*l.YS
@ -164,6 +170,26 @@ class Congress(Diplomat):
l.defaultStackGroups() l.defaultStackGroups()
class Parliament(Congress):
def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt)
return self._shuffleHookMoveToTop(cards,
lambda c: (c.rank == ACE, (c.deck, c.suit)))
def startGame(self):
self.s.talon.dealRow(rows=self.s.foundations, frames=0)
Congress.startGame(self)
class Wheatsheaf(Congress):
Foundation_Classes = [
SS_FoundationStack,
StackWrapper(SS_FoundationStack, base_rank=KING, dir=-1),
]
RowStack_Class = UD_SS_RowStack
# /*********************************************************************** # /***********************************************************************
# // Rows of Four # // Rows of Four
# ************************************************************************/ # ************************************************************************/
@ -238,4 +264,8 @@ registerGame(GameInfo(485, Dieppe, "Dieppe",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(489, LittleNapoleon, "Little Napoleon", registerGame(GameInfo(489, LittleNapoleon, "Little Napoleon",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED)) GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(548, Parliament, "Parliament",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(549, Wheatsheaf, "Wheatsheaf",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))

View file

@ -611,6 +611,65 @@ class Robert(Game):
self.s.talon.dealCards() self.s.talon.dealCards()
# /***********************************************************************
# // Diamond Mine
# ************************************************************************/
DIAMOND = 3
class DiamondMine_Foundation(AbstractFoundationStack):
pass
class DiamondMine_RowStack(RK_RowStack):
def acceptsCards(self, from_stack, cards):
if not RK_RowStack.acceptsCards(self, from_stack, cards):
return False
if cards[0].suit == DIAMOND:
return False
if self.cards:
return self.cards[-1].suit != DIAMOND
return True
class DiamondMine(Game):
def createGame(self):
l, s = Layout(self), self.s
self.setSize(l.XM+13*l.XS, l.YM+2*l.YS+15*l.YOFFSET)
x, y = l.XM+6*l.XS, l.YM
s.foundations.append(SS_FoundationStack(x, y, self,
base_rank=ANY_RANK, suit=DIAMOND, mod=13))
x, y = l.XM, l.YM+l.YS
for i in range(13):
s.rows.append(DiamondMine_RowStack(x, y, self))
x += l.XS
s.talon = InitialDealTalonStack(l.XM, self.height-l.YS, self)
l.defaultAll()
def startGame(self):
for i in range(3):
self.s.talon.dealRow(flip=0, frames=0)
self.startDealSample()
self.s.talon.dealRow()
def isGameWon(self):
if len(self.s.foundations[0].cards) != 13:
return False
for s in self.s.rows:
if len(s.cards) == 0:
continue
if len(s.cards) != 13:
return False
if not isSameSuitSequence(s.cards):
return False
return True
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) == 1
# register the game # register the game
registerGame(GameInfo(36, Golf, "Golf", registerGame(GameInfo(36, Golf, "Golf",
GI.GT_GOLF, 1, 0, GI.SL_BALANCED)) GI.GT_GOLF, 1, 0, GI.SL_BALANCED))
@ -633,3 +692,6 @@ registerGame(GameInfo(405, AllInARow, "All in a Row",
GI.GT_GOLF | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_GOLF | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(432, Robert, "Robert", registerGame(GameInfo(432, Robert, "Robert",
GI.GT_GOLF, 1, 2, GI.SL_LUCK)) GI.GT_GOLF, 1, 2, GI.SL_LUCK))
registerGame(GameInfo(551, DiamondMine, "Diamond Mine",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))

View file

@ -128,10 +128,10 @@ class Boudoir(Game):
x, y = l.XM, l.YM+l.YS-l.TEXT_HEIGHT/2 x, y = l.XM, l.YM+l.YS-l.TEXT_HEIGHT/2
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
x + l.CW / 2, y - l.YM, font=self.app.getFont("canvas_default")
anchor="s", s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
font=self.app.getFont("canvas_default")) anchor=ta, font=font)
l.createText(s.talon, "s") l.createText(s.talon, "s")
y += l.YS+l.TEXT_HEIGHT y += l.YS+l.TEXT_HEIGHT
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
@ -192,11 +192,11 @@ class CaptiveQueens(Game):
x, y = l.XM, l.YM+l.TEXT_HEIGHT x, y = l.XM, l.YM+l.TEXT_HEIGHT
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
s.talon.texts.rounds = MfxCanvasText(self.canvas,
x + l.CW / 2, y - l.YM,
anchor="s",
font=self.app.getFont("canvas_default"))
l.createText(s.talon, "s") l.createText(s.talon, "s")
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)
y += l.YS+l.TEXT_HEIGHT y += l.YS+l.TEXT_HEIGHT
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
@ -449,9 +449,9 @@ 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") tx, ty, ta, tf = l.getTextAttr(s.talon, "ne")
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, anchor=ta, font=font)
font=self.app.getFont("canvas_default"))
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):
@ -730,6 +730,65 @@ class CornerSuite(Game):
return abs(card1.rank-card2.rank) == 1 return abs(card1.rank-card2.rank) == 1
# /***********************************************************************
# // Scuffle
# ************************************************************************/
class Scuffle_Talon(RedealTalonStack):
def canDealCards(self):
if self.round == self.max_rounds:
return len(self.cards) != 0
return not self.game.isGameWon()
def dealCards(self, sound=0):
if self.cards:
return self.dealRowAvail(sound=sound)
RedealTalonStack.redealCards(self, shuffle=True, sound=sound)
return self.dealRowAvail(sound=sound)
class Scuffle_RowStack(BasicRowStack):
##clickHandler = BasicRowStack.doubleclickHandler
pass
class Scuffle(Game):
def createGame(self):
l, s = Layout(self), self.s
self.setSize(l.XM+6*l.XS, l.YM+2*l.YS)
s.talon = Scuffle_Talon(l.XM, l.YM+l.YS/2, self, max_rounds=3)
l.createText(s.talon, 's')
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)
x, y = l.XM+2*l.XS, l.YM
for i in range(4):
s.foundations.append(RK_FoundationStack(x, y, self))
x += l.XS
x, y = l.XM+2*l.XS, l.YM+l.YS
for i in range(4):
stack = Scuffle_RowStack(x, y, self, max_move=1)
s.rows.append(stack)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
x += l.XS
l.defaultStackGroups()
def _shuffleHook(self, cards):
return self._shuffleHookMoveToTop(cards,
lambda c: (c.rank == ACE, c.suit))
def startGame(self):
self.startDealSample()
self.s.talon.dealRow(rows=self.s.foundations)
self.s.talon.dealRow()
# register the game # register the game
registerGame(GameInfo(330, Sultan, "Sultan", registerGame(GameInfo(330, Sultan, "Sultan",
@ -759,3 +818,5 @@ registerGame(GameInfo(438, SixesAndSevens, "Sixes and Sevens",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(477, CornerSuite, "Corner Suite", registerGame(GameInfo(477, CornerSuite, "Corner Suite",
GI.GT_2DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_2DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(553, Scuffle, "Scuffle",
GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))

View file

@ -102,8 +102,8 @@ from pysoltk import bind, unbind_destroy
from pysoltk import after, after_idle, after_cancel from pysoltk import after, after_idle, after_cancel
from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText
from pysoltk import Card from pysoltk import Card
from pysoltk import getTextWidth
from tkFont import Font
# /*********************************************************************** # /***********************************************************************
# // Let's start with some test methods for cards. # // Let's start with some test methods for cards.
@ -1398,14 +1398,16 @@ class DealBaseCard_StackMethods:
class RedealCards_StackMethods: class RedealCards_StackMethods:
def redealCards(self, sound=0, shuffle=False, reverse=False, frames=4): def redealCards(self, rows=None, sound=0, shuffle=False, reverse=False, frames=4):
if sound and self.game.app.opt.animations: if sound and self.game.app.opt.animations:
self.game.startDealSample() self.game.startDealSample()
lr = len(self.game.s.rows) lr = len(self.game.s.rows)
# move all cards to the Talon # move all cards to the Talon
num_cards = 0 num_cards = 0
assert len(self.cards) == 0 assert len(self.cards) == 0
rows = list(self.game.s.rows)[:] if rows is None:
rows = self.game.s.rows
rows = list(rows)
if reverse: if reverse:
rows.reverse() rows.reverse()
for r in rows: for r in rows:
@ -1525,7 +1527,7 @@ class TalonStack(Stack,
else: else:
ca = None ca = None
font = self.game.app.getFont("canvas_default") font = self.game.app.getFont("canvas_default")
text_width = Font(self.game.canvas, font).measure(_('Redeal')) text_width = getTextWidth(_('Redeal'), font=font, root=self.game.canvas)
if images.CARDW >= text_width+4 and ca: if images.CARDW >= text_width+4 and ca:
# add a redeal text above the bottom image # add a redeal text above the bottom image
if self.max_rounds != 1: if self.max_rounds != 1:
@ -2212,6 +2214,8 @@ class ArbitraryStack(OpenStack):
def startDrag(self, event, sound=1): def startDrag(self, event, sound=1):
OpenStack.startDrag(self, event, sound=sound) OpenStack.startDrag(self, event, sound=sound)
for c in self.cards[self.game.drag.index+1:]:
c.moveBy(0, -self.CARD_YOFFSET[0])
def doubleclickHandler(self, event): def doubleclickHandler(self, event):
# flip or drop a card # flip or drop a card
@ -2231,10 +2235,6 @@ class ArbitraryStack(OpenStack):
return 1 return 1
return 0 return 0
## def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
## i = len(self.cards)-1
## self.singleCardMove(i, to_stack, frames=frames, shadow=shadow)
def moveCardsBackHandler(self, event, drag): def moveCardsBackHandler(self, event, drag):
i = self.cards.index(drag.cards[0]) i = self.cards.index(drag.cards[0])
for card in self.cards[i:]: for card in self.cards[i:]:

View file

@ -51,11 +51,13 @@ __all__ = ['wm_withdraw',
'loadImage', 'loadImage',
#'fillImage', #'fillImage',
'createImage', 'createImage',
'getTextWidth',
] ]
# imports # imports
import sys, os, re import sys, os, re
import Tkinter import Tkinter
from tkFont import Font
try: try:
# PIL # PIL
import Image import Image
@ -398,3 +400,11 @@ def createImage(width, height, fill, outline=None):
fillImage(image, fill, outline) fillImage(image, fill, outline)
return image return image
# /***********************************************************************
# // font utils
# ************************************************************************/
def getTextWidth(text, font, root=None):
return Font(root=root, font=font).measure(text)