mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ 6 new games
* improved findcarddialog git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@38 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
84b710bb51
commit
138bfe335c
7 changed files with 557 additions and 23 deletions
|
@ -1159,7 +1159,7 @@ class Game:
|
|||
|
||||
# redeal cards (used in RedealTalonStack; all cards already in talon)
|
||||
def redealCards(self):
|
||||
pass
|
||||
raise SubclassResponsibility
|
||||
|
||||
# the actual hint class (or None)
|
||||
Hint_Class = DefaultHint
|
||||
|
@ -1467,6 +1467,8 @@ for %d moves.
|
|||
def _highlightCards(self, info, sleep=1.5):
|
||||
if not info:
|
||||
return 0
|
||||
if self.pause:
|
||||
return 0
|
||||
items = []
|
||||
for s, c1, c2, color in info:
|
||||
assert c1 in s.cards and c2 in s.cards
|
||||
|
|
|
@ -370,6 +370,209 @@ class OpenSlyFox(SlyFox):
|
|||
l.defaultStackGroups()
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Princess Patience
|
||||
# ************************************************************************/
|
||||
|
||||
class PrincessPatience_RowStack(SS_RowStack):
|
||||
|
||||
def canMoveCards(self, cards):
|
||||
if not SS_RowStack.canMoveCards(self, cards):
|
||||
return False
|
||||
index = list(self.game.s.rows).index(self)
|
||||
col = index % 4
|
||||
row = index / 4
|
||||
if index < 16: # left
|
||||
for i in range(col+1, 4):
|
||||
r = self.game.s.rows[row*4+i]
|
||||
if r.cards:
|
||||
return False
|
||||
else: # right
|
||||
for i in range(0, col):
|
||||
r = self.game.s.rows[row*4+i]
|
||||
if r.cards:
|
||||
return False
|
||||
return True
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not SS_RowStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
if not self.cards:
|
||||
return from_stack is self.game.s.waste
|
||||
return True
|
||||
|
||||
|
||||
class PrincessPatience(Game):
|
||||
RowStack_Class = PrincessPatience_RowStack
|
||||
|
||||
def createGame(self, max_rounds=1):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+11*l.XS, l.YM+5*l.YS)
|
||||
|
||||
y = l.YM
|
||||
for i in range(4):
|
||||
x = l.XM
|
||||
for j in range(4):
|
||||
stack = self.RowStack_Class(x, y, self, max_move=1)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
x += l.XS
|
||||
y += l.YS
|
||||
y = l.YM
|
||||
for i in range(4):
|
||||
x = l.XM+7*l.XS
|
||||
for j in range(4):
|
||||
stack = self.RowStack_Class(x, y, self, max_move=1)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
x += l.XS
|
||||
y += l.YS
|
||||
|
||||
x, y = l.XM+4.5*l.XS, l.YM
|
||||
for i in range(4):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
|
||||
s.foundations.append(SS_FoundationStack(x+l.XS, y, self, suit=i))
|
||||
y += l.YS
|
||||
|
||||
x, y = l.XM+4.5*l.XS, self.height-l.YS
|
||||
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
|
||||
l.createText(s.talon, 'sw')
|
||||
x += l.XS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
l.createText(s.waste, 'se')
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards()
|
||||
|
||||
|
||||
shallHighlightMatch = Game._shallHighlightMatch_SS
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Grandmamma's Patience
|
||||
# ************************************************************************/
|
||||
|
||||
class GrandmammasPatience_Talon(OpenTalonStack):
|
||||
rightclickHandler = OpenStack.rightclickHandler
|
||||
doubleclickHandler = OpenStack.doubleclickHandler
|
||||
|
||||
|
||||
class GrandmammasPatience_RowStack(BasicRowStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not BasicRowStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
return from_stack not in self.game.s.rows
|
||||
|
||||
|
||||
class GrandmammasPatience(Game):
|
||||
|
||||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
h0 = l.YS+4*l.YOFFSET
|
||||
self.setSize(l.XM+11*l.XS, l.YM+2*l.YS+2*h0)
|
||||
self.base_rank = ANY_RANK
|
||||
|
||||
x, y = l.XM, l.YM
|
||||
s.talon = GrandmammasPatience_Talon(x, y, self)
|
||||
l.createText(s.talon, 'ne')
|
||||
|
||||
x, y = self.width-4*l.XS, l.YM
|
||||
for i in range(4):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i,
|
||||
dir=-1, mod=13, max_move=0, base_rank=ANY_RANK))
|
||||
x += l.XS
|
||||
stack = s.foundations[0]
|
||||
tx, ty, ta, tf = l.getTextAttr(stack, "sw")
|
||||
font = self.app.getFont("canvas_default")
|
||||
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
|
||||
anchor=ta, font=font)
|
||||
x, y = self.width-4*l.XS, self.height-l.YS
|
||||
for i in range(4):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i,
|
||||
mod=13, max_move=0, base_rank=ANY_RANK))
|
||||
x += l.XS
|
||||
stack = s.foundations[4]
|
||||
tx, ty, ta, tf = l.getTextAttr(stack, "sw")
|
||||
font = self.app.getFont("canvas_default")
|
||||
stack.texts.misc = MfxCanvasText(self.canvas,
|
||||
tx, ty, anchor=ta, font=font)
|
||||
|
||||
y = l.YM+l.YS
|
||||
for i in range(2):
|
||||
x = l.XM
|
||||
for j in range(11):
|
||||
s.rows.append(GrandmammasPatience_RowStack(x, y, self,
|
||||
max_accept=1, max_cards=2))
|
||||
x += l.XS
|
||||
y += h0
|
||||
|
||||
x, y = l.XM, self.height-l.YS
|
||||
for i in range(4):
|
||||
s.reserves.append(ReserveStack(x, y, self))
|
||||
x += l.XS
|
||||
|
||||
l.defaultStackGroups()
|
||||
self.sg.dropstacks.append(s.talon)
|
||||
|
||||
|
||||
def startGame(self):
|
||||
c = self.s.talon.cards[-1]
|
||||
self.base_rank = c.rank
|
||||
to_stack = self.s.foundations[c.suit]
|
||||
self.flipMove(self.s.talon)
|
||||
self.moveMove(1, self.s.talon, to_stack, frames=0)
|
||||
for s in self.s.foundations[:4]:
|
||||
s.cap.base_rank = c.rank
|
||||
for s in self.s.foundations[4:]:
|
||||
s.cap.base_rank = (c.rank+1)%13
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.fillStack()
|
||||
|
||||
|
||||
def fillStack(self, stack):
|
||||
if stack in self.s.rows and not stack.cards:
|
||||
if self.s.talon.cards:
|
||||
old_state = self.enterState(self.S_FILL)
|
||||
self.s.talon.moveMove(1, stack)
|
||||
self.leaveState(old_state)
|
||||
|
||||
def updateText(self):
|
||||
if self.preview > 1:
|
||||
return
|
||||
base_rank = self.base_rank
|
||||
if base_rank == ANY_RANK:
|
||||
t1 = t2 = ''
|
||||
else:
|
||||
t1 = RANKS[base_rank]+_(" Descending")
|
||||
t2 = RANKS[(base_rank+1)%13]+_(" Ascending")
|
||||
self.s.foundations[0].texts.misc.config(text=t1)
|
||||
self.s.foundations[4].texts.misc.config(text=t2)
|
||||
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.base_rank = game.loadinfo.base_rank
|
||||
for s in self.s.foundations[:4]:
|
||||
s.cap.base_rank = self.base_rank
|
||||
for s in self.s.foundations[4:]:
|
||||
s.cap.base_rank = (self.base_rank+1)%13
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(base_rank=None) # register extra load var.
|
||||
self.loadinfo.base_rank = p.load()
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
p.dump(self.base_rank)
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(280, Camelot, "Camelot",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
|
||||
|
@ -377,4 +580,9 @@ registerGame(GameInfo(610, SlyFox, "Sly Fox",
|
|||
GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(614, OpenSlyFox, "Open Sly Fox",
|
||||
GI.GT_NUMERICA | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(623, PrincessPatience, "Princess Patience",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(622, GrandmammasPatience, "Grandmamma's Patience",
|
||||
GI.GT_NUMERICA, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class Fan(Game):
|
|||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self, rows=(5,5,5,3), playcards=9, reserves=0):
|
||||
def createGame(self, rows=(5,5,5,3), playcards=9, reserves=0, texts=False):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
|
@ -106,6 +106,12 @@ class Fan(Game):
|
|||
x += w
|
||||
x, y = self.width - l.XS, self.height - l.YS
|
||||
s.talon = self.Talon_Class(x, y, self)
|
||||
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)
|
||||
|
||||
|
||||
# define stack-groups
|
||||
l.defaultStackGroups()
|
||||
|
@ -601,6 +607,40 @@ class TroikaPlus(Troika):
|
|||
## self.s.talon.dealRow(rows=self.s.rows[:-1])
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Fascination Fan
|
||||
# ************************************************************************/
|
||||
|
||||
class FascinationFan_Talon(RedealTalonStack):
|
||||
def dealCards(self, sound=0):
|
||||
RedealTalonStack.redealCards(self, shuffle=True, sound=sound)
|
||||
|
||||
class FascinationFan(Fan):
|
||||
Talon_Class = StackWrapper(FascinationFan_Talon, max_rounds=7)
|
||||
#Talon_Class = StackWrapper(LaBelleLucie_Talon, max_rounds=7)
|
||||
RowStack_Class = StackWrapper(AC_RowStack, base_rank=NO_RANK)
|
||||
|
||||
def createGame(self):
|
||||
Fan.createGame(self, texts=True)
|
||||
|
||||
def startGame(self):
|
||||
for i in range(2):
|
||||
self.s.talon.dealRow(rows=self.s.rows[:17], flip=0, frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
def redealCards(self):
|
||||
nrows = len(self.s.talon.cards)/3
|
||||
if len(self.s.talon.cards)%3: nrows += 1
|
||||
self.s.talon.dealRowAvail(rows=self.s.rows[:nrows], flip=0, frames=4)
|
||||
self.s.talon.dealRowAvail(rows=self.s.rows[:nrows], flip=0, frames=4)
|
||||
self.s.talon.dealRowAvail(frames=4)
|
||||
for r in self.s.rows[nrows-2:nrows]:
|
||||
if r.canFlipCard(): r.flipMove()
|
||||
|
||||
shallHighlightMatch = Game._shallHighlightMatch_AC
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(56, Fan, "Fan",
|
||||
|
@ -637,4 +677,6 @@ registerGame(GameInfo(516, Troika, "Troika",
|
|||
GI.GT_FAN_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(517, TroikaPlus, "Troika +",
|
||||
GI.GT_FAN_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(625, FascinationFan, "Fascination Fan",
|
||||
GI.GT_FAN_TYPE, 1, 6, GI.SL_BALANCED))
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ from pysollib.stack import *
|
|||
from pysollib.game import Game
|
||||
from pysollib.layout import Layout
|
||||
from pysollib.hint import DefaultHint, FreeCellType_Hint, CautiousDefaultHint
|
||||
from pysollib.pysoltk import MfxCanvasText
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -463,6 +464,113 @@ class Glencoe(Intrigue):
|
|||
]
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Step-Up
|
||||
# ************************************************************************/
|
||||
|
||||
class StepUp_Foundation(SS_FoundationStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not SS_FoundationStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
if from_stack in self.game.s.reserves:
|
||||
return True
|
||||
for r in self.game.s.reserves:
|
||||
if not r.cards:
|
||||
return True
|
||||
return False
|
||||
|
||||
class StepUp_Talon(WasteTalonStack):
|
||||
def canDealCards(self):
|
||||
if not WasteTalonStack.canDealCards(self):
|
||||
return False
|
||||
for r in self.game.s.reserves:
|
||||
if not r.cards:
|
||||
return False
|
||||
return True
|
||||
|
||||
class StepUp_RowStack(AC_RowStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not AC_RowStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
if (from_stack in self.game.s.reserves or
|
||||
from_stack in self.game.s.foundations):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class StepUp(Game):
|
||||
|
||||
def createGame(self):
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+13*l.XS, l.YM+7*l.YS)
|
||||
self.base_rank = ANY_RANK
|
||||
|
||||
x, y = l.XM+2.5*l.XS, l.YM
|
||||
for i in range(8):
|
||||
s.foundations.append(StepUp_Foundation(x, y, self,
|
||||
suit=i%4, mod=13, base_rank=ANY_RANK))
|
||||
x += l.XS
|
||||
tx, ty, ta, tf = l.getTextAttr(s.foundations[0], "sw")
|
||||
font = self.app.getFont("canvas_default")
|
||||
self.texts.info = MfxCanvasText(self.canvas, tx, ty,
|
||||
anchor=ta, font=font)
|
||||
|
||||
x, y = l.XM, l.YM+l.YS
|
||||
for i in range(13):
|
||||
s.reserves.append(ReserveStack(x, y, self))
|
||||
x += l.XS
|
||||
x, y = l.XM+2*l.XS, l.YM+2*l.YS
|
||||
for i in range(9):
|
||||
s.rows.append(StepUp_RowStack(x, y, self, max_move=1, mod=13))
|
||||
x += l.XS
|
||||
|
||||
x, y = l.XM, l.YM+2.5*l.YS
|
||||
s.talon = StepUp_Talon(x, y, self, max_rounds=1)
|
||||
l.createText(s.talon, 'se')
|
||||
y += l.YS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
l.createText(s.waste, 'se')
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def startGame(self):
|
||||
c = self.s.talon.cards[-1]
|
||||
self.base_rank = c.rank
|
||||
self.s.talon.flipMove()
|
||||
self.s.talon.moveMove(1, self.s.foundations[c.suit], frames=0)
|
||||
for s in self.s.foundations:
|
||||
s.cap.base_rank = c.rank
|
||||
self.s.talon.dealRow(rows=self.s.reserves, frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards()
|
||||
|
||||
def updateText(self):
|
||||
if self.preview > 1:
|
||||
return
|
||||
base_rank = self.base_rank
|
||||
if base_rank == ANY_RANK:
|
||||
t = ''
|
||||
else:
|
||||
t = RANKS[base_rank]
|
||||
self.texts.info.config(text=t)
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.base_rank = game.loadinfo.base_rank
|
||||
for s in self.s.foundations:
|
||||
s.cap.base_rank = self.base_rank
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(base_rank=None) # register extra load var.
|
||||
self.loadinfo.base_rank = p.load()
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
p.dump(self.base_rank)
|
||||
|
||||
shallHighlightMatch = Game._shallHighlightMatch_ACW
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(141, DerKatzenschwanz, "Cat's Tail",
|
||||
GI.GT_FREECELL | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL,
|
||||
|
@ -488,6 +596,8 @@ registerGame(GameInfo(612, Glencoe, "Glencoe",
|
|||
registerGame(GameInfo(616, LaggardLady, "Laggard Lady",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED,
|
||||
rules_filename="intrigue.html"))
|
||||
registerGame(GameInfo(624, StepUp, "Step-Up",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -730,7 +730,6 @@ class AnnoDomini(Numerica):
|
|||
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(257, Numerica, "Numerica",
|
||||
GI.GT_NUMERICA | GI.GT_CONTRIB, 1, 0, GI.SL_BALANCED,
|
||||
|
|
|
@ -169,6 +169,161 @@ class BoxKite(StHelena):
|
|||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Les Quatre Coins
|
||||
# ************************************************************************/
|
||||
|
||||
class LesQuatreCoins_RowStack(UD_RK_RowStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not UD_RK_RowStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
return len(self.game.s.talon.cards) == 0
|
||||
|
||||
|
||||
class LesQuatreCoins_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 not self.cards:
|
||||
RedealTalonStack.redealCards(self, sound=0)
|
||||
if sound and not self.game.demo:
|
||||
self.game.startDealSample()
|
||||
rows = self.game.s.rows
|
||||
rows = rows[:1]+rows[4:8]+(rows[2],rows[1])+rows[8:]+rows[3:4]
|
||||
num_cards = self.dealRowAvail(rows=rows)
|
||||
if sound and not self.game.demo:
|
||||
self.game.stopSamples()
|
||||
return num_cards
|
||||
|
||||
|
||||
class LesQuatreCoins_Foundation(SS_FoundationStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not SS_FoundationStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
if not self.cards:
|
||||
return True
|
||||
if self.game.s.talon.cards:
|
||||
if from_stack in self.game.s.rows[4:]:
|
||||
i = list(self.game.s.foundations).index(self)
|
||||
j = list(self.game.s.rows).index(from_stack)
|
||||
return i == j-4
|
||||
return True
|
||||
|
||||
|
||||
class LesQuatreCoins(Game):
|
||||
Hint_Class = CautiousDefaultHint
|
||||
|
||||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+7*l.XS, l.YM+5*l.YS)
|
||||
|
||||
for i, j in ((0,0),(5,0),(0,4),(5,4)):
|
||||
x, y = l.XM+l.XS+i*l.XS, l.YM+j*l.YS
|
||||
stack = LesQuatreCoins_RowStack(x, y, self,
|
||||
max_move=1, base_rank=NO_RANK)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
for x in (l.XM+2*l.XS, l.XM+5*l.XS):
|
||||
y = l.YM+l.YS/2
|
||||
for j in range(4):
|
||||
stack = LesQuatreCoins_RowStack(x, y, self,
|
||||
max_move=1, base_rank=NO_RANK)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
y += l.YS
|
||||
x, y = l.XM+3*l.XS, l.YM+l.YS/2
|
||||
for i in range(4):
|
||||
s.foundations.append(LesQuatreCoins_Foundation(x, y, self, suit=i))
|
||||
y += l.YS
|
||||
x, y = l.XM+4*l.XS, l.YM+l.YS/2
|
||||
for i in range(4):
|
||||
s.foundations.append(LesQuatreCoins_Foundation(x, y, self, suit=i,
|
||||
base_rank=KING, dir=-1))
|
||||
y += l.YS
|
||||
|
||||
x, y = l.XM, l.YM+2*l.YS
|
||||
s.talon = LesQuatreCoins_Talon(x, y, 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)
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealCards()
|
||||
|
||||
shallHighlightMatch = Game._shallHighlightMatch_RK
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Regal Family
|
||||
# ************************************************************************/
|
||||
|
||||
class RegalFamily_RowStack(UD_SS_RowStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not UD_SS_RowStack.acceptsCards(self, from_stack, cards):
|
||||
return False
|
||||
return len(self.game.s.talon.cards) == 0
|
||||
|
||||
|
||||
class RegalFamily(Game):
|
||||
Hint_Class = CautiousDefaultHint
|
||||
|
||||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+8*l.XS, l.YM+5*l.YS)
|
||||
|
||||
for i, j in ((0,0),(1,0),(2,0),(3,0),(4,0),(5,0),(6,0),
|
||||
(6,1),(6,2),(6,3),
|
||||
(6,4),(5,4),(4,4),(3,4),(2,4),(1,4),(0,4),
|
||||
(0,3),(0,2),(0,1)
|
||||
):
|
||||
x, y = l.XM+l.XS+i*l.XS, l.YM+j*l.YS
|
||||
stack = RegalFamily_RowStack(x, y, self,
|
||||
max_move=1, base_rank=NO_RANK)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
|
||||
x, y = l.XM+3*l.XS, l.YM+l.YS
|
||||
for i in range(3):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i,
|
||||
base_rank=9, mod=13, dir=-1))
|
||||
s.foundations.append(SS_FoundationStack(x, y+2*l.YS, self, suit=i,
|
||||
base_rank=9, mod=13, dir=-1))
|
||||
x += l.XS
|
||||
x, y = l.XM+3*l.XS, l.YM+2*l.YS
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=3,
|
||||
base_rank=ACE, mod=13))
|
||||
x += 2*l.XS
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=3,
|
||||
base_rank=JACK, mod=13, dir=-1))
|
||||
|
||||
x, y = l.XM, l.YM+2*l.YS
|
||||
s.talon = DealRowTalonStack(x, y, self)
|
||||
l.createText(s.talon, 's')
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
|
||||
shallHighlightMatch = Game._shallHighlightMatch_SS
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(302, StHelena, "St. Helena",
|
||||
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED,
|
||||
|
@ -177,4 +332,8 @@ registerGame(GameInfo(302, StHelena, "St. Helena",
|
|||
))
|
||||
registerGame(GameInfo(408, BoxKite, "Box Kite",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(620, LesQuatreCoins, "Les Quatre Coins",
|
||||
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(621, RegalFamily, "Regal Family",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
|
||||
|
|
|
@ -60,10 +60,12 @@ class FindCardDialog(Tkinter.Toplevel):
|
|||
self.images_dir = os.path.join(dir, 'small-emblems')
|
||||
self.label_width, self.label_height = SMALL_EMBLEMS_SIZE
|
||||
self.canvas = MfxCanvas(self, bg='white')
|
||||
##self.canvas = MfxCanvas(self, bg='black')
|
||||
self.canvas.pack(expand=True, fill='both')
|
||||
#
|
||||
self.groups = []
|
||||
self.highlight_items = None
|
||||
self.busy = False
|
||||
self.connectGame(game)
|
||||
#
|
||||
bind(self, "WM_DELETE_WINDOW", self.destroy)
|
||||
|
@ -83,7 +85,7 @@ class FindCardDialog(Tkinter.Toplevel):
|
|||
im = FindCardDialog.CARD_IMAGES.get((rank, suit))
|
||||
if im is None:
|
||||
r = '%02d' % (rank+1)
|
||||
s = 'csdh'[suit]
|
||||
s = 'cshd'[suit]
|
||||
fn = os.path.join(dir, r+s+'.gif')
|
||||
im = makeImage(file=fn)
|
||||
FindCardDialog.CARD_IMAGES[(rank, suit)] = im
|
||||
|
@ -91,22 +93,22 @@ class FindCardDialog(Tkinter.Toplevel):
|
|||
cim.addtag(group)
|
||||
cim.lower()
|
||||
#
|
||||
## rect_width = 4
|
||||
## x1, y1 = x0+dx, y0+dy
|
||||
## rect = MfxCanvasRectangle(self.canvas, x0, y0, x1, y1,
|
||||
## width=rect_width,
|
||||
## fill=None,
|
||||
## outline='red',
|
||||
## state='hidden')
|
||||
## rect.addtag(group)
|
||||
rect = None
|
||||
rect_width = 4
|
||||
x1, y1 = x0+dx, y0+dy
|
||||
rect = MfxCanvasRectangle(self.canvas, x0+1, y0+1, x1-1, y1-1,
|
||||
width=rect_width,
|
||||
fill=None,
|
||||
outline='red',
|
||||
state='hidden'
|
||||
)
|
||||
rect.addtag(group)
|
||||
#
|
||||
bind(group, '<Enter>',
|
||||
lambda e, suit=suit, rank=rank, rect=rect:
|
||||
self.enterEvent(suit, rank, rect))
|
||||
self.enterEvent(suit, rank, rect, group))
|
||||
bind(group, '<Leave>',
|
||||
lambda e, suit=suit, rank=rank, rect=rect:
|
||||
self.leaveEvent(suit, rank, rect))
|
||||
self.leaveEvent(suit, rank, rect, group))
|
||||
self.groups.append(group)
|
||||
|
||||
def connectGame(self, game):
|
||||
|
@ -129,28 +131,36 @@ class FindCardDialog(Tkinter.Toplevel):
|
|||
w, h = dx*j+2, dy*i+2
|
||||
self.canvas.config(width=w, height=h)
|
||||
|
||||
def enterEvent(self, suit, rank, rect):
|
||||
##print 'enterEvent', suit, rank
|
||||
def enterEvent(self, suit, rank, rect, group):
|
||||
##print 'enterEvent', suit, rank, self.busy
|
||||
if self.busy: return
|
||||
self.busy = True
|
||||
self.highlight_items = self.game.highlightCard(suit, rank)
|
||||
if not self.highlight_items:
|
||||
self.highlight_items = []
|
||||
if self.highlight_items:
|
||||
self.timer = after(self, self.normal_timeout, self.timeoutEvent)
|
||||
return
|
||||
rect.config(state='normal')
|
||||
self.canvas.update_idletasks()
|
||||
self.busy = False
|
||||
|
||||
def leaveEvent(self, suit, rank, rect):
|
||||
##print 'leaveEvent', suit, rank
|
||||
def leaveEvent(self, suit, rank, rect, group):
|
||||
##print 'leaveEvent', suit, rank, self.busy
|
||||
if self.busy: return
|
||||
self.busy = True
|
||||
if self.highlight_items:
|
||||
for i in self.highlight_items:
|
||||
i.delete()
|
||||
#self.game.canvas.update_idletasks()
|
||||
#self.canvas.update_idletasks()
|
||||
self.highlight_items = []
|
||||
if self.timer:
|
||||
after_cancel(self.timer)
|
||||
self.timer = None
|
||||
return
|
||||
rect.config(state='hidden')
|
||||
if self.game.canvas:
|
||||
self.game.canvas.update_idletasks()
|
||||
self.canvas.update_idletasks()
|
||||
self.busy = False
|
||||
|
||||
|
||||
def timeoutEvent(self, *event):
|
||||
if self.highlight_items:
|
||||
|
@ -174,6 +184,9 @@ class FindCardDialog(Tkinter.Toplevel):
|
|||
after_cancel(self.timer)
|
||||
self.timer = None
|
||||
self.wm_withdraw()
|
||||
if self.highlight_items:
|
||||
for i in self.highlight_items:
|
||||
i.delete()
|
||||
Tkinter.Toplevel.destroy(self)
|
||||
|
||||
|
||||
|
@ -203,3 +216,4 @@ def destroy_find_card_dialog():
|
|||
pass
|
||||
find_card_dialog = None
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue