From ccd250eb1492e8deea8c5ef725888a9d9981b77b Mon Sep 17 00:00:00 2001 From: Joe R Date: Mon, 26 Dec 2022 10:53:25 -0500 Subject: [PATCH] Added Roaming Proils game. --- html-src/rules/roamingproils.html | 28 ++++++++++++++++++++++ pysollib/gamedb.py | 2 +- pysollib/games/fan.py | 40 ++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 html-src/rules/roamingproils.html diff --git a/html-src/rules/roamingproils.html b/html-src/rules/roamingproils.html new file mode 100644 index 00000000..b469b71d --- /dev/null +++ b/html-src/rules/roamingproils.html @@ -0,0 +1,28 @@ +

Roaming Proils

+

+Fan game type. 1 deck. No redeal. + +

Object

+

+Move all cards to the foundations. + +

Rules

+

+Cards are dealt into 17 piles of three cards each, with only the +top card of each pile face-up. The final card is dealt to a +single reserve pile. +

+Tableau piles are built by same rank, but only three consecutive +cards of the same rank are allowed in the same tableau pile. This is +called a proil, and the fourth card of the same rank cannot be moved to +a proil. Empty piles cannot be filled. The reserve card can be moved +to an appropriate tableau pile at any time, but once the reserve is +empty, only a king can be moved to it. +

+The foundations are built up by suit. The game is won if +all cards are moved to the foundations. + +

Notes

+

+The name "Proil" is a distortion of "Pair Royal", which describes +a three-of-a-kind in Cribbage. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 9675f101..2456df8f 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -548,7 +548,7 @@ class GI: tuple(range(22217, 22219))), ('fc-2.14', tuple(range(811, 827))), ('fc-2.15', tuple(range(827, 855)) + tuple(range(22400, 22407))), - ('dev', tuple(range(855, 879))) + ('dev', tuple(range(855, 880))) ) # deprecated - the correct way is to or a GI.GT_XXX flag diff --git a/pysollib/games/fan.py b/pysollib/games/fan.py index e0e14514..a52e556d 100644 --- a/pysollib/games/fan.py +++ b/pysollib/games/fan.py @@ -611,10 +611,10 @@ class BoxFan(Fan): # ************************************************************************ # * Troika +# * Quads # ************************************************************************ class Troika(Fan): - RowStack_Class = StackWrapper(RK_RowStack, dir=0, base_rank=NO_RANK, max_cards=3) @@ -667,6 +667,42 @@ class QuadsPlus(Quads): self.s.talon.dealRow(rows=self.s.rows[:-1]) +# ************************************************************************ +# * Roaming Proils +# ************************************************************************ + +class RoamingProils_RowStack(RK_RowStack): + + def acceptsCards(self, from_stack, cards): + if not RK_RowStack.acceptsCards(self, from_stack, cards): + return False + rank_sequence = 1 + for card in reversed(self.cards): + if card.rank == cards[0].rank and card.face_up: + rank_sequence += 1 + else: + break + + if rank_sequence > 3: + return False + return True + + +class RoamingProils(Fan): + RowStack_Class = StackWrapper(RoamingProils_RowStack, dir=0, + base_rank=NO_RANK) + ReserveStack_Class = StackWrapper(ReserveStack, base_rank=KING) + + def createGame(self): + Fan.createGame(self, rows=(5, 5, 5, 2), playcards=5, reserves=1) + + def startGame(self): + for i in range(2): + self.s.talon.dealRow(rows=self.s.rows[:17], flip=0, frames=0) + self._startAndDealRow() + self.s.talon.dealRow(rows=self.s.reserves) + + # ************************************************************************ # * Fascination Fan # ************************************************************************ @@ -1103,3 +1139,5 @@ registerGame(GameInfo(834, RainbowFan, "Rainbow Fan", GI.GT_FAN_TYPE, 2, 3, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(871, CeilingFan, "Ceiling Fan", GI.GT_FAN_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) +registerGame(GameInfo(879, RoamingProils, "Roaming Proils", + GI.GT_FAN_TYPE, 1, 0, GI.SL_BALANCED))