From eebb9ff89469cef3bf0ddad1d4375ac4468d70f8 Mon Sep 17 00:00:00 2001 From: skomoroh Date: Wed, 6 Dec 2006 22:13:05 +0000 Subject: [PATCH] + 3 new games git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@105 efabe8c0-fbe8-4139-b769-b5e6d273206e --- pysollib/games/bisley.py | 80 ++++++++++++++++ pysollib/games/braid.py | 139 ++++++++++++++++++++++++++++ pysollib/games/grandfathersclock.py | 13 ++- pysollib/games/pyramid.py | 3 +- pysollib/games/royalcotillion.py | 107 +++++++++++++++++++++ 5 files changed, 340 insertions(+), 2 deletions(-) diff --git a/pysollib/games/bisley.py b/pysollib/games/bisley.py index e01b1a8f..5748d70c 100644 --- a/pysollib/games/bisley.py +++ b/pysollib/games/bisley.py @@ -32,6 +32,7 @@ from pysollib.stack import * from pysollib.game import Game from pysollib.layout import Layout from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint +from pysollib.pysoltk import MfxCanvasText # /*********************************************************************** @@ -275,6 +276,83 @@ class HospitalPatience(Game): +# /*********************************************************************** +# // Board Patience +# ************************************************************************/ + +class BoardPatience(Game): + Hint_Class = CautiousDefaultHint + + def createGame(self): + + l, s = Layout(self), self.s + self.setSize(l.XM+10*l.XS, l.YM+2*l.YS+12*l.YOFFSET) + + # extra settings + self.base_card = None + + # create stacks + x, y = l.XM+3*l.XS, l.YM + for i in range(4): + s.foundations.append(SS_FoundationStack(x, y, self, + suit=i, mod=13)) + x = x + l.XS + tx, ty, ta, tf = l.getTextAttr(s.foundations[-1], "ne") + font = self.app.getFont("canvas_default") + self.texts.info = MfxCanvasText(self.canvas, tx, ty, + anchor=ta, font=font) + x, y = l.XM, l.YM+l.YS + for i in range(10): + s.rows.append(UD_AC_RowStack(x, y, self, mod=13)) + x += l.XS + + x, y = l.XM, l.YM + s.talon = InitialDealTalonStack(x, y, self) + + # default + l.defaultAll() + + def updateText(self): + if self.preview > 1: + return + if not self.texts.info: + return + if not self.base_card: + t = "" + else: + t = RANKS[self.base_card.rank] + self.texts.info.config(text=t) + + def startGame(self): + # deal base_card to Foundations, update foundations cap.base_rank + self.base_card = self.s.talon.getCard() + for s in self.s.foundations: + s.cap.base_rank = self.base_card.rank + n = self.base_card.suit + self.flipMove(self.s.talon) + self.moveMove(1, self.s.talon, self.s.foundations[n], frames=0) + # deal to rows + for i in range(4): + self.s.talon.dealRow(frames=0) + self.startDealSample() + self.s.talon.dealRow() + self.s.talon.dealRowAvail() + + shallHighlightMatch = Game._shallHighlightMatch_ACW + + def _restoreGameHook(self, game): + self.base_card = self.cards[game.loadinfo.base_card_id] + for s in self.s.foundations: + s.cap.base_rank = self.base_card.rank + + def _loadGameHook(self, p): + self.loadinfo.addattr(base_card_id=None) # register extra load var. + self.loadinfo.base_card_id = p.load() + + def _saveGameHook(self, p): + p.dump(self.base_card.id) + + # register the game registerGame(GameInfo(290, Bisley, "Bisley", GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) @@ -288,4 +366,6 @@ registerGame(GameInfo(375, Mancunian, "Mancunian", GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(686, HospitalPatience, "Hospital Patience", GI.GT_1DECK_TYPE, 1, -1, GI.SL_MOSTLY_LUCK)) +registerGame(GameInfo(692, BoardPatience, "Board Patience", + GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) diff --git a/pysollib/games/braid.py b/pysollib/games/braid.py index 39dae0a9..b4923bd0 100644 --- a/pysollib/games/braid.py +++ b/pysollib/games/braid.py @@ -372,6 +372,143 @@ class BigBraid(Braid): Foundation_Classes = [Braid_Foundation, Braid_Foundation, Braid_Foundation] +# /*********************************************************************** +# // Casket +# ************************************************************************/ + +class Casket_Hint(CautiousDefaultHint): + def computeHints(self): + CautiousDefaultHint.computeHints(self) + if self.hints: + return + if not self.game.s.waste.cards: + return + r = self.game.s.waste.cards[-1].rank + if 0 <= r <= 3: + to_stack = self.game.s.reserves[0] + elif 4 <= r <= 7: + to_stack = self.game.s.reserves[1] + else: + to_stack = self.game.s.reserves[2] + self.addHint(5000, 1, self.game.s.waste, to_stack) + + +class JewelsStack(OpenStack): + def canFlipCard(self): + return False + + +class Casket_RowStack(SS_RowStack): + def getBottomImage(self): + return self.game.app.images.getReserveBottom() + def acceptsCards(self, from_stack, cards): + if not SS_RowStack.acceptsCards(self, from_stack, cards): + return False + if not self.cards: + # don't accepts from lid + return from_stack not in self.game.s.lid + return True + + +class Casket_Reserve(ReserveStack): + def acceptsCards(self, from_stack, cards): + if not ReserveStack.acceptsCards(self, from_stack, cards): + return False + return from_stack is self.game.s.waste + + +class Casket(Game): + Hint_Class = Casket_Hint + + def createGame(self): + # create layout + l, s = Layout(self), self.s + font=self.app.getFont("canvas_default") + + # set window + self.setSize(l.XM+10*l.XS, l.YM+4.5*l.YS) + + + # register extra stack variables + s.addattr(jewels=None) + s.addattr(lid=[]) + + # create stacks + # Lid + x0, y0 = l.XM+2.5*l.XS, l.YM + for xx, yy in ((0, 0.5), + (1, 0.25), + (2, 0), + (3, 0.25), + (4, 0.5), + ): + x, y = x0+xx*l.XS, y0+yy*l.YS + s.lid.append(BasicRowStack(x, y, self, max_accept=0)) + + # Casket + x0, y0 = l.XM+3*l.XS, l.YM+1.5*l.YS + for xx, yy in ((0,0), (3,0), + (0,1), (3,1), + (0,2),(1,2),(2,2),(3,2), + ): + x, y = x0+xx*l.XS, y0+yy*l.YS + stack = Casket_RowStack(x, y, self, max_move=1) + stack.CARD_YOFFSET = 0 + s.rows.append(stack) + + # Reserves + x, y = l.XM, l.YM+1.5*l.YS + for i in range(3): + stack = Casket_Reserve(x, y, self, max_cards=UNLIMITED_CARDS) + l.createText(stack, "ne") + s.reserves.append(stack) + y += l.YS + + # Foundations + x = l.XM+8*l.XS + for i in range(2): + y = l.YM + for j in range(4): + s.foundations.append(SS_FoundationStack(x, y, self, suit=j)) + y += l.YS + x += l.XS + + # Jewels + x, y = l.XM+4.5*l.XS, l.YM+2*l.YS + s.jewels = JewelsStack(x, y, self) + l.createText(s.jewels, "s") + + # waste & talon + x, y = l.XM, l.YM + s.talon = WasteTalonStack(x, y, self, max_rounds=1) + l.createText(s.talon, "s") + x += l.XS + s.waste = WasteStack(x, y, self, max_cards=1) + + # define stack-groups + self.sg.talonstacks = [s.talon] + [s.waste] + self.sg.openstacks = s.foundations + s.rows + s.reserves + self.sg.dropstacks = s.lid + s.rows + [s.waste] + s.reserves + + + def startGame(self): + for i in range(13): + self.s.talon.dealRow(rows=[self.s.jewels], frames=0, flip=0) + self.startDealSample() + self.s.talon.dealToStacksOrFoundations(stacks=self.s.lid) + self.s.talon.dealToStacksOrFoundations(stacks=self.s.rows) + self.s.talon.dealCards() + + def fillStack(self, stack): + if not stack.cards and stack in self.s.lid: + if self.s.jewels.cards: + old_state = self.enterState(self.S_FILL) + self.s.jewels.flipMove() + self.s.jewels.moveMove(1, stack) + self.leaveState(old_state) + + shallHighlightMatch = Game._shallHighlightMatch_SS + # register the game registerGame(GameInfo(12, Braid, "Braid", @@ -388,3 +525,5 @@ registerGame(GameInfo(377, BackbonePlus, "Backbone +", GI.GT_NAPOLEON, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(510, BigBraid, "Big Braid", GI.GT_NAPOLEON | GI.GT_ORIGINAL, 3, 2, GI.SL_BALANCED)) +registerGame(GameInfo(694, Casket, "Casket", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) diff --git a/pysollib/games/grandfathersclock.py b/pysollib/games/grandfathersclock.py index 187fa3bf..1fbf4138 100644 --- a/pysollib/games/grandfathersclock.py +++ b/pysollib/games/grandfathersclock.py @@ -187,6 +187,17 @@ class Dial(Game): BLACK, RED = 0, 1 + +class Hemispheres_Hint(DefaultHint): + def shallMovePile(self, from_stack, to_stack, pile, rpile): + if not self._defaultShallMovePile(from_stack, to_stack, pile, rpile): + return False + if from_stack in self.game.s.rows and to_stack in self.game.s.rows: + # check for loops + return len(from_stack.cards) == 1 + return True + + class Hemispheres_RowStack(SC_RowStack): def _canSwapPair(self, from_stack): @@ -240,7 +251,7 @@ class Hemispheres_RowStack(SC_RowStack): class Hemispheres(Game): - Hint_Class = CautiousDefaultHint + Hint_Class = Hemispheres_Hint def createGame(self): diff --git a/pysollib/games/pyramid.py b/pysollib/games/pyramid.py index 55d4e0c0..8b30cfc8 100644 --- a/pysollib/games/pyramid.py +++ b/pysollib/games/pyramid.py @@ -1118,7 +1118,8 @@ class KingTut(RelaxedPyramid): registerGame(GameInfo(38, Pyramid, "Pyramid", GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(193, RelaxedPyramid, "Relaxed Pyramid", - GI.GT_PAIRING_TYPE | GI.GT_RELAXED, 1, 2, GI.SL_MOSTLY_LUCK)) + GI.GT_PAIRING_TYPE | GI.GT_RELAXED, 1, 2, GI.SL_MOSTLY_LUCK, + altnames=(" Pyramid's Stones",) )) ##registerGame(GameInfo(44, Thirteen, "Thirteen", ## GI.GT_PAIRING_TYPE, 1, 0)) registerGame(GameInfo(592, Giza, "Giza", diff --git a/pysollib/games/royalcotillion.py b/pysollib/games/royalcotillion.py index 4d7fe037..f002e572 100644 --- a/pysollib/games/royalcotillion.py +++ b/pysollib/games/royalcotillion.py @@ -979,6 +979,111 @@ class BoxingTheCompass(FourWinds): pass +# /*********************************************************************** +# // Colonel +# ************************************************************************/ + +class Colonel_Hint(DefaultHint): + def _getMoveCardBonus(self, r, t, pile, rpile): + if r in self.game.s.rows and t in self.game.s.rows: + if rpile: + return 0 + return DefaultHint._getMoveCardBonus(self, r, t, pile, rpile) + + +class Colonel_RowStack(SS_RowStack): + + def _getStackIndex(self, stack): + index = list(self.game.s.rows).index(stack) + if index < 12: + row = 0 + elif 12 <= index < 24: + row = 1 + else: + row = 2 + return index, row + + def acceptsCards(self, from_stack, cards): + if not SS_RowStack.acceptsCards(self, from_stack, cards): + return False + + self_index, self_row = self._getStackIndex(self) + + if self_row in (1,2): + above_stack = self.game.s.rows[self_index-12] + if not above_stack.cards: + return False + + below_stack = None + if self_row in (0,1): + below_stack = self.game.s.rows[self_index+12] + + # from_stack is waste + if from_stack is self.game.s.waste: + if below_stack is None or not below_stack.cards: + return True + else: + return False + + # from_stack in rows + from_index, from_row = self._getStackIndex(from_stack) + if below_stack and below_stack.cards: + return from_stack is below_stack + return from_row > self_row + + def canMoveCards(self, cards): + self_index, self_row = self._getStackIndex(self) + if self_row in (0,1): + below_stack = self.game.s.rows[self_index+12] + if below_stack.cards: + return False + return SS_RowStack.canMoveCards(self, cards) + + def getBottomImage(self): + return self.game.app.images.getReserveBottom() + + +class Colonel(Game): + Hint_Class = Colonel_Hint + + def createGame(self): + l, s = Layout(self), self.s + self.setSize(l.XM+12*l.XS, l.YM+5*l.YS) + + x, y = l.XM+2*l.XS, l.YM + for i in range(8): + s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4, + max_move=0)) + x += l.XS + + y = l.YM+l.YS + for i in range(3): + x = l.XM + for j in range(12): + stack = Colonel_RowStack(x, y, self, max_move=1) + stack.CARD_YOFFSET = 0 + s.rows.append(stack) + x += l.XS + y += l.YS + + x, y = l.XM+5*l.XS, l.YM+4*l.YS + s.talon = WasteTalonStack(x, y, self, max_rounds=1) + l.createText(s.talon, 'sw') + x += l.XS + s.waste = WasteStack(x, y, self) + l.createText(s.waste, 'se') + + l.defaultStackGroups() + + + def startGame(self): + self.startDealSample() + self.s.talon.dealRow() + self.s.talon.dealCards() + + shallHighlightMatch = Game._shallHighlightMatch_SS + + # register the game registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion", @@ -1017,4 +1122,6 @@ registerGame(GameInfo(675, FourWinds, "Four Winds", GI.GT_1DECK_TYPE, 1, 1, GI.SL_BALANCED)) registerGame(GameInfo(676, BoxingTheCompass, "Boxing the Compass", GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED)) +registerGame(GameInfo(693, Colonel, "Colonel", + GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))