From 713f498068a9ba5d019758ebe79412598f36c556 Mon Sep 17 00:00:00 2001 From: Joe R Date: Sat, 16 Mar 2024 14:52:10 -0400 Subject: [PATCH] Added Ninety-One game. --- html-src/rules/ninetyone.html | 23 +++++++++ po/de_pysol.po | 3 ++ po/fr_pysol.po | 3 ++ po/it_pysol.po | 3 ++ po/pl_pysol.po | 3 ++ po/pt_BR_pysol.po | 3 ++ po/pysol.pot | 3 ++ po/ru_pysol.po | 3 ++ pysollib/gamedb.py | 2 +- pysollib/games/numerica.py | 90 +++++++++++++++++++++++++++++++++++ pysollib/stack.py | 2 +- 11 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 html-src/rules/ninetyone.html diff --git a/html-src/rules/ninetyone.html b/html-src/rules/ninetyone.html new file mode 100644 index 00000000..582ba04d --- /dev/null +++ b/html-src/rules/ninetyone.html @@ -0,0 +1,23 @@ +

Ninety-One

+

+One-Deck game type. 1 deck. No redeal. + +

Object

+

+Remove all the cards. + +

Rules

+

+The deck is dealt evenly to thirteen piles. Single cards may be moved +between piles without restriction. If the total rank of the top cards +of all thirteen piles totals 91 (kings are 13, queens are 12, jacks +are 11), those cards are removed. +

+The game is won if you can remove all cards in four groups of 91. + +

Notes

+

+Autodrop is disabled for this game. +

+The ranks of a full sequence of cards, from ace to king, will total 91. +But there are other possible sequences too. diff --git a/po/de_pysol.po b/po/de_pysol.po index bc44bfd5..95e02316 100644 --- a/po/de_pysol.po +++ b/po/de_pysol.po @@ -1266,6 +1266,9 @@ msgstr[1] "%d Wiederholungen" msgid "Talon." msgstr "Talon." +msgid "Reserve." +msgstr "Reserve." + #: pysollib/stack.py:2228 pysollib/stack.py:2992 msgid "Reserve. No building." msgstr "Reserve. Nicht aufgebaut." diff --git a/po/fr_pysol.po b/po/fr_pysol.po index 8b790e2b..f3cc0590 100644 --- a/po/fr_pysol.po +++ b/po/fr_pysol.po @@ -1296,6 +1296,9 @@ msgstr[1] "%d donnes" msgid "Talon." msgstr "Talon." +msgid "Reserve." +msgstr "Réserve." + #: pysollib/stack.py:2228 pysollib/stack.py:2992 msgid "Reserve. No building." msgstr "Réserve. Aucun empilement." diff --git a/po/it_pysol.po b/po/it_pysol.po index 3d5f1b39..e870d309 100644 --- a/po/it_pysol.po +++ b/po/it_pysol.po @@ -2420,6 +2420,9 @@ msgstr "" "Tableau: Decrescente per colore. Sequenze di carte dello stesso seme possono " "essere spostate in gruppo" +msgid "Reserve." +msgstr "Riserva." + #: pysollib/games/klondike.py:461 msgid "Reserve. Only Kings are acceptable." msgstr "Riserva. Accetta solo i Re" diff --git a/po/pl_pysol.po b/po/pl_pysol.po index 5d86fa13..03309b5e 100644 --- a/po/pl_pysol.po +++ b/po/pl_pysol.po @@ -1303,6 +1303,9 @@ msgstr[2] "%d rozdań" msgid "Talon." msgstr "Stos wyjściowy." +msgid "Reserve." +msgstr "Stos rezerwowy." + #: pysollib/stack.py:2228 pysollib/stack.py:2992 msgid "Reserve. No building." msgstr "Stos rezerwowy. Nie układaj." diff --git a/po/pt_BR_pysol.po b/po/pt_BR_pysol.po index f763cc13..f62697d3 100644 --- a/po/pt_BR_pysol.po +++ b/po/pt_BR_pysol.po @@ -1295,6 +1295,9 @@ msgstr[1] "%d redistribuições" msgid "Talon." msgstr "Monte" +msgid "Reserve." +msgstr "Reservar." + #: pysollib/stack.py:2228 pysollib/stack.py:2992 msgid "Reserve. No building." msgstr "Reservar. Sem construção." diff --git a/po/pysol.pot b/po/pysol.pot index bd7e89fb..ab088b2f 100644 --- a/po/pysol.pot +++ b/po/pysol.pot @@ -2258,6 +2258,9 @@ msgid "" "moved as a unit." msgstr "" +msgid "Reserve." +msgstr "" + #: pysollib/games/klondike.py:461 msgid "Reserve. Only Kings are acceptable." msgstr "" diff --git a/po/ru_pysol.po b/po/ru_pysol.po index 1370ac91..a7660975 100644 --- a/po/ru_pysol.po +++ b/po/ru_pysol.po @@ -1293,6 +1293,9 @@ msgstr[2] "%d пересдач" msgid "Talon." msgstr "Колода." +msgid "Reserve." +msgstr "Резерв." + #: pysollib/stack.py:2228 pysollib/stack.py:2992 msgid "Reserve. No building." msgstr "Резерв. Без выкладывания." diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 45524ca2..1f699356 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -598,7 +598,7 @@ class GI: ('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, 958)) + tuple(range(11017, 11020)) + + ('dev', tuple(range(906, 959)) + tuple(range(11017, 11020)) + tuple(range(5600, 5624)) + tuple(range(18000, 18005)) + tuple(range(19000, 19012)) + tuple(range(22303, 22311)) + tuple(range(22353, 22361))), diff --git a/pysollib/games/numerica.py b/pysollib/games/numerica.py index 301db0b7..c89caff2 100644 --- a/pysollib/games/numerica.py +++ b/pysollib/games/numerica.py @@ -32,6 +32,7 @@ from pysollib.mygettext import _ from pysollib.pysoltk import MfxCanvasText from pysollib.stack import \ AC_RowStack, \ + AbstractFoundationStack, \ BasicRowStack, \ DealRowTalonStack, \ InitialDealTalonStack, \ @@ -1313,6 +1314,93 @@ class TheBogey(Game): self.s.talon.dealRow(rows=self.s.rows) +# ************************************************************************ +# * Ninety-One +# ************************************************************************ + +class NinetyOne_RowStack(OpenStack): + + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + OpenStack.moveMove(self, ncards, to_stack, frames=frames, + shadow=shadow) + if to_stack in self.game.s.rows: + self.game.checkTotal() + + +class NinetyOne(Game): + Hint_Class = None + + def createGame(self): + # create layout + l, s = Layout(self), self.s + + self.setSize(l.XM + 7 * l.XS, l.YM + 2 * l.YS) + + x, y = l.XM, l.YM + # create stacks + for j in range(7): + s.rows.append(NinetyOne_RowStack(x, y, self, max_move=1, + max_accept=1)) + x += l.XS + x, y = l.XM, l.YM + l.YS + for j in range(6): + s.rows.append(NinetyOne_RowStack(x, y, self, max_move=1, + max_accept=1)) + x += l.XS + + # create text + if self.preview <= 1: + y += l.YS // 2 + self.texts.score = MfxCanvasText( + self.canvas, x, y, anchor="sw", + font=self.app.getFont("canvas_large")) + + x, y = self.getInvisibleCoords() + s.talon = InitialDealTalonStack(x, y, self) + s.foundations.append(AbstractFoundationStack(x, y, self, + max_move=0, + max_accept=0, + suit=ANY_SUIT)) + + # define stack-groups + l.defaultStackGroups() + + def startGame(self): + for i in range(3): + self.s.talon.dealRow(frames=0) + self._startAndDealRow() + + def updateText(self): + if self.preview > 1 or not self.texts.score: + return + self.texts.score.config(text=self.getTotal()) + + def getTotal(self): + total = 0 + for r in self.s.rows: + if len(r.cards) == 0: + continue + total += r.cards[-1].rank + 1 + return total + + def checkTotal(self): + self.updateText() + if self.getTotal() == 91: + for r in self.s.rows: + if len(r.cards) == 0: + return + self.startDealSample() + old_state = self.enterState(self.S_FILL) + for r in self.s.rows: + r.moveMove(1, self.s.foundations[0]) + self.leaveState(old_state) + self.stopSamples() + self.checkTotal() + + def getAutoStacks(self, event=None): + return ((), (), ()) + + # register the game registerGame(GameInfo(257, Numerica, "Numerica", GI.GT_NUMERICA | GI.GT_CONTRIB, 1, 0, GI.SL_BALANCED, @@ -1370,3 +1458,5 @@ registerGame(GameInfo(899, Housefly, "Housefly", GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(931, TheBogey, "The Bogey", GI.GT_1DECK_TYPE, 1, -1, GI.SL_BALANCED)) +registerGame(GameInfo(958, NinetyOne, "Ninety-One", + GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/stack.py b/pysollib/stack.py index a0123ac9..3f47eeb8 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -2294,7 +2294,7 @@ class OpenStack(Stack): def getHelp(self): if self.cap.max_accept == 0: return _('Reserve. No building.') - return '' + return 'Reserve.' # ************************************************************************