From 611bd370246130f7a1a5d8eddbb6814cf5266305 Mon Sep 17 00:00:00 2001 From: Joe R Date: Sun, 10 Dec 2023 15:53:41 -0500 Subject: [PATCH] Added The Lucky Number game. --- html-src/rules/theluckynumber.html | 28 ++++++++++ pysollib/gamedb.py | 2 +- pysollib/games/pyramid.py | 86 ++++++++++++++++++++++++++++-- 3 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 html-src/rules/theluckynumber.html diff --git a/html-src/rules/theluckynumber.html b/html-src/rules/theluckynumber.html new file mode 100644 index 000000000..b85d3cbaf --- /dev/null +++ b/html-src/rules/theluckynumber.html @@ -0,0 +1,28 @@ +

The Lucky Number

+

+Pairing game type. 2 decks. No redeal. + +

Object

+

+Move all cards to the single foundation. + +

Rules

+

+Twelve piles of four cards each are dealt to the tableau. Pairs of cards +that total eleven can be moved to the foundation. When there are no moves +left, cards can be dealt from the talon one at a time and paired off with +the tableau cards. When a tableau pile is empty, it is filled from the +top card of the waste, or talon if the waste is empty. +

+Picture cards are removed in a set of Jack, Queen, King. A +single picture card of each type can be moved to the three reserves, +but they must all be discarded at the same time - no further cards +can be dealt from the talon or filled from the waste until a set of +three has been removed. +

+No redeal is allowed. The game is won if all cards have been discarded. + +

Notes

+

+ +Autodrop is disabled for this game. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index da1094820..8175807b1 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -592,7 +592,7 @@ def _callback(gi, gt=game_type): ('fc-2.20', tuple(range(855, 897))), ('fc-2.21', tuple(range(897, 900)) + tuple(range(11014, 11017)) + tuple(range(13160, 13163)) + (16682,)), - ('dev', tuple(range(906, 937)) + tuple(range(11017, 11020)) + + ('dev', tuple(range(906, 938)) + tuple(range(11017, 11020)) + tuple(range(5600, 5624)) + tuple(range(18000, 18005)) + tuple(range(22303, 22311)) + tuple(range(22353, 22361))), ) diff --git a/pysollib/games/pyramid.py b/pysollib/games/pyramid.py index 7a2ea24d5..28344ae3b 100644 --- a/pysollib/games/pyramid.py +++ b/pysollib/games/pyramid.py @@ -538,6 +538,8 @@ class Elevens(Pyramid): RowStack_Class = Elevens_RowStack Reserve_Class = Elevens_Reserve + Talon_Class = AutoDealTalonStack + Waste_Class = None def createGame(self, rows=3, cols=3, reserves=3, maxpiles=-1, texts=False): @@ -552,12 +554,17 @@ def createGame(self, rows=3, cols=3, reserves=3, maxpiles=-1, texts=False): layout.YM + (rows + rp) * layout.YS) x, y = self.width-layout.XS, layout.YM - s.talon = AutoDealTalonStack(x, y, self) - layout.createText(s.talon, 's') + s.talon = self.Talon_Class(x, y, self) + if self.Waste_Class is None: + layout.createText(s.talon, 's') + else: + layout.createText(s.talon, 'nw') + y += layout.YS + s.waste = self.Waste_Class(x, y, self) x, y = self.width-layout.XS, self.height-layout.YS s.foundations.append(AbstractFoundationStack(x, y, self, suit=ANY_SUIT, max_accept=0, - max_move=0, max_cards=52)) + max_move=0, max_cards=52 * self.gameinfo.decks)) layout.createText(s.foundations[0], 'n') y = layout.YM piles = 0 @@ -690,6 +697,77 @@ def createGame(self): Elevens.createGame(self, rows=2, cols=7, maxpiles=13, reserves=4) +# ************************************************************************ +# * The Lucky Number +# ************************************************************************ + +class TheLuckyNumber_Talon(WasteTalonStack): + + def canDealCards(self): + for s in self.game.s.reserves: + if s.cards: + return False + return WasteTalonStack.canDealCards(self) + + +class TheLuckyNumber_Waste(WasteStack): + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + if to_stack in self.game.s.rows and len(to_stack.cards) > 0: + self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow) + else: + self.game.moveMove(ncards, self, to_stack, + frames=frames, shadow=shadow) + self.fillStack() + + def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1): + if not self.game.demo: + self.game.playSample("droppair", priority=200) + if not (n == 1 and other_stack.cards): + return + old_state = self.game.enterState(self.game.S_FILL) + f = self.game.s.foundations[0] + self.game.moveMove(n, self, f, frames=frames, shadow=shadow) + self.game.moveMove(n, other_stack, f, frames=frames, shadow=shadow) + self.game.leaveState(old_state) + other_stack.fillStack() + + +class TheLuckyNumber(Elevens): + Talon_Class = StackWrapper(TheLuckyNumber_Talon, max_rounds=1) + Waste_Class = TheLuckyNumber_Waste + + def createGame(self): + Elevens.createGame(self, cols=4) + + def startGame(self): + for i in range(3): + self.s.talon.dealRow(frames=0) + self._startAndDealRow() + self.s.talon.dealCards() + + def fillStack(self, stack): + old_state = self.enterState(self.S_FILL) + reserves_ncards = 0 + for s in self.s.reserves: + if s.cards: + reserves_ncards += 1 + if reserves_ncards == 0: + for r in self.s.rows: + if not r.cards: + if self.s.waste.cards: + self.s.waste.moveMove(1, r) + elif self.s.talon.cards: + self.s.talon.flipMove() + self.s.talon.moveMove(1, r) + elif reserves_ncards == len(self.s.reserves): + if not self.demo: + self.playSample("droppair", priority=200) + for s in self.s.reserves: + s.moveMove(1, self.s.foundations[0], frames=4) + self.fillStack(stack) + self.leaveState(old_state) + + # ************************************************************************ # * Fifteens # ************************************************************************ @@ -1642,3 +1720,5 @@ def fillStack(self, stack): registerGame(GameInfo(929, EightCards, "Eight Cards", GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK, altnames=('Acht Karten',))) +registerGame(GameInfo(937, TheLuckyNumber, "The Lucky Number", + GI.GT_PAIRING_TYPE, 2, 0, GI.SL_LUCK))