From bd3e3cd0837f693024f157e58c8947eafac6ce9e Mon Sep 17 00:00:00 2001 From: Joe R Date: Sat, 21 Aug 2021 19:53:00 -0400 Subject: [PATCH] Added Racing Aces game. --- html-src/rules/acesandkings.html | 12 ++--- html-src/rules/racingaces.html | 29 +++++++++++ pysollib/gamedb.py | 4 +- pysollib/games/acesandkings.py | 83 ++++++++++++++++++++++++-------- 4 files changed, 101 insertions(+), 27 deletions(-) create mode 100644 html-src/rules/racingaces.html diff --git a/html-src/rules/acesandkings.html b/html-src/rules/acesandkings.html index 1f18d482..bf7c1d0a 100644 --- a/html-src/rules/acesandkings.html +++ b/html-src/rules/acesandkings.html @@ -12,14 +12,14 @@ The four leftmost foundations are built up from ace to king, while the four foundations on the right are built down from king to ace.

-There are two thirteen card reserves, along with four talon piles. +There are two thirteen card reserves, along with four tableau piles. The topmost card of the reserve may be moved to any appropriate -foundation, as may any of the talon cards. No building is allowed -on the talon, and if a talon card is moved, it is replaced from -the top of the stock. +foundation, as may any of the tableau cards. No building is allowed +on the tableau, and if a tableau card is moved, it is replaced from +the top of the talon.

-Cards are dealt from the stock one at a time. No redeal is allowed. -When the stock is empty, any card can be moved to an empty tableau +Cards are dealt from the talon one at a time. No redeal is allowed. +When the talon is empty, any card can be moved to an empty tableau pile.

Strategy

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

Racing Aces

+

+Three-Deck game type. 3 decks. No redeal. + +

Object

+

+Move all the cards to the foundations. + +

Quick Description

+

+Racing Aces is a three deck variation of +Aces and Kings. + +

Rules

+

+There are four sets of four foundations. The first set is built up +from ace to king, the second set is built down from king to ace, the +third set is built up from seven to king, and the last set is built +down from six to ace. +

+There are three thirteen card reserves, along with six tableau piles. +The topmost card of the reserve may be moved to any appropriate +foundation, as may any of the tableau cards. No building is allowed +on the tableau, and if a tableau card is moved, it is replaced from +the top of the talon. +

+Cards are dealt from the talon one at a time. No redeal is allowed. +When the talon is empty, any card can be moved to an empty tableau +pile. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 0394e5ea..230c80d0 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -348,7 +348,7 @@ class GI: ("Bill Taylor", (349,)), ("Thomas Warfield", (189, 264, 300, 320, 336, 337, 359, 415, 427, 458, 495, 496, 497, 508, - 800, 814)), + 800, 814, 820)), ) GAMES_BY_PYSOL_VERSION = ( @@ -423,7 +423,7 @@ class GI: ('fc-2.8', (343001,)), ('fc-2.12', tuple(range(774, 811)) + (16681,) + tuple(range(22217, 22219))), - ('fc-2.14', tuple(range(811, 820))) + ('fc-2.14', tuple(range(811, 821))) ) # deprecated - the correct way is to or a GI.GT_XXX flag diff --git a/pysollib/games/acesandkings.py b/pysollib/games/acesandkings.py index b19c6fd2..9bab711c 100644 --- a/pysollib/games/acesandkings.py +++ b/pysollib/games/acesandkings.py @@ -24,13 +24,14 @@ from pysollib.game import Game from pysollib.gamedb import GI, GameInfo, registerGame from pysollib.layout import Layout +from pysollib.pysoltk import MfxCanvasText from pysollib.stack import \ BasicRowStack, \ OpenStack, \ RK_FoundationStack, \ WasteStack, \ WasteTalonStack -from pysollib.util import ACE, KING +from pysollib.util import ACE, KING, RANKS # ************************************************************************ @@ -42,50 +43,82 @@ class AcesAndKings_RowStack(BasicRowStack): return len(cards) == 1 and len(self.cards) == 0 +class AcesAndKings_FoundationStack(RK_FoundationStack): + getBottomImage = RK_FoundationStack._getReserveBottomImage + + class AcesAndKings(Game): + NUM_RESERVES = 2 + NUM_TABLEAU = 4 + FOUNDATION_SETS = ((ACE, KING),) + # # game layout # - def createGame(self, rows=4, max_rounds=1, num_deal=1): + def createGame(self, max_rounds=1, num_deal=1): # create layout l, s = Layout(self), self.s # set window - self.setSize(l.XM + (8.5 * l.XS), l.YM + (3 * l.YS)) + self.setSize(l.XM + (8.5 * l.XS), l.YM + + ((2 + len(self.FOUNDATION_SETS)) * l.YS)) # create stacks - x, y = l.XM, l.YM + x, y = 2 * l.XM, l.YM - w1, w2 = 4 * l.XS + l.XM, 2 * l.XS + w1, w2 = (10 * (l.XS + l.XM)) / self.NUM_RESERVES, 2 * l.XS if w2 + 13 * l.XOFFSET > w1: l.XOFFSET = int((w1 - w2) / 13) - for i in range(2): + for i in range(self.NUM_RESERVES): stack = OpenStack(x, y, self) stack.CARD_XOFFSET = l.XOFFSET l.createText(stack, "sw") s.reserves.append(stack) - x += 4.5 * l.XS + x += (9 / self.NUM_RESERVES) * l.XS x, y = l.XM, y + l.YS - for i in range(4): - s.foundations.append(RK_FoundationStack(x, y, self, suit=i, - base_rank=ACE, dir=1)) - x = x + l.XS - x = x + (l.XS / 2) - for i in range(4): - s.foundations.append(RK_FoundationStack(x, y, self, suit=i, - base_rank=KING, dir=-1)) - x = x + l.XS - x, y = l.XM + l.XS, y + l.YS + + font = self.app.getFont("canvas_default") + + for i in self.FOUNDATION_SETS: + for j in range(4): + stack = AcesAndKings_FoundationStack(x, y, self, suit=j, + base_rank=i[0], dir=1, + max_cards=(13 - i[0])) + stack.texts.misc = MfxCanvasText(self.canvas, + x + l.CW // 2, + y + l.CH // 2, + anchor="center", + font=font) + stack.texts.misc.config(text=(RANKS[i[0]][0])) + s.foundations.append(stack) + + x = x + l.XS + x = x + (l.XS / 2) + for j in range(4): + stack = AcesAndKings_FoundationStack(x, y, self, suit=j, + base_rank=i[1], dir=-1, + max_cards=(i[1] + 1)) + stack.texts.misc = MfxCanvasText(self.canvas, + x + l.CW // 2, + y + l.CH // 2, + anchor="center", + font=font) + stack.texts.misc.config(text=(RANKS[i[1]][0])) + s.foundations.append(stack) + + x = x + l.XS + x, y = l.XM, y + l.YS + x += (2.5 * l.XM) s.talon = WasteTalonStack( x, y, self, max_rounds=max_rounds, num_deal=num_deal) l.createText(s.talon, "sw") x = x + l.XS s.waste = WasteStack(x, y, self) l.createText(s.waste, "se", text_format="%D") - x += 2.5 * l.XS - for i in range(rows): + x = ((8.5 - self.NUM_TABLEAU) * l.XS) + l.XM + for i in range(self.NUM_TABLEAU): s.rows.append(AcesAndKings_RowStack(x, y, self, max_accept=1)) x = x + l.XS @@ -120,8 +153,20 @@ class AceyAndKingsley(AcesAndKings): AcesAndKings.startGame(self) +# ************************************************************************ +# * Racing Aces +# ************************************************************************ + +class RacingAces(AcesAndKings): + NUM_RESERVES = 3 + NUM_TABLEAU = 6 + FOUNDATION_SETS = ((ACE, KING), (6, 5)) + + # register the game registerGame(GameInfo(800, AcesAndKings, "Aces and Kings", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(814, AceyAndKingsley, "Acey and Kingsley", GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(820, RacingAces, "Racing Aces", + GI.GT_3DECK_TYPE, 3, 0, GI.SL_BALANCED))