diff --git a/pysollib/games/golf.py b/pysollib/games/golf.py index 015881c7..ffd1ab16 100644 --- a/pysollib/games/golf.py +++ b/pysollib/games/golf.py @@ -878,9 +878,7 @@ class ThreeFirTrees_RowStack(Golf_RowStack): return False -class ThreeFirTrees(Golf): - Hint_Class = CautiousDefaultHint - +class FirTree_GameMethods: def _createFirTree(self, l, x0, y0): rows = [] # create stacks @@ -902,10 +900,13 @@ class ThreeFirTrees(Golf): n += 1 return rows + +class ThreeFirTrees(Golf, FirTree_GameMethods): + Hint_Class = CautiousDefaultHint + def createGame(self): l, s = Layout(self), self.s - self.setSize(l.XM+max(7*l.XS, 2*l.XS+26*l.XOFFSET), l.YM+5*l.YS) x0, y0 = (self.width-7*l.XS)/2, l.YM @@ -934,6 +935,73 @@ class ThreeFirTrees(Golf): self.s.talon.dealCards() +# /*********************************************************************** +# // Napoleon Takes Moscow +# // Napoleon Leaves Moscow +# ************************************************************************/ + +class NapoleonTakesMoscow(Game, FirTree_GameMethods): + RowStack_Class = StackWrapper(SS_RowStack, base_rank=KING, max_move=1) + Hint_Class = CautiousDefaultHint + + def createGame(self): + + l, s = Layout(self), self.s + self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+15*l.YOFFSET) + + x, y = l.XM+l.XS, l.YM + for i in range(8): + s.foundations.append(SS_FoundationStack(x, y, self, suit=i/2)) + x += l.XS + + x, y = l.XM, l.YM+l.YS + for i in range(2): + for j in range(4): + s.rows.append(self.RowStack_Class(x, y, self)) + x += l.XS + x += 2*l.XS + + x, y = l.XM+4*l.XS, l.YM+l.YS + s.reserves += self._createFirTree(l, x, y) + + x, y = l.XM, self.height-l.YS + s.talon = WasteTalonStack(x, y, self, max_rounds=3) + l.createText(s.talon, 'n') + tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn') + font = self.app.getFont('canvas_default') + s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty-l.TEXT_MARGIN, + anchor=ta, font=font) + + x += l.XS + s.waste = WasteStack(x, y, self) + l.createText(s.waste, 'n') + + # define stack-groups + l.defaultStackGroups() + + def startGame(self): + self.s.talon.dealRow(rows=self.s.reserves, frames=0) + for i in range(3): + self.s.talon.dealRow(frames=0) + self.startDealSample() + self.s.talon.dealRow() + self.s.talon.dealCards() + + shallHighlightMatch = Game._shallHighlightMatch_SS + + +class NapoleonLeavesMoscow(NapoleonTakesMoscow): + RowStack_Class = StackWrapper(SS_RowStack, base_rank=KING) + Hint_Class = DefaultHint + + def startGame(self): + self.s.talon.dealRow(rows=self.s.reserves, frames=0) + for i in range(4): + self.s.talon.dealRow(frames=0) + self.startDealSample() + self.s.talon.dealRow() + self.s.talon.dealCards() + # register the game registerGame(GameInfo(36, Golf, "Golf", @@ -966,9 +1034,14 @@ registerGame(GameInfo(709, Waterfall, "Waterfall", registerGame(GameInfo(720, Vague, "Vague", GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(723, DevilsSolitaire, "Devil's Solitaire", - GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED)) + GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED, + altnames=('Banner',) )) registerGame(GameInfo(728, ThirtyTwoCards, "Thirty Two Cards", GI.GT_2DECK_TYPE, 2, 0, GI.SL_LUCK)) registerGame(GameInfo(731, ThreeFirTrees, "Three Fir-trees", GI.GT_GOLF, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(733, NapoleonTakesMoscow, "Napoleon Takes Moscow", + GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED)) +registerGame(GameInfo(734, NapoleonLeavesMoscow, "Napoleon Leaves Moscow", + GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED)) diff --git a/pysollib/games/montana.py b/pysollib/games/montana.py index f86245a7..afcf1778 100644 --- a/pysollib/games/montana.py +++ b/pysollib/games/montana.py @@ -464,5 +464,5 @@ registerGame(GameInfo(381, SpacesAndAces, "Spaces and Aces", registerGame(GameInfo(706, Paganini, "Paganini", GI.GT_MONTANA | GI.GT_OPEN, 1, 1, GI.SL_MOSTLY_SKILL, ranks=(0, 5, 6, 7, 8, 9, 10, 11, 12), - )) + altnames=('Long Trip',) )) diff --git a/pysollib/games/yukon.py b/pysollib/games/yukon.py index 45312b54..b08ce580 100644 --- a/pysollib/games/yukon.py +++ b/pysollib/games/yukon.py @@ -700,6 +700,45 @@ class Hawaiian(Game): shallHighlightMatch = Game._shallHighlightMatch_AC +# /*********************************************************************** +# // Wave +# ************************************************************************/ + +class WaveTalon(DealRowTalonStack): + def dealCards(self, sound=0): + if sound and self.game.app.opt.animations: + self.game.startDealSample() + n = self.dealRowAvail(flip=0, sound=0) + n += self.dealRowAvail(sound=0) + if sound: + self.game.stopSamples() + return n + + +class Wave(Game): + Hint_Class = Yukon_Hint + + def createGame(self, rows=8): + l, s = Layout(self), self.s + l.klondikeLayout(rows=rows, waste=0, playcards=25) + self.setSize(l.size[0], l.size[1]) + s.talon = WaveTalon(l.s.talon.x, l.s.talon.y, self) + for r in l.s.foundations: + s.foundations.append(SS_FoundationStack(r.x, r.y, self, + suit=r.suit)) + for r in l.s.rows: + s.rows.append(Yukon_AC_RowStack(r.x, r.y, self)) + l.defaultAll() + + def startGame(self): + self.s.talon.dealRow(frames=0) + self.s.talon.dealRow(frames=0, flip=0) + self.startDealSample() + self.s.talon.dealRow() + + shallHighlightMatch = Game._shallHighlightMatch_AC + + # register the game registerGame(GameInfo(19, Yukon, "Yukon", @@ -761,3 +800,5 @@ registerGame(GameInfo(603, Brisbane, "Brisbane", GI.GT_SPIDER, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(707, Hawaiian, "Hawaiian", GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(732, Wave, "Wave", + GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED)) diff --git a/pysollib/stack.py b/pysollib/stack.py index c38c987d..e5b2340b 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -76,6 +76,7 @@ __all__ = ['cardsFaceUp', 'Spider_SS_RowStack', 'Yukon_AC_RowStack', 'Yukon_SS_RowStack', + 'Yukon_RK_RowStack', 'KingAC_RowStack', 'KingSS_RowStack', 'KingRK_RowStack', @@ -2310,6 +2311,16 @@ class Yukon_SS_RowStack(Yukon_AC_RowStack): elif self.cap.dir < 0: return _('Tableau. Build down by suit, can move any face-up cards regardless of sequence.') else: return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.') +# A Yukon_Rank_RowStack builds down by rank +# but can move any face-up cards regardless of sequence. +class Yukon_RK_RowStack(Yukon_AC_RowStack): + def _isSequence(self, c1, c2): + return (c1.rank + self.cap.dir) % self.cap.mod == c2.rank + def getHelp(self): + if self.cap.dir > 0: return _('Tableau. Build up regardless of suit, can move any face-up cards regardless of sequence.') + elif self.cap.dir < 0: return _('Tableau. Build up regardless of suit, can move any face-up cards regardless of sequence.') + else: return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.') + # # King-versions of some of the above stacks: they accepts only Kings or # sequences starting with a King as base_rank cards (i.e. when empty).