diff --git a/html-src/rules/kingsway.html b/html-src/rules/kingsway.html new file mode 100644 index 00000000..0eaaa59e --- /dev/null +++ b/html-src/rules/kingsway.html @@ -0,0 +1,29 @@ +

King's Way

+

+Golf type. 2 decks. 1 redeal. + +

Object

+

+Move all cards except the kings to the waste stack. + +

Rules

+

+Deal the eight kings to eight tableau piles. Then, deal five cards on +top of each king - the bottom-most one face-down and the others face-up. +

+Deal cards from the talon one at a time. You can move cards from the +tableau to build the waste stack up or down by alternate color. Kings +cannot be moved to the waste stack. +

+There is an additional reserve pile. Aces from the waste stack (not the +tableau) may be moved to this reserve. This reserve controls a single +redeal - when the talon is empty, you can take one card from the bottom +of the tableau for each card in the reserve, and use these cards to +build a new talon. You can only do this once. +

+The game is won if all cards are moved to the waste pile, except for the +immovable kings. + +

Notes

+

+Autodrop is disabled for this game. diff --git a/po/de_pysol.po b/po/de_pysol.po index 4cc098a3..24492e4e 100644 --- a/po/de_pysol.po +++ b/po/de_pysol.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: PySol 0.0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 10:00-0400\n" +"PO-Revision-Date: 2024-07-04 17:03-0400\n" "Last-Translator: H. Schaekel \n" "Language-Team: German\n" "Language: de\n" @@ -2367,6 +2367,9 @@ msgstr "Basiskarte - Ass oder König." msgid "Waste. Build up or down regardless of suit." msgstr "Zwischentalon. Hoch oder Runter unabhängig der Farbe zu erstelle." +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/fr_pysol.po b/po/fr_pysol.po index 00341c35..5d0d31b2 100644 --- a/po/fr_pysol.po +++ b/po/fr_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 1.02\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 09:59-0400\n" +"PO-Revision-Date: 2024-07-04 17:03-0400\n" "Last-Translator: Eric Rausch \n" "Language-Team: French\n" "Language: fr\n" @@ -2407,6 +2407,9 @@ msgstr "Carte de départ - As ou Roi." msgid "Waste. Build up or down regardless of suit." msgstr "Défausse. Croissant ou décroissant indépendamment de l'enseigne." +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/it_pysol.po b/po/it_pysol.po index 27d38502..e077362c 100644 --- a/po/it_pysol.po +++ b/po/it_pysol.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: it_pysol\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 09:59-0400\n" +"PO-Revision-Date: 2024-07-04 17:03-0400\n" "Last-Translator: Giuliano Colla \n" "Language-Team: Italiano \n" "Language: it\n" @@ -2415,6 +2415,9 @@ msgstr "Carta Base - Asso o Re" msgid "Waste. Build up or down regardless of suit." msgstr "Pozzo: Sequenza crescente o decrescente indipendentemente dal seme" +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/pl_pysol.po b/po/pl_pysol.po index e5768ebd..bc846de3 100644 --- a/po/pl_pysol.po +++ b/po/pl_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PySolFC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 09:58-0400\n" +"PO-Revision-Date: 2024-07-04 17:03-0400\n" "Last-Translator: Jerzy Trzeciak \n" "Language-Team: Polish \n" "Language: pl\n" @@ -2421,6 +2421,9 @@ msgstr "Karta bazowa - As lub Król." msgid "Waste. Build up or down regardless of suit." msgstr "Zrzut. Układaj w górę lub w dół niezależnie od koloru." +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/pt_BR_pysol.po b/po/pt_BR_pysol.po index bbf8c9c3..623af9ba 100644 --- a/po/pt_BR_pysol.po +++ b/po/pt_BR_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 09:58-0400\n" +"PO-Revision-Date: 2024-07-04 17:04-0400\n" "Last-Translator: Matheus Knack \n" "Language-Team: \n" "Language: pt_BR\n" @@ -2429,6 +2429,9 @@ msgid "Waste. Build up or down regardless of suit." msgstr "" "Descarte. Construa crescente ou descrescente independentemente de naipe." +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/pysol.pot b/po/pysol.pot index 9f527269..ffb30e3c 100644 --- a/po/pysol.pot +++ b/po/pysol.pot @@ -2254,6 +2254,9 @@ msgstr "" msgid "Waste. Build up or down regardless of suit." msgstr "" +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/po/ru_pysol.po b/po/ru_pysol.po index e58ec416..1cab798d 100644 --- a/po/ru_pysol.po +++ b/po/ru_pysol.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2024-06-30 09:58-0400\n" +"PO-Revision-Date: 2024-07-04 17:04-0400\n" "Last-Translator: Skomoroh \n" "Language-Team: Russian \n" "Language: ru\n" @@ -2414,6 +2414,9 @@ msgstr "Базовая карта - Туз или Король." msgid "Waste. Build up or down regardless of suit." msgstr "Сброс. Складывать по возрастанию или убыванию не считаясь с мастью." +msgid "Waste. Build up or down by alternate color." +msgstr "" + #: pysollib/games/klondike.py:125 #, python-format msgid "Balance $%d" diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index e8cb04c1..350ea561 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -604,7 +604,7 @@ class GI: tuple(range(13168, 13170)) + tuple(range(18000, 18005)) + tuple(range(19000, 19012)) + tuple(range(22303, 22311)) + tuple(range(22353, 22361))), - ('dev', tuple(range(961, 965))), + ('dev', tuple(range(961, 966))), ) # deprecated - the correct way is to or a GI.GT_XXX flag diff --git a/pysollib/games/golf.py b/pysollib/games/golf.py index c175af5a..a74d1c72 100644 --- a/pysollib/games/golf.py +++ b/pysollib/games/golf.py @@ -136,8 +136,12 @@ class Golf_RowStack(BasicRowStack): class Golf(Game): Solver_Class = BlackHoleSolverWrapper(preset='golf', base_rank=0, queens_on_kings=True) + Talon_Class = Golf_Talon Waste_Class = Golf_Waste Hint_Class = Golf_Hint + Reserve_Class = None + + ROUNDS = 1 # # game layout @@ -161,13 +165,18 @@ class Golf(Game): x, y = layout.XM + layout.XS // 2, layout.YM for i in range(columns): s.rows.append(Golf_RowStack(x, y, self)) - x = x + layout.XS + x += layout.XS x, y = layout.XM, self.height - layout.YS - s.talon = Golf_Talon(x, y, self, max_rounds=1) + s.talon = self.Talon_Class(x, y, self, max_rounds=self.ROUNDS) layout.createText(s.talon, "n") - x = x + layout.XS + x += layout.XS s.waste = self.Waste_Class(x, y, self) - s.waste.CARD_XOFFSET = layout.XOFFSET + if self.Reserve_Class is None: + s.waste.CARD_XOFFSET = layout.XOFFSET + else: + x += layout.XS + s.reserves.append(self.Reserve_Class(x, y, self)) + layout.createText(s.reserves[0], "n") layout.createText(s.waste, "n") # the Waste is also our only Foundation in this game s.foundations.append(s.waste) @@ -176,6 +185,9 @@ class Golf(Game): self.sg.openstacks = [s.waste] self.sg.talonstacks = [s.talon] self.sg.dropstacks = s.rows + if self.Reserve_Class is not None: + self.sg.openstacks += s.reserves + self.sg.reservestacks = s.reserves # # game overrides @@ -228,7 +240,9 @@ class Thieves(Golf): # ************************************************************************ -# * +# * Dead King Golf +# * Relaxed Golf +# * Double Putt # ************************************************************************ class DeadKingGolf(Golf): @@ -259,6 +273,110 @@ class DoublePutt(DoubleGolf): shallHighlightMatch = Game._shallHighlightMatch_RKW +# ************************************************************************ +# * King's Way +# ************************************************************************ + +class KingsWay_Talon(Golf_Talon): + def _redeal(self): + game = self.game + num_redeal = len(game.s.reserves[0].cards) + # TODO: I know there's a better way to do this. + while len(game.s.waste.cards) > 0: + game.moveMove(1, self.waste, game.s.reserves[0], frames=0) + for i in range(num_redeal): + game.moveMove(1, game.s.reserves[0], self, frames=0) + if self.cards[-1].face_up: + game.flipMove(self) + while len(game.s.reserves[0].cards) > num_redeal: + game.moveMove(1, game.s.reserves[0], self.waste, frames=0) + self.game.nextRoundMove(self) + self.dealCards() + + def canDealCards(self): + return (len(self.cards) > 0 + or (self.round == 1 and len(self.cards) == 0 + and len(self.game.s.reserves[0].cards) > 0)) + + def dealCards(self, sound=False): + if self.cards: + return WasteTalonStack.dealCards(self, sound=sound) + if sound: + self.game.startDealSample() + self._redeal() + if sound: + self.game.stopSamples() + return + + +class KingsWay_Waste(Golf_Waste): + + def __init__(self, x, y, game, **cap): + kwdefault(cap, max_move=1, max_accept=1) + WasteStack.__init__(self, x, y, game, **cap) + + def acceptsCards(self, from_stack, cards): + if self.cards[-1].color == cards[0].color: + return False + if cards[0].rank == KING: + return False + return Golf_Waste.acceptsCards(self, from_stack, cards) + + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + WasteStack.moveMove(self, ncards, to_stack, frames=frames, + shadow=shadow) + self.game.s.talon.dealCards() + + def rightclickHandler(self, event): + if self.cards and self.cards[-1].rank == ACE: + self.playMoveMove(1, self.game.s.reserves[0]) + + def getHelp(self): + return _('Waste. Build up or down by alternate color.') + + +class KingsWay_Reserve(ReserveStack): + + def getBottomImage(self): + return self.game.app.images.getLetter(ACE) + + def acceptsCards(self, from_stack, cards): + return from_stack == self.game.s.waste and cards[0].rank == ACE + + +class KingsWay(Golf): + Solver_Class = None + + Talon_Class = KingsWay_Talon + Waste_Class = KingsWay_Waste + Reserve_Class = StackWrapper(KingsWay_Reserve, max_accept=1) + + ROUNDS = 2 + + def createGame(self): + Golf.createGame(self, 8) + + def _shuffleHook(self, cards): + return self._shuffleHookMoveToTop(cards, + lambda c: (c.rank == KING, None)) + + def startGame(self): + self.s.talon.dealRow(rows=self.s.rows, frames=0) + self.s.talon.dealRow(rows=self.s.rows, flip=0, frames=0) + for i in range(2): + self.s.talon.dealRow(rows=self.s.rows, frames=0) + self.startDealSample() + for i in range(2): + self.s.talon.dealRow(rows=self.s.rows) + self.s.talon.dealCards() # deal first card to WasteStack + + def isGameWon(self): + for r in self.s.rows: + if len(r.cards) != 1: + return False + return True + + # ************************************************************************ # * Elevator - Relaxed Golf in a Pyramid layout # ************************************************************************ @@ -1562,3 +1680,5 @@ registerGame(GameInfo(941, BinaryStar, "Binary Star", registerGame(GameInfo(959, DoubleUintah, "Double Uintah", GI.GT_GOLF, 2, UNLIMITED_REDEALS, GI.SL_MOSTLY_LUCK)) +registerGame(GameInfo(965, KingsWay, "King's Way", + GI.GT_GOLF, 2, 1, GI.SL_MOSTLY_LUCK))