mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ 11 new games
* improved StackDesc * improved CautiousDefaultHint git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@30 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
3c6df76c7a
commit
556a82c367
14 changed files with 397 additions and 30 deletions
|
@ -1253,11 +1253,13 @@ for %d moves.
|
||||||
strings=(_("&New game"), None, _("&Cancel")),
|
strings=(_("&New game"), None, _("&Cancel")),
|
||||||
image=self.app.gimages.logos[4], separatorwidth=2)
|
image=self.app.gimages.logos[4], separatorwidth=2)
|
||||||
elif self.gstats.updated < 0:
|
elif self.gstats.updated < 0:
|
||||||
|
self.finished = True
|
||||||
self.playSample("gamefinished", priority=1000)
|
self.playSample("gamefinished", priority=1000)
|
||||||
d = MfxMessageDialog(self.top, title=_("Game finished"), bitmap="info",
|
d = MfxMessageDialog(self.top, title=_("Game finished"), bitmap="info",
|
||||||
text=_("\nGame finished\n"),
|
text=_("\nGame finished\n"),
|
||||||
strings=(_("&New game"), None, _("&Cancel")))
|
strings=(_("&New game"), None, _("&Cancel")))
|
||||||
else:
|
else:
|
||||||
|
self.finished = True
|
||||||
self.playSample("gamelost", priority=1000)
|
self.playSample("gamelost", priority=1000)
|
||||||
d = MfxMessageDialog(self.top, title=_("Game finished"), bitmap="info",
|
d = MfxMessageDialog(self.top, title=_("Game finished"), bitmap="info",
|
||||||
text=_("\nGame finished, but not without my help...\n"),
|
text=_("\nGame finished, but not without my help...\n"),
|
||||||
|
|
|
@ -213,16 +213,19 @@ class Interregnum_Foundation(RK_FoundationStack):
|
||||||
class Interregnum(Game):
|
class Interregnum(Game):
|
||||||
GAME_VERSION = 2
|
GAME_VERSION = 2
|
||||||
|
|
||||||
|
Talon_Class = DealRowTalonStack
|
||||||
|
RowStack_Class = StackWrapper(BasicRowStack, max_accept=0, max_move=1)
|
||||||
|
|
||||||
#
|
#
|
||||||
# game layout
|
# game layout
|
||||||
#
|
#
|
||||||
|
|
||||||
def createGame(self, rows=8):
|
def createGame(self, rows=8, playcards=12, texts=False):
|
||||||
# create layout
|
# create layout
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
# set window
|
# set window
|
||||||
self.setSize(l.XM + max(9,rows)*l.XS, l.YM + 5*l.YS)
|
self.setSize(l.XM+max(9,rows)*l.XS, l.YM+3*l.YS+playcards*l.YOFFSET)
|
||||||
|
|
||||||
# extra settings
|
# extra settings
|
||||||
self.base_cards = None
|
self.base_cards = None
|
||||||
|
@ -236,9 +239,15 @@ class Interregnum(Game):
|
||||||
s.foundations.append(Interregnum_Foundation(x, y, self, mod=13, max_move=0))
|
s.foundations.append(Interregnum_Foundation(x, y, self, mod=13, max_move=0))
|
||||||
for i in range(rows):
|
for i in range(rows):
|
||||||
x, y, = l.XM + (2*i+8-rows)*l.XS/2, l.YM + 2*l.YS
|
x, y, = l.XM + (2*i+8-rows)*l.XS/2, l.YM + 2*l.YS
|
||||||
s.rows.append(BasicRowStack(x, y, self, max_accept=0, max_move=1))
|
s.rows.append(self.RowStack_Class(x, y, self))
|
||||||
s.talon = DealRowTalonStack(self.width-l.XS, self.height-l.YS, self)
|
s.talon = self.Talon_Class(self.width-l.XS, self.height-l.YS, self)
|
||||||
l.createText(s.talon, "nn")
|
if texts:
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
l.createText(s.talon, "nn")
|
||||||
|
|
||||||
# define stack-groups
|
# define stack-groups
|
||||||
l.defaultStackGroups()
|
l.defaultStackGroups()
|
||||||
|
@ -249,6 +258,7 @@ class Interregnum(Game):
|
||||||
|
|
||||||
def startGame(self):
|
def startGame(self):
|
||||||
self.startDealSample()
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
# deal base_cards to reserves, update foundations cap.base_rank
|
# deal base_cards to reserves, update foundations cap.base_rank
|
||||||
self.base_cards = []
|
self.base_cards = []
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
|
@ -256,8 +266,6 @@ class Interregnum(Game):
|
||||||
self.s.foundations[i].cap.base_rank = (self.base_cards[i].rank + 1) % 13
|
self.s.foundations[i].cap.base_rank = (self.base_cards[i].rank + 1) % 13
|
||||||
self.flipMove(self.s.talon)
|
self.flipMove(self.s.talon)
|
||||||
self.moveMove(1, self.s.talon, self.s.reserves[i])
|
self.moveMove(1, self.s.talon, self.s.reserves[i])
|
||||||
# deal other cards
|
|
||||||
self.s.talon.dealRow()
|
|
||||||
|
|
||||||
def getAutoStacks(self, event=None):
|
def getAutoStacks(self, event=None):
|
||||||
return ((), (), self.sg.dropstacks)
|
return ((), (), self.sg.dropstacks)
|
||||||
|
@ -282,6 +290,57 @@ class Interregnum(Game):
|
||||||
for c in self.base_cards:
|
for c in self.base_cards:
|
||||||
p.dump(c.id)
|
p.dump(c.id)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Primrose
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Primrose_Talon(DealRowTalonStack):
|
||||||
|
|
||||||
|
def canDealCards(self):
|
||||||
|
if self.round == self.max_rounds and not self.cards:
|
||||||
|
return False
|
||||||
|
return not self.game.isGameWon()
|
||||||
|
|
||||||
|
def _redeal(self):
|
||||||
|
lr = len(self.game.s.rows)
|
||||||
|
rows = self.game.s.rows
|
||||||
|
r = self.game.s.rows[self.round-1]
|
||||||
|
for i in range(len(r.cards)):
|
||||||
|
self.game.moveMove(1, r, self, frames=4)
|
||||||
|
self.game.flipMove(self)
|
||||||
|
self.game.nextRoundMove(self)
|
||||||
|
|
||||||
|
def dealCards(self, sound=0):
|
||||||
|
if sound:
|
||||||
|
self.game.startDealSample()
|
||||||
|
if len(self.cards) == 0:
|
||||||
|
self._redeal()
|
||||||
|
if self.round == 1:
|
||||||
|
n = self.dealRowAvail(sound=0)
|
||||||
|
else:
|
||||||
|
rows = self.game.s.rows
|
||||||
|
n = self.dealRowAvail(rows=rows[self.round-2:], sound=0)
|
||||||
|
#n = 0
|
||||||
|
while self.cards:
|
||||||
|
n += self.dealRowAvail(rows=rows, sound=0)
|
||||||
|
if sound:
|
||||||
|
self.game.stopSamples()
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
class Primrose(Interregnum):
|
||||||
|
Talon_Class = StackWrapper(Primrose_Talon, max_rounds=9)
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Interregnum.createGame(self, playcards=16, texts=True)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in range(11):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
Interregnum.startGame(self)
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Colorado
|
# // Colorado
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
@ -479,4 +538,6 @@ registerGame(GameInfo(553, Scuffle, "Scuffle",
|
||||||
GI.GT_NUMERICA, 1, 2, GI.SL_MOSTLY_LUCK))
|
GI.GT_NUMERICA, 1, 2, GI.SL_MOSTLY_LUCK))
|
||||||
registerGame(GameInfo(560, DoubleAcquaintance, "Double Acquaintance",
|
registerGame(GameInfo(560, DoubleAcquaintance, "Double Acquaintance",
|
||||||
GI.GT_NUMERICA, 2, 2, GI.SL_BALANCED))
|
GI.GT_NUMERICA, 2, 2, GI.SL_BALANCED))
|
||||||
|
registerGame(GameInfo(569, Primrose, "Primrose",
|
||||||
|
GI.GT_NUMERICA, 2, 8, GI.SL_BALANCED))
|
||||||
|
|
||||||
|
|
|
@ -353,7 +353,8 @@ class Streets(FortyThieves):
|
||||||
|
|
||||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
return (card1.color != card2.color and
|
return (card1.color != card2.color and
|
||||||
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
|
(card1.rank + 1 == card2.rank or
|
||||||
|
card2.rank + 1 == card1.rank))
|
||||||
|
|
||||||
|
|
||||||
class Maria(Streets):
|
class Maria(Streets):
|
||||||
|
@ -929,8 +930,120 @@ class TheSpark(Game):
|
||||||
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Double Gold Mine
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class DoubleGoldMine_RowStack(AC_RowStack):
|
||||||
|
def getBottomImage(self):
|
||||||
|
return self.game.app.images.getReserveBottom()
|
||||||
|
|
||||||
|
class DoubleGoldMine(Streets):
|
||||||
|
|
||||||
|
RowStack_Class = DoubleGoldMine_RowStack
|
||||||
|
|
||||||
|
ROW_MAX_MOVE = UNLIMITED_MOVES
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Streets.createGame(self, rows=9, num_deal=3)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Interchange
|
||||||
|
# // Unlimited
|
||||||
|
# // Breakwater
|
||||||
|
# // Forty Nine
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Interchange(FortyThieves):
|
||||||
|
|
||||||
|
RowStack_Class = StackWrapper(SS_RowStack, base_rank=KING)
|
||||||
|
|
||||||
|
ROW_MAX_MOVE = UNLIMITED_MOVES
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
FortyThieves.createGame(self, rows=7)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in (0,1,2):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.s.talon.dealRow(flip=0, frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
|
||||||
|
class Unlimited(Interchange):
|
||||||
|
def createGame(self):
|
||||||
|
FortyThieves.createGame(self, rows=7, max_rounds=UNLIMITED_REDEALS)
|
||||||
|
|
||||||
|
|
||||||
|
class Breakwater(Interchange):
|
||||||
|
RowStack_Class = RK_RowStack
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
|
||||||
|
class FortyNine_RowStack(AC_RowStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not AC_RowStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if self.cards:
|
||||||
|
return len(cards) == 1
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class FortyNine(Interchange):
|
||||||
|
RowStack_Class = FortyNine_RowStack
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in range(6):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Indian Patience
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class IndianPatience_RowStack(Indian_RowStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not Indian_RowStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if not self.game.s.talon.cards:
|
||||||
|
return True
|
||||||
|
if self.cards:
|
||||||
|
if from_stack in self.game.s.rows and len(from_stack.cards) == 1:
|
||||||
|
return False
|
||||||
|
return len(self.cards) != 1
|
||||||
|
return True
|
||||||
|
|
||||||
|
class IndianPatience(Indian):
|
||||||
|
RowStack_Class = IndianPatience_RowStack
|
||||||
|
|
||||||
|
def fillStack(self, stack):
|
||||||
|
if stack in self.s.rows and not stack.cards:
|
||||||
|
old_state = self.enterState(self.S_FILL)
|
||||||
|
if self.s.talon.cards:
|
||||||
|
if len(self.s.talon.cards) == 1:
|
||||||
|
self.s.talon.flipMove()
|
||||||
|
self.s.talon.moveMove(1, stack)
|
||||||
|
if self.s.talon.cards:
|
||||||
|
self.s.talon.flipMove()
|
||||||
|
self.s.talon.moveMove(1, stack)
|
||||||
|
if self.s.talon.cards:
|
||||||
|
self.s.talon.flipMove()
|
||||||
|
self.s.talon.moveMove(1, stack)
|
||||||
|
self.leaveState(old_state)
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
|
@ -975,8 +1088,7 @@ registerGame(GameInfo(126, RedAndBlack, "Red and Black", # was: 75
|
||||||
registerGame(GameInfo(113, Zebra, "Zebra",
|
registerGame(GameInfo(113, Zebra, "Zebra",
|
||||||
GI.GT_FORTY_THIEVES, 2, 1, GI.SL_BALANCED))
|
GI.GT_FORTY_THIEVES, 2, 1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(69, Indian, "Indian",
|
registerGame(GameInfo(69, Indian, "Indian",
|
||||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED,
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
||||||
altnames=("Indian Patience",) ))
|
|
||||||
registerGame(GameInfo(74, Midshipman, "Midshipman",
|
registerGame(GameInfo(74, Midshipman, "Midshipman",
|
||||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(198, NapoleonsExile, "Napoleon's Exile",
|
registerGame(GameInfo(198, NapoleonsExile, "Napoleon's Exile",
|
||||||
|
@ -1026,5 +1138,16 @@ registerGame(GameInfo(556, Junction, "Junction",
|
||||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12) ))
|
ranks=(0, 6, 7, 8, 9, 10, 11, 12) ))
|
||||||
registerGame(GameInfo(564, TheSpark, "The Spark",
|
registerGame(GameInfo(564, TheSpark, "The Spark",
|
||||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_LUCK))
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_LUCK))
|
||||||
|
registerGame(GameInfo(573, DoubleGoldMine, "Double Gold Mine",
|
||||||
|
GI.GT_NUMERICA | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(574, Interchange, "Interchange",
|
||||||
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(575, Unlimited, "Unlimited",
|
||||||
|
GI.GT_FORTY_THIEVES, 2, -1, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(576, Breakwater, "Breakwater",
|
||||||
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(577, FortyNine, "Forty Nine",
|
||||||
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(578, IndianPatience, "Indian Patience",
|
||||||
|
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
|
@ -576,12 +576,25 @@ class EternalTriangle(Hypotenuse):
|
||||||
|
|
||||||
class RightTriangle_Talon(OpenStack, DealRowTalonStack):
|
class RightTriangle_Talon(OpenStack, DealRowTalonStack):
|
||||||
def __init__(self, x, y, game, max_rounds=1, num_deal=1, **cap):
|
def __init__(self, x, y, game, max_rounds=1, num_deal=1, **cap):
|
||||||
|
kwdefault(cap, max_move=1, max_accept=1, max_cards=999999)
|
||||||
Stack.__init__(self, x, y, game, cap=cap)
|
Stack.__init__(self, x, y, game, cap=cap)
|
||||||
self.max_rounds = max_rounds
|
self.max_rounds = max_rounds
|
||||||
self.num_deal = num_deal
|
self.num_deal = num_deal
|
||||||
self.round = 1
|
self.round = 1
|
||||||
self.base_cards = [] # for DealBaseCard_StackMethods
|
self.base_cards = [] # for DealBaseCard_StackMethods
|
||||||
|
|
||||||
|
def clickHandler(self, event):
|
||||||
|
if self.cards and not self.cards[-1].face_up:
|
||||||
|
return self.game.dealCards(sound=1)
|
||||||
|
return OpenStack.clickHandler(self, event)
|
||||||
|
|
||||||
|
def canDealCards(self):
|
||||||
|
if not DealRowTalonStack.canDealCards(self):
|
||||||
|
return False
|
||||||
|
if self.cards and self.cards[-1].face_up:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def canFlipCard(self):
|
def canFlipCard(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -589,10 +602,11 @@ class RightTriangle_Talon(OpenStack, DealRowTalonStack):
|
||||||
return self.game.app.images.getReserveBottom()
|
return self.game.app.images.getReserveBottom()
|
||||||
|
|
||||||
def getHelp(self):
|
def getHelp(self):
|
||||||
return ''
|
return DealRowTalonStack.getHelp(self)
|
||||||
|
|
||||||
|
|
||||||
class RightTriangle(Hypotenuse):
|
class RightTriangle(Hypotenuse):
|
||||||
Talon_Class = StackWrapper(RightTriangle_Talon, max_accept=1, max_move=1)
|
Talon_Class = RightTriangle_Talon
|
||||||
|
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
Gypsy.createGame(self, rows=10, playcards=24)
|
Gypsy.createGame(self, rows=10, playcards=24)
|
||||||
|
|
|
@ -45,6 +45,8 @@ from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||||
from pysollib.hint import KlondikeType_Hint
|
from pysollib.hint import KlondikeType_Hint
|
||||||
from pysollib.pysoltk import MfxCanvasText
|
from pysollib.pysoltk import MfxCanvasText
|
||||||
|
|
||||||
|
from canfield import CanfieldRush_Talon
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Klondike
|
# // Klondike
|
||||||
|
@ -1116,14 +1118,31 @@ class Boost(Klondike):
|
||||||
# // Gold Rush
|
# // Gold Rush
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
from canfield import CanfieldRush_Talon
|
|
||||||
|
|
||||||
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)
|
Klondike.createGame(self, max_rounds=3)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Gold Mine
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class GoldMine_RowStack(AC_RowStack):
|
||||||
|
def getBottomImage(self):
|
||||||
|
return self.game.app.images.getReserveBottom()
|
||||||
|
|
||||||
|
|
||||||
|
class GoldMine(Klondike):
|
||||||
|
RowStack_Class = GoldMine_RowStack
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
Klondike.createGame(self, max_rounds=1, num_deal=3)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(2, Klondike, "Klondike",
|
registerGame(GameInfo(2, Klondike, "Klondike",
|
||||||
|
@ -1231,7 +1250,7 @@ registerGame(GameInfo(479, Saratoga, "Saratoga",
|
||||||
registerGame(GameInfo(491, Whitehorse, "Whitehorse",
|
registerGame(GameInfo(491, Whitehorse, "Whitehorse",
|
||||||
GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED))
|
GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(518, Boost, "Boost",
|
registerGame(GameInfo(518, Boost, "Boost",
|
||||||
GI.GT_KLONDIKE, 1, 2, GI.SL_BALANCED))
|
GI.GT_KLONDIKE | GI.GT_ORIGINAL, 1, 2, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(522, ArticGarden, "Artic Garden",
|
registerGame(GameInfo(522, ArticGarden, "Artic Garden",
|
||||||
GI.GT_RAGLAN, 1, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_RAGLAN, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
registerGame(GameInfo(532, GoldRush, "Gold Rush",
|
registerGame(GameInfo(532, GoldRush, "Gold Rush",
|
||||||
|
@ -1240,4 +1259,6 @@ registerGame(GameInfo(539, Usk, "Usk",
|
||||||
GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED))
|
GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(541, BatsfordAgain, "Batsford Again",
|
registerGame(GameInfo(541, BatsfordAgain, "Batsford Again",
|
||||||
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
||||||
|
registerGame(GameInfo(572, GoldMine, "Gold Mine",
|
||||||
|
GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
|
@ -305,8 +305,16 @@ class RedMoon(BlueMoon):
|
||||||
|
|
||||||
|
|
||||||
class Galary_Hint(Montana_Hint):
|
class Galary_Hint(Montana_Hint):
|
||||||
# TODO
|
def shallMovePile(self, from_stack, to_stack, pile, rpile):
|
||||||
shallMovePile = DefaultHint._cautiousShallMovePile
|
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
|
||||||
|
return 0
|
||||||
|
# now check for loops
|
||||||
|
rr = self.ClonedStack(from_stack, stackcards=rpile)
|
||||||
|
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 0
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class Galary_RowStack(Montana_RowStack):
|
class Galary_RowStack(Montana_RowStack):
|
||||||
|
|
|
@ -529,6 +529,63 @@ class Twenty(Game):
|
||||||
self.leaveState(old_state)
|
self.leaveState(old_state)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Three Pirates
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class ThreePirates_Talon(DealRowTalonStack):
|
||||||
|
def dealCards(self, sound=0):
|
||||||
|
num_cards = 0
|
||||||
|
old_state = self.game.enterState(self.game.S_DEAL)
|
||||||
|
if self.cards:
|
||||||
|
if sound and not self.game.demo:
|
||||||
|
self.game.playSample("dealwaste")
|
||||||
|
num_cards = self.dealRowAvail(rows=self.game.s.reserves,
|
||||||
|
sound=0, frames=4)
|
||||||
|
self.game.leaveState(old_state)
|
||||||
|
return num_cards
|
||||||
|
|
||||||
|
|
||||||
|
class ThreePirates(Game):
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
|
self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+16*l.YOFFSET)
|
||||||
|
|
||||||
|
x, y, = l.XM+l.XS, l.YM
|
||||||
|
for i in range(8):
|
||||||
|
s.foundations.append(SS_FoundationStack(x, y, self, suit=i/2))
|
||||||
|
x = x + l.XS
|
||||||
|
|
||||||
|
x, y, = l.XM, l.YM+l.YS
|
||||||
|
for i in range(10):
|
||||||
|
s.rows.append(SS_RowStack(x, y, self, max_move=1))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x, y = l.XM, self.height-l.YS
|
||||||
|
s.talon = ThreePirates_Talon(x, y, self)
|
||||||
|
l.createText(s.talon, 'n')
|
||||||
|
x += l.XS
|
||||||
|
for i in (0,1,2):
|
||||||
|
stack = WasteStack(x, y, self)
|
||||||
|
s.reserves.append(stack)
|
||||||
|
l.createText(stack, 'n')
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
l.defaultStackGroups()
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in (0,1,2):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||||
|
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
|
registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
|
||||||
|
@ -553,4 +610,6 @@ registerGame(GameInfo(443, Twenty, "Twenty",
|
||||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(465, Granada, "Granada",
|
registerGame(GameInfo(465, Granada, "Granada",
|
||||||
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
|
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
|
||||||
|
registerGame(GameInfo(579, ThreePirates, "Three Pirates",
|
||||||
|
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
|
@ -1020,6 +1020,61 @@ class FredsSpider3Decks(FredsSpider):
|
||||||
Spidike.createGame(self, rows=13, playcards=26)
|
Spidike.createGame(self, rows=13, playcards=26)
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Long Tail
|
||||||
|
# // Short Tail
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class LongTail(RelaxedSpider):
|
||||||
|
|
||||||
|
def createGame(self, rows=5, playcards=16):
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
|
decks = self.gameinfo.decks
|
||||||
|
max_rows = max(2+decks*4, 2+rows)
|
||||||
|
w, h = l.XM+max_rows*l.XS, l.YM+l.YS+playcards*l.YOFFSET
|
||||||
|
self.setSize(w, h)
|
||||||
|
|
||||||
|
x, y = l.XM, l.YM
|
||||||
|
s.talon = DealRowTalonStack(x, y, self)
|
||||||
|
l.createText(s.talon, 'ne')
|
||||||
|
|
||||||
|
x += (max_rows-decks*4)*l.XS
|
||||||
|
for i in range(decks*4):
|
||||||
|
s.foundations.append(Spider_SS_Foundation(x, y, self))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x, y = l.XM, l.YM+l.YS
|
||||||
|
stack = ReserveStack(x, y, self, max_cards=UNLIMITED_CARDS)
|
||||||
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, l.YOFFSET
|
||||||
|
s.reserves.append(stack)
|
||||||
|
l.createText(stack, 'ne')
|
||||||
|
|
||||||
|
x += 2*l.XS
|
||||||
|
for i in range(rows):
|
||||||
|
s.rows.append(Spider_RowStack(x, y, self))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
l.defaultStackGroups()
|
||||||
|
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealRow(rows=self.s.reserves*2)
|
||||||
|
|
||||||
|
|
||||||
|
def getQuickPlayScore(self, ncards, from_stack, to_stack):
|
||||||
|
if to_stack in self.s.reserves:
|
||||||
|
return 0
|
||||||
|
return 1+RelaxedSpider.getQuickPlayScore(self, ncards, from_stack, to_stack)
|
||||||
|
|
||||||
|
|
||||||
|
class ShortTail(LongTail):
|
||||||
|
def createGame(self):
|
||||||
|
LongTail.createGame(self, rows=8, playcards=24)
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(10, RelaxedSpider, "Relaxed Spider",
|
registerGame(GameInfo(10, RelaxedSpider, "Relaxed Spider",
|
||||||
GI.GT_SPIDER | GI.GT_RELAXED, 2, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_SPIDER | GI.GT_RELAXED, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
@ -1124,4 +1179,8 @@ registerGame(GameInfo(543, FarmersWife, "Farmer's Wife",
|
||||||
GI.GT_SPIDER, 1, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_SPIDER, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
registerGame(GameInfo(544, HowTheyRun, "How They Run",
|
registerGame(GameInfo(544, HowTheyRun, "How They Run",
|
||||||
GI.GT_SPIDER, 1, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_SPIDER, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(570, LongTail, "Long Tail",
|
||||||
|
GI.GT_SPIDER, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
registerGame(GameInfo(571, ShortTail, "Short Tail",
|
||||||
|
GI.GT_SPIDER | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
|
@ -428,12 +428,12 @@ class Matrimony_Talon(DealRowTalonStack):
|
||||||
if len(self.cards) == 0:
|
if len(self.cards) == 0:
|
||||||
self._redeal()
|
self._redeal()
|
||||||
if self.round == 1:
|
if self.round == 1:
|
||||||
n = self.dealRowAvail(sound=sound)
|
n = self.dealRowAvail(sound=0)
|
||||||
else:
|
else:
|
||||||
rows = self.game.s.rows[-self.round+1:]
|
rows = self.game.s.rows[-self.round+1:]
|
||||||
n = self.dealRowAvail(rows=rows, sound=sound)
|
n = self.dealRowAvail(rows=rows, sound=0)
|
||||||
while self.cards:
|
while self.cards:
|
||||||
n += self.dealRowAvail(rows=self.game.s.rows, sound=sound)
|
n += self.dealRowAvail(rows=self.game.s.rows, sound=0)
|
||||||
if sound:
|
if sound:
|
||||||
self.game.stopSamples()
|
self.game.stopSamples()
|
||||||
return n
|
return n
|
||||||
|
|
|
@ -693,6 +693,7 @@ registerGame(GameInfo(525, Queensland, "Queensland",
|
||||||
registerGame(GameInfo(526, OutbackPatience, "Outback Patience",
|
registerGame(GameInfo(526, OutbackPatience, "Outback Patience",
|
||||||
GI.GT_YUKON, 1, 0, GI.SL_BALANCED))
|
GI.GT_YUKON, 1, 0, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(530, RussianSpider, "Russian Spider",
|
registerGame(GameInfo(530, RussianSpider, "Russian Spider",
|
||||||
GI.GT_SPIDER, 1, 0, GI.SL_BALANCED))
|
GI.GT_SPIDER, 1, 0, GI.SL_BALANCED,
|
||||||
|
altnames=('Ukrainian Solitaire',) ))
|
||||||
registerGame(GameInfo(531, DoubleRussianSpider, "Double Russian Spider",
|
registerGame(GameInfo(531, DoubleRussianSpider, "Double Russian Spider",
|
||||||
GI.GT_SPIDER | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))
|
GI.GT_SPIDER | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))
|
||||||
|
|
|
@ -215,6 +215,9 @@ class AbstractHint(HintInterface):
|
||||||
def _cautiousShallMovePile(self, from_stack, to_stack, pile, rpile):
|
def _cautiousShallMovePile(self, from_stack, to_stack, pile, rpile):
|
||||||
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
|
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
|
||||||
return 0
|
return 0
|
||||||
|
#
|
||||||
|
if len(rpile) == 0:
|
||||||
|
return 1
|
||||||
# now check for loops
|
# now check for loops
|
||||||
rr = self.ClonedStack(from_stack, stackcards=rpile)
|
rr = self.ClonedStack(from_stack, stackcards=rpile)
|
||||||
if rr.acceptsCards(to_stack, pile):
|
if rr.acceptsCards(to_stack, pile):
|
||||||
|
@ -228,6 +231,9 @@ class AbstractHint(HintInterface):
|
||||||
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
|
if from_stack is to_stack or not to_stack.acceptsCards(from_stack, pile):
|
||||||
return 0
|
return 0
|
||||||
if self.level >= 2:
|
if self.level >= 2:
|
||||||
|
#
|
||||||
|
if len(rpile) == 0:
|
||||||
|
return 1
|
||||||
# now check for loops
|
# now check for loops
|
||||||
rr = self.ClonedStack(from_stack, stackcards=rpile)
|
rr = self.ClonedStack(from_stack, stackcards=rpile)
|
||||||
if rr.acceptsCards(to_stack, pile):
|
if rr.acceptsCards(to_stack, pile):
|
||||||
|
|
|
@ -1956,6 +1956,10 @@ class FreeCell_SS_RowStack(SS_RowStack):
|
||||||
class Spider_AC_RowStack(AC_RowStack):
|
class Spider_AC_RowStack(AC_RowStack):
|
||||||
def _isAcceptableSequence(self, cards):
|
def _isAcceptableSequence(self, cards):
|
||||||
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
||||||
|
def getHelp(self):
|
||||||
|
if self.cap.dir > 0: return _('Tableau. Build up regardless of suit. Sequences of cards in alternate color can be moved as a unit.')
|
||||||
|
elif self.cap.dir < 0: return _('Tableau. Build down regardless of suit. Sequences of cards in alternate color can be moved as a unit.')
|
||||||
|
else: return _('Tableau. Build by same rank.')
|
||||||
|
|
||||||
# A Spider_SameSuit_RowStack builds down by rank and suit,
|
# A Spider_SameSuit_RowStack builds down by rank and suit,
|
||||||
# but accepts sequences that match by rank only.
|
# but accepts sequences that match by rank only.
|
||||||
|
@ -1963,8 +1967,8 @@ class Spider_SS_RowStack(SS_RowStack):
|
||||||
def _isAcceptableSequence(self, cards):
|
def _isAcceptableSequence(self, cards):
|
||||||
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
||||||
def getHelp(self):
|
def getHelp(self):
|
||||||
if self.cap.dir > 0: return _('Tableau. Build up regardless of suit.')
|
if self.cap.dir > 0: return _('Tableau. Build up regardless of suit. Sequences of cards in the same suit can be moved as a unit.')
|
||||||
elif self.cap.dir < 0: return _('Tableau. Build down regardless of suit.')
|
elif self.cap.dir < 0: return _('Tableau. Build down regardless of suit. Sequences of cards in the same suit can be moved as a unit.')
|
||||||
else: return _('Tableau. Build by same rank.')
|
else: return _('Tableau. Build by same rank.')
|
||||||
|
|
||||||
# A Yukon_AlternateColor_RowStack builds down by rank and alternate color,
|
# A Yukon_AlternateColor_RowStack builds down by rank and alternate color,
|
||||||
|
|
|
@ -148,7 +148,8 @@ class MfxCanvas(Tkinter.Canvas):
|
||||||
self.__tileimage = image
|
self.__tileimage = image
|
||||||
if stretch:
|
if stretch:
|
||||||
#
|
#
|
||||||
id = self._x_create("image", 0, 0, image=image, anchor="nw")
|
id = self._x_create("image", -self.xmargin, -self.ymargin,
|
||||||
|
image=image, anchor="nw")
|
||||||
self.tag_lower(id) # also see tag_lower above
|
self.tag_lower(id) # also see tag_lower above
|
||||||
self.__tiles.append(id)
|
self.__tiles.append(id)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -680,6 +680,7 @@ class StackDesc:
|
||||||
self.game = game
|
self.game = game
|
||||||
self.stack = stack
|
self.stack = stack
|
||||||
self.canvas = game.canvas
|
self.canvas = game.canvas
|
||||||
|
self.bindings = []
|
||||||
|
|
||||||
font = game.app.getFont('canvas_small')
|
font = game.app.getFont('canvas_small')
|
||||||
##print self.app.cardset.CARDW, self.app.images.CARDW
|
##print self.app.cardset.CARDW, self.app.images.CARDW
|
||||||
|
@ -690,22 +691,29 @@ class StackDesc:
|
||||||
if text:
|
if text:
|
||||||
frame = Tkinter.Frame(self.canvas, highlightthickness=1,
|
frame = Tkinter.Frame(self.canvas, highlightthickness=1,
|
||||||
highlightbackground='black')
|
highlightbackground='black')
|
||||||
|
self.frame = frame
|
||||||
label = Tkinter.Message(frame, font=font, text=text, width=cardw-8,
|
label = Tkinter.Message(frame, font=font, text=text, width=cardw-8,
|
||||||
fg='#000000', bg='#ffffe0')
|
fg='#000000', bg='#ffffe0', bd=1)
|
||||||
label.pack()
|
label.pack()
|
||||||
self.label = label
|
self.label = label
|
||||||
self.id = self.canvas.create_window(x, y, window=frame, anchor='n')
|
self.id = self.canvas.create_window(x, y, window=frame, anchor='n')
|
||||||
self.binding = label.bind('<ButtonPress>', self.buttonPressEvent)
|
self.bindings.append(label.bind('<ButtonPress>', self._buttonPressEvent))
|
||||||
|
##self.bindings.append(label.bind('<Enter>', self._enterEvent))
|
||||||
else:
|
else:
|
||||||
self.id = None
|
self.id = None
|
||||||
|
|
||||||
def buttonPressEvent(self, *event):
|
def _buttonPressEvent(self, *event):
|
||||||
self.game.deleteStackDesc()
|
##self.game.deleteStackDesc()
|
||||||
|
self.frame.tkraise()
|
||||||
|
|
||||||
|
def _enterEvent(self, *event):
|
||||||
|
self.frame.tkraise()
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
if self.id:
|
if self.id:
|
||||||
self.canvas.delete(self.id)
|
self.canvas.delete(self.id)
|
||||||
self.label.unbind('<ButtonPress>', self.binding)
|
for b in self.bindings:
|
||||||
|
self.label.unbind('<ButtonPress>', b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue