diff --git a/html-src/rules/germanclock.html b/html-src/rules/germanclock.html new file mode 100644 index 00000000..a024e5c1 --- /dev/null +++ b/html-src/rules/germanclock.html @@ -0,0 +1,25 @@ +
+One-Deck game type. 1 deck. 1 redeal. + +
+Move all cards to the tableau. + +
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. +
+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. + +
+German Clock is more commonly known as The Clock. It is not to be +confused with another game by that same name. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 46a15db1..e4e35cac 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -479,7 +479,8 @@ class GI: ('fc-2.8', (343001,)), ('fc-2.12', tuple(range(774, 811)) + (16681,) + 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 diff --git a/pysollib/games/grandfathersclock.py b/pysollib/games/grandfathersclock.py index 6ffebbb7..9a2eb06a 100644 --- a/pysollib/games/grandfathersclock.py +++ b/pysollib/games/grandfathersclock.py @@ -25,19 +25,22 @@ from pysollib.game import Game from pysollib.gamedb import GI, GameInfo, registerGame from pysollib.hint import CautiousDefaultHint, DefaultHint from pysollib.layout import Layout +from pysollib.pysoltk import MfxCanvasText from pysollib.stack import \ - AC_FoundationStack, \ - BasicRowStack, \ - DealRowTalonStack, \ - InitialDealTalonStack, \ - InvisibleStack, \ - RK_RowStack, \ - SC_RowStack, \ - SS_FoundationStack, \ - SS_RowStack, \ - WasteStack, \ - WasteTalonStack -from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN + AC_FoundationStack, \ + AC_RowStack, \ + BasicRowStack, \ + DealRowTalonStack, \ + InitialDealTalonStack, \ + InvisibleStack, \ + RK_RowStack, \ + SC_RowStack, \ + SS_FoundationStack, \ + SS_RowStack, \ + StackWrapper, \ + WasteStack, \ + WasteTalonStack +from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN, RANKS class GrandfathersClock_Hint(CautiousDefaultHint): @@ -479,6 +482,7 @@ class BigBen(Game): # ************************************************************************ class Clock_RowStack(RK_RowStack): + getBottomImage = RK_RowStack._getReserveBottomImage def _numFaceDown(self): ncards = 0 @@ -538,6 +542,10 @@ class Clock_RowStack(RK_RowStack): class Clock(Game): + RowStack_Class = Clock_RowStack + Talon_Class = InitialDealTalonStack + + HAS_WASTE = False def createGame(self): # create layout @@ -546,9 +554,14 @@ class Clock(Game): # set window dx = l.XS + 3*l.XOFFSET 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) + font = self.app.getFont("canvas_default") + # create stacks + row_rank = 0 for xx, yy in ( (3.25, 0.15), (4.25, 0.5), @@ -565,26 +578,53 @@ class Clock(Game): ): x = l.XM + xx*dx 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.SHRINK_FACTOR = 1 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 - 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.SHRINK_FACTOR = 1 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 - s.talon = InitialDealTalonStack(x, y, self) + if self.HAS_WASTE: + 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 s.internals.append(InvisibleStack(self)) s.internals.append(InvisibleStack(self)) # default - l.defaultAll() + l.defaultStackGroups() def startGame(self): for i in range(3): @@ -607,6 +647,43 @@ class Clock(Game): 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 registerGame(GameInfo(261, GrandfathersClock, "Grandfather's Clock", 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", GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK, altnames=("Travellers",))) +registerGame(GameInfo(827, GermanClock, "German Clock", + GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK))