mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Added German Clock game.
This commit is contained in:
parent
1bc31007c5
commit
2de479320b
3 changed files with 123 additions and 18 deletions
25
html-src/rules/germanclock.html
Normal file
25
html-src/rules/germanclock.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<h1>German Clock</h1>
|
||||||
|
<p>
|
||||||
|
One-Deck game type. 1 deck. 1 redeal.
|
||||||
|
|
||||||
|
<h3>Object</h3>
|
||||||
|
<p>
|
||||||
|
Move all cards to the tableau.
|
||||||
|
|
||||||
|
<h3>Rules</h3>
|
||||||
|
<p>The tableau is dealt in a circle of twelve piles, similar to the
|
||||||
|
twelve numbers on a clock, with a thirteenth pile placed in the middle.
|
||||||
|
Each pile represents cards of the number in that position on a clock,
|
||||||
|
with Jacks in the 11 o'clock pile and queens in the 12 o'clock pile.
|
||||||
|
Kings go in the middle.
|
||||||
|
<p>
|
||||||
|
Deal cards from the stock one at a time. Cards can be moved from the
|
||||||
|
waste pile to the appropriate tableau pile as mentioned above. Tableau
|
||||||
|
piles must be built up by alternate colors, and all of the tableau piles
|
||||||
|
must be built up using the same sequence of suits. One redeal is
|
||||||
|
allowed. The game is won if all cards are moved to the tableau.
|
||||||
|
|
||||||
|
<h3>Notes</h3>
|
||||||
|
<p>
|
||||||
|
German Clock is more commonly known as The Clock. It is not to be
|
||||||
|
confused with <a href="clock.html">another game by that same name.</a>
|
|
@ -479,7 +479,8 @@ class GI:
|
||||||
('fc-2.8', (343001,)),
|
('fc-2.8', (343001,)),
|
||||||
('fc-2.12', tuple(range(774, 811)) + (16681,) +
|
('fc-2.12', tuple(range(774, 811)) + (16681,) +
|
||||||
tuple(range(22217, 22219))),
|
tuple(range(22217, 22219))),
|
||||||
('fc-2.14', tuple(range(811, 827)))
|
('fc-2.14', tuple(range(811, 827))),
|
||||||
|
('fc-2.16', tuple(range(827, 829)))
|
||||||
)
|
)
|
||||||
|
|
||||||
# deprecated - the correct way is to or a GI.GT_XXX flag
|
# deprecated - the correct way is to or a GI.GT_XXX flag
|
||||||
|
|
|
@ -25,19 +25,22 @@ from pysollib.game import Game
|
||||||
from pysollib.gamedb import GI, GameInfo, registerGame
|
from pysollib.gamedb import GI, GameInfo, registerGame
|
||||||
from pysollib.hint import CautiousDefaultHint, DefaultHint
|
from pysollib.hint import CautiousDefaultHint, DefaultHint
|
||||||
from pysollib.layout import Layout
|
from pysollib.layout import Layout
|
||||||
|
from pysollib.pysoltk import MfxCanvasText
|
||||||
from pysollib.stack import \
|
from pysollib.stack import \
|
||||||
AC_FoundationStack, \
|
AC_FoundationStack, \
|
||||||
BasicRowStack, \
|
AC_RowStack, \
|
||||||
DealRowTalonStack, \
|
BasicRowStack, \
|
||||||
InitialDealTalonStack, \
|
DealRowTalonStack, \
|
||||||
InvisibleStack, \
|
InitialDealTalonStack, \
|
||||||
RK_RowStack, \
|
InvisibleStack, \
|
||||||
SC_RowStack, \
|
RK_RowStack, \
|
||||||
SS_FoundationStack, \
|
SC_RowStack, \
|
||||||
SS_RowStack, \
|
SS_FoundationStack, \
|
||||||
WasteStack, \
|
SS_RowStack, \
|
||||||
WasteTalonStack
|
StackWrapper, \
|
||||||
from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN
|
WasteStack, \
|
||||||
|
WasteTalonStack
|
||||||
|
from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN, RANKS
|
||||||
|
|
||||||
|
|
||||||
class GrandfathersClock_Hint(CautiousDefaultHint):
|
class GrandfathersClock_Hint(CautiousDefaultHint):
|
||||||
|
@ -479,6 +482,7 @@ class BigBen(Game):
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
class Clock_RowStack(RK_RowStack):
|
class Clock_RowStack(RK_RowStack):
|
||||||
|
getBottomImage = RK_RowStack._getReserveBottomImage
|
||||||
|
|
||||||
def _numFaceDown(self):
|
def _numFaceDown(self):
|
||||||
ncards = 0
|
ncards = 0
|
||||||
|
@ -538,6 +542,10 @@ class Clock_RowStack(RK_RowStack):
|
||||||
|
|
||||||
|
|
||||||
class Clock(Game):
|
class Clock(Game):
|
||||||
|
RowStack_Class = Clock_RowStack
|
||||||
|
Talon_Class = InitialDealTalonStack
|
||||||
|
|
||||||
|
HAS_WASTE = False
|
||||||
|
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
# create layout
|
# create layout
|
||||||
|
@ -546,9 +554,14 @@ class Clock(Game):
|
||||||
# set window
|
# set window
|
||||||
dx = l.XS + 3*l.XOFFSET
|
dx = l.XS + 3*l.XOFFSET
|
||||||
w = max(5.25*dx + l.XS, 5.5*dx)
|
w = max(5.25*dx + l.XS, 5.5*dx)
|
||||||
|
if self.HAS_WASTE:
|
||||||
|
w += l.XS
|
||||||
self.setSize(l.XM + w, l.YM + 4*l.YS)
|
self.setSize(l.XM + w, l.YM + 4*l.YS)
|
||||||
|
|
||||||
|
font = self.app.getFont("canvas_default")
|
||||||
|
|
||||||
# create stacks
|
# create stacks
|
||||||
|
row_rank = 0
|
||||||
for xx, yy in (
|
for xx, yy in (
|
||||||
(3.25, 0.15),
|
(3.25, 0.15),
|
||||||
(4.25, 0.5),
|
(4.25, 0.5),
|
||||||
|
@ -565,26 +578,53 @@ class Clock(Game):
|
||||||
):
|
):
|
||||||
x = l.XM + xx*dx
|
x = l.XM + xx*dx
|
||||||
y = l.YM + yy*l.YS
|
y = l.YM + yy*l.YS
|
||||||
stack = Clock_RowStack(x, y, self, max_move=0)
|
stack = self.RowStack_Class(x, y, self, max_move=0,
|
||||||
|
base_rank=row_rank)
|
||||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
||||||
stack.SHRINK_FACTOR = 1
|
stack.SHRINK_FACTOR = 1
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
|
if self.preview <= 1:
|
||||||
|
label = RANKS[row_rank][0]
|
||||||
|
if label == "1":
|
||||||
|
label = "10"
|
||||||
|
stack.texts.misc = MfxCanvasText(self.canvas,
|
||||||
|
x + l.CW // 2,
|
||||||
|
y + l.CH // 2,
|
||||||
|
anchor="center",
|
||||||
|
font=font)
|
||||||
|
stack.texts.misc.config(text=label)
|
||||||
|
row_rank += 1
|
||||||
|
|
||||||
x, y = l.XM + 2.25*dx, l.YM + 1.5*l.YS
|
x, y = l.XM + 2.25*dx, l.YM + 1.5*l.YS
|
||||||
stack = Clock_RowStack(x, y, self, max_move=1)
|
stack = self.RowStack_Class(x, y, self, max_move=1, base_rank=row_rank)
|
||||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
||||||
stack.SHRINK_FACTOR = 1
|
stack.SHRINK_FACTOR = 1
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
|
if self.preview <= 1:
|
||||||
|
stack.texts.misc = MfxCanvasText(self.canvas,
|
||||||
|
x + l.CW // 2,
|
||||||
|
y + l.CH // 2,
|
||||||
|
anchor="center",
|
||||||
|
font=font)
|
||||||
|
stack.texts.misc.config(text=(RANKS[row_rank][0]))
|
||||||
|
|
||||||
x, y = self.width - l.XS, self.height - l.YS
|
if self.HAS_WASTE:
|
||||||
s.talon = InitialDealTalonStack(x, y, self)
|
x, y = self.width - (2 * l.XS), self.height - l.YS
|
||||||
|
s.talon = self.Talon_Class(x, y, self)
|
||||||
|
l.createText(s.talon, 'n')
|
||||||
|
x += l.XS
|
||||||
|
s.waste = WasteStack(x, y, self)
|
||||||
|
l.createText(s.waste, 'n')
|
||||||
|
else:
|
||||||
|
x, y = self.width - l.XS, self.height - l.YS
|
||||||
|
s.talon = self.Talon_Class(x, y, self)
|
||||||
|
|
||||||
# create an invisible stacks
|
# create an invisible stacks
|
||||||
s.internals.append(InvisibleStack(self))
|
s.internals.append(InvisibleStack(self))
|
||||||
s.internals.append(InvisibleStack(self))
|
s.internals.append(InvisibleStack(self))
|
||||||
|
|
||||||
# default
|
# default
|
||||||
l.defaultAll()
|
l.defaultStackGroups()
|
||||||
|
|
||||||
def startGame(self):
|
def startGame(self):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
|
@ -607,6 +647,43 @@ class Clock(Game):
|
||||||
return (), (), ()
|
return (), (), ()
|
||||||
|
|
||||||
|
|
||||||
|
# ************************************************************************
|
||||||
|
# * German Clock
|
||||||
|
# ************************************************************************
|
||||||
|
|
||||||
|
class GermanClock_RowStack(AC_RowStack):
|
||||||
|
getBottomImage = AC_RowStack._getReserveBottomImage
|
||||||
|
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
num_cards = len(self.cards)
|
||||||
|
for i in range(13):
|
||||||
|
check_seq = self.game.s.rows[i].cards
|
||||||
|
if len(check_seq) > num_cards:
|
||||||
|
if check_seq[num_cards].suit != cards[0].suit:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return AC_RowStack.acceptsCards(self, from_stack, cards)
|
||||||
|
|
||||||
|
|
||||||
|
class GermanClock(Clock):
|
||||||
|
RowStack_Class = StackWrapper(GermanClock_RowStack, dir=0, max_move=0)
|
||||||
|
Talon_Class = StackWrapper(WasteTalonStack, max_rounds=2)
|
||||||
|
|
||||||
|
HAS_WASTE = True
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def isGameWon(self):
|
||||||
|
for r in self.s.rows:
|
||||||
|
if len(r.cards) < 4:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def getAutoStacks(self, event=None):
|
||||||
|
return Game.getAutoStacks(self, event)
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(261, GrandfathersClock, "Grandfather's Clock",
|
registerGame(GameInfo(261, GrandfathersClock, "Grandfather's Clock",
|
||||||
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_BALANCED))
|
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_BALANCED))
|
||||||
|
@ -620,3 +697,5 @@ registerGame(GameInfo(697, BigBen, "Big Ben",
|
||||||
registerGame(GameInfo(737, Clock, "Clock",
|
registerGame(GameInfo(737, Clock, "Clock",
|
||||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK,
|
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK,
|
||||||
altnames=("Travellers",)))
|
altnames=("Travellers",)))
|
||||||
|
registerGame(GameInfo(827, GermanClock, "German Clock",
|
||||||
|
GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK))
|
||||||
|
|
Loading…
Add table
Reference in a new issue