From b92debbbfd4cedcd4c11b7e45c0ac9954d63853a Mon Sep 17 00:00:00 2001 From: Joe R Date: Sat, 13 Jul 2024 18:37:24 -0400 Subject: [PATCH] Add Xerxes and Zingara games --- html-src/rules/xerxes.html | 27 ++++++++++ html-src/rules/zingara.html | 15 ++++++ pysollib/gamedb.py | 4 +- pysollib/games/katzenschwanz.py | 89 +++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 html-src/rules/xerxes.html create mode 100644 html-src/rules/zingara.html diff --git a/html-src/rules/xerxes.html b/html-src/rules/xerxes.html new file mode 100644 index 0000000000..9dd4845e26 --- /dev/null +++ b/html-src/rules/xerxes.html @@ -0,0 +1,27 @@ +

Xerxes

+

+Two-Deck game type. 2 stripped decks. No redeal. + +

Object

+

+Move all cards to the foundations. + +

Rules

+

+Xerxes is played with only the nines through kings of each +suit from two decks, plus the aces. The remaining cards are +removed. +

+One nine is dealt to the first foundation pile, and a tableau pile +of cards is dealt underneath it. When each nine is dealt, that is +dealt to the next foundation, and the next tableau pile is started +underneath it, until all cards are dealt. +

+Any card can be moved to an empty tableau pile, but otherwise, no +building on the tableau is allowed. The foundation piles are built +up from nine to king, then ace, regardless of suit. The game is won +if all cards are moved to the foundations. + +

Notes

+

+Autodrop is disabled for this game. diff --git a/html-src/rules/zingara.html b/html-src/rules/zingara.html new file mode 100644 index 0000000000..41086b1cb7 --- /dev/null +++ b/html-src/rules/zingara.html @@ -0,0 +1,15 @@ +

Zingara

+

+Two-Deck game type. 2 stripped decks. No redeal. + +

Object

+

+Move all cards to the foundations. + +

Quick Description

+

+Like Xerxes, +but played with cards from seven through king, plus the aces. +During the initial deal, the sevens are dealt to the foundations, and +if an eight or nine would be dealt that can be played to a foundation, +it is dealt there immediately. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index d57de2407a..6a9afde96b 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -495,7 +495,7 @@ def _callback(gi, gt=game_type): ("Mark Masten", (811,)), ("Albert Morehead and Geoffrey Mott-Smith", (25, 42, 48, 173, 282, 303, 362, 547, 738, - 845)), + 845, 967, 968)), ("Toby Ord", (788,)), ("David Parlett", (64, 98, 294, 338, 654, 796, 812, 844)), ("Joe R.", (938, 960,)), @@ -603,7 +603,7 @@ def _callback(gi, gt=game_type): tuple(range(13168, 13170)) + tuple(range(18000, 18005)) + tuple(range(19000, 19012)) + tuple(range(22303, 22311)) + tuple(range(22353, 22361))), - ('dev', tuple(range(961, 967))), + ('dev', tuple(range(961, 969))), ) # deprecated - the correct way is to or a GI.GT_XXX flag diff --git a/pysollib/games/katzenschwanz.py b/pysollib/games/katzenschwanz.py index 86015d11a7..ae2cf878a2 100644 --- a/pysollib/games/katzenschwanz.py +++ b/pysollib/games/katzenschwanz.py @@ -293,6 +293,8 @@ class SalicLaw(DerKatzenschwanz): max_accept=UNLIMITED_ACCEPTS) ROW_BASE_RANK = KING + DEAL_ALL = False + HEIGHT = 5 # # game layout @@ -302,8 +304,14 @@ def createGame(self): # , rows=9, reserves=8): # create layout l, s = Layout(self), self.s + cols = 10 # set size - self.setSize(l.XM+10*l.XS, l.YM+(5+len(self.Foundation_Classes))*l.YS) + if self.DEAL_ALL: + cols = 8 + + self.setSize(l.XM + cols * l.XS, + l.YM + (self.HEIGHT + + len(self.Foundation_Classes)) * l.YS) # playcards = 4*l.YS // l.YOFFSET @@ -333,8 +341,12 @@ def createGame(self): # , rows=9, reserves=8): stack.CARD_YOFFSET = yoffset s.rows.append(stack) x += l.XS - s.talon = self.Talon_Class(l.XM+9*l.XS, l.YM, self) - l.createText(s.talon, "s") + if self.DEAL_ALL: + x, y = self.getInvisibleCoords() + s.talon = self.Talon_Class(x, y, self) + else: + s.talon = self.Talon_Class(l.XM + 9 * l.XS, l.YM, self) + l.createText(s.talon, "s") # define stack-groups l.defaultStackGroups() @@ -428,6 +440,71 @@ def getQuickPlayScore(self, ncards, from_stack, to_stack): shallHighlightMatch = Game._shallHighlightMatch_RK +# ************************************************************************ +# * Xerxes +# * Zingara +# ************************************************************************ + +class Xerxes_RowStack(OpenStack): + def acceptsCards(self, from_stack, cards): + if len(self.cards) == 0: + return True + return False + + +class Xerxes(SalicLaw): + Talon_Class = InitialDealTalonStack + Foundation_Classes = [ + StackWrapper(RK_FoundationStack, max_move=0, max_cards=6, mod=13) + ] + RowStack_Class = StackWrapper(Xerxes_RowStack, max_move=1) + ROW_BASE_RANK = 8 + DEAL_ALL = True + HEIGHT = 4 + AUTO_DEAL_RANK = 8 + + def startGame(self): + self.startDealSample() + i = -1 + while self.s.talon.cards: + if self.s.talon.cards[-1].rank == self.ROW_BASE_RANK: + i += 1 + self.s.talon.dealRow(rows=[self.s.foundations[i]], frames=4) + else: + played = False + if self.s.talon.cards[-1].rank <= self.AUTO_DEAL_RANK: + for f in range(i + 1): + if self.s.foundations[f].cards[-1].rank == \ + self.s.talon.cards[-1].rank - 1: + self.s.talon.dealRow(rows=[self.s.foundations[f]], + frames=4) + played = True + break + if not played: + self.s.talon.dealRow(rows=[self.s.rows[i]], frames=4) + + def _shuffleHook(self, cards): + for c in cards[:]: + if c.rank == self.ROW_BASE_RANK: + cards.remove(c) + break + cards.append(c) + return cards + + def isGameWon(self): + return Game.isGameWon(self) + + def getAutoStacks(self, event=None): + return ((), (), self.sg.dropstacks) + + +class Zingara(Xerxes): + Foundation_Classes = [ + StackWrapper(RK_FoundationStack, max_move=0, max_cards=8, mod=13) + ] + ROW_BASE_RANK = 6 + + # ************************************************************************ # * Intrigue # * Laggard Lady @@ -752,3 +829,9 @@ def startGame(self): registerGame(GameInfo(766, Kentish, "Kentish", GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) +registerGame(GameInfo(967, Xerxes, "Xerxes", + GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_STRIPPED, 2, 0, + GI.SL_BALANCED, ranks=(0, 8, 9, 10, 11, 12),)) +registerGame(GameInfo(968, Zingara, "Zingara", + GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_STRIPPED, 2, 0, + GI.SL_BALANCED, ranks=(0, 6, 7, 8, 9, 10, 11, 12),))