#!/usr/bin/env python # -*- mode: python; coding: utf-8; -*- # ---------------------------------------------------------------------------## # # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2005-2009 Skomoroh # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # ---------------------------------------------------------------------------## import pysollib.game from pysollib.game import Game from pysollib.gamedb import GI, GameInfo, registerGame from pysollib.games.canfield import CanfieldRush_Talon from pysollib.hint import CautiousDefaultHint from pysollib.hint import FreeCellSolverWrapper from pysollib.hint import KlondikeType_Hint from pysollib.layout import Layout from pysollib.mfxutil import Struct, kwdefault from pysollib.mygettext import _ from pysollib.pysoltk import MfxCanvasText from pysollib.stack import \ AC_RowStack, \ BO_RowStack, \ DealRowTalonStack, \ InitialDealTalonStack, \ KingAC_RowStack, \ OpenStack, \ OpenTalonStack, \ RK_FoundationStack, \ RK_RowStack, \ RedealTalonStack, \ ReserveStack, \ SC_RowStack, \ SS_FoundationStack, \ SS_RowStack, \ Stack, \ StackWrapper, \ SuperMoveAC_RowStack, \ UD_SS_RowStack, \ WasteStack, \ WasteTalonStack, \ isSameColorSequence from pysollib.util import ACE, ANY_RANK, ANY_SUIT, KING, NO_RANK # ************************************************************************ # * Klondike # ************************************************************************ class Klondike(Game): Layout_Method = staticmethod(Layout.klondikeLayout) Talon_Class = WasteTalonStack Foundation_Class = SS_FoundationStack RowStack_Class = KingAC_RowStack Hint_Class = KlondikeType_Hint def createGame(self, max_rounds=-1, num_deal=1, **layout): # create layout lay, s = Layout(self), self.s kwdefault(layout, rows=7, waste=1, texts=1, playcards=16) self.Layout_Method.__get__(lay, lay.__class__)(**layout) # self.__class__.Layout_Method(lay, **layout) self.setSize(lay.size[0], lay.size[1]) # create stacks s.talon = self.Talon_Class(lay.s.talon.x, lay.s.talon.y, self, max_rounds=max_rounds, num_deal=num_deal) if lay.s.waste: s.waste = WasteStack(lay.s.waste.x, lay.s.waste.y, self) for r in lay.s.foundations: s.foundations.append( self.Foundation_Class(r.x, r.y, self, suit=r.suit)) for r in lay.s.rows: s.rows.append(self.RowStack_Class(r.x, r.y, self)) # default lay.defaultAll() return lay def startGame(self, flip=0, reverse=1): for i in range(1, len(self.s.rows)): self.s.talon.dealRow( rows=self.s.rows[i:], flip=flip, frames=0, reverse=reverse) self.startDealSample() self.s.talon.dealRow(reverse=reverse) if self.s.waste: self.s.talon.dealCards() # deal first card to WasteStack shallHighlightMatch = Game._shallHighlightMatch_AC # ************************************************************************ # * Vegas Klondike # ************************************************************************ class VegasKlondike(Klondike): getGameScore = Game.getGameScoreCasino getGameBalance = Game.getGameScoreCasino def createGame(self, max_rounds=1): lay = Klondike.createGame(self, max_rounds=max_rounds) self.texts.score = MfxCanvasText(self.canvas, 8, self.height - 8, anchor="sw", font=self.app.getFont("canvas_large")) return lay def updateText(self): if self.preview > 1: return b1, b2 = self.app.stats.gameid_balance, 0 if self.shallUpdateBalance(): b2 = self.getGameBalance() t = _("Balance $%d") % (b1 + b2) self.texts.score.config(text=t) def getDemoInfoTextAttr(self, tinfo): return tinfo[1] # "se" corner # ************************************************************************ # * Casino Klondike # ************************************************************************ class CasinoKlondike(VegasKlondike): def createGame(self): lay = VegasKlondike.createGame(self, max_rounds=3) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) # ************************************************************************ # * Klondike by Threes # ************************************************************************ class KlondikeByThrees(Klondike): def createGame(self): Klondike.createGame(self, num_deal=3) # ************************************************************************ # * Thumb and Pouch # * Chinaman # ************************************************************************ class ThumbAndPouch(Klondike): RowStack_Class = BO_RowStack def createGame(self): Klondike.createGame(self, max_rounds=1) def shallHighlightMatch(self, stack1, card1, stack2, card2): return (card1.suit != card2.suit and (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)) class Chinaman(ThumbAndPouch): RowStack_Class = StackWrapper(BO_RowStack, base_rank=KING) def createGame(self): lay = Klondike.createGame(self, num_deal=3, max_rounds=2, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) # ************************************************************************ # * Whitehead # ************************************************************************ class Whitehead_RowStack(SS_RowStack): def _isAcceptableSequence(self, cards): return isSameColorSequence(cards, self.cap.mod, self.cap.dir) def getHelp(self): return _('Tableau. Build down by color. Sequences of cards ' 'in the same suit can be moved as a unit.') class Whitehead(Klondike): RowStack_Class = Whitehead_RowStack Hint_Class = CautiousDefaultHint def createGame(self): Klondike.createGame(self, max_rounds=1) def startGame(self): Klondike.startGame(self, flip=1) shallHighlightMatch = Game._shallHighlightMatch_SS getQuickPlayScore = Game._getSpiderQuickPlayScore # ************************************************************************ # * Small Harp (Klondike in a different layout) # ************************************************************************ class SmallHarp(Klondike): Layout_Method = staticmethod(Layout.gypsyLayout) def startGame(self): for i in range(len(self.s.rows)): self.s.talon.dealRow(rows=self.s.rows[:i], flip=0, frames=0) self._startAndDealRowAndCards() # ************************************************************************ # * Eastcliff # * Easthaven # ************************************************************************ class Eastcliff(Klondike): RowStack_Class = AC_RowStack def createGame(self): Klondike.createGame(self, max_rounds=1) def startGame(self): for i in range(2): self.s.talon.dealRow(flip=0, frames=0) self.startDealSample() self.s.talon.dealRow() if self.s.waste: self.s.talon.dealCards() # deal first card to WasteStack class Easthaven(Eastcliff): Talon_Class = DealRowTalonStack def createGame(self): Klondike.createGame(self, max_rounds=1, waste=0) class DoubleEasthaven(Easthaven): def createGame(self): Klondike.createGame(self, rows=8, max_rounds=1, waste=0, playcards=20) class TripleEasthaven(Easthaven): def createGame(self): Klondike.createGame(self, rows=12, max_rounds=1, waste=0, playcards=26) # ************************************************************************ # * Westcliff # * Westhaven # ************************************************************************ class Westcliff(Eastcliff): Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) def createGame(self): Klondike.createGame(self, max_rounds=1, rows=10) class Westhaven(Westcliff): Talon_Class = DealRowTalonStack def createGame(self): Klondike.createGame(self, max_rounds=1, rows=10, waste=0) # ************************************************************************ # * Pas Seul # ************************************************************************ class PasSeul(pysollib.game.StartDealRowAndCards, Eastcliff): def createGame(self): Klondike.createGame(self, max_rounds=1, rows=6) # ************************************************************************ # * Blind Alleys # ************************************************************************ class BlindAlleys(Eastcliff): def createGame(self): lay = Klondike.createGame(self, max_rounds=2, rows=6, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) def _shuffleHook(self, cards): # move Aces to top of the Talon (i.e. first cards to be dealt) return self._shuffleHookMoveToTop( cards, lambda c: (c.rank == 0, c.suit)) def startGame(self): self.s.talon.dealRow(rows=self.s.foundations, frames=0) Eastcliff.startGame(self) # ************************************************************************ # * Somerset # * Morehead # * Usk # ************************************************************************ class Somerset(Klondike): Talon_Class = InitialDealTalonStack RowStack_Class = SuperMoveAC_RowStack Hint_Class = CautiousDefaultHint Solver_Class = FreeCellSolverWrapper() def createGame(self): Klondike.createGame(self, max_rounds=1, rows=10, waste=0, texts=0) def startGame(self): for i in range(6): self.s.talon.dealRow(rows=self.s.rows[i:], frames=0) self.startDealSample() self.s.talon.dealRow(rows=self.s.rows[6:]) self.s.talon.dealRow(rows=self.s.rows[7:]) class Morehead(Somerset): RowStack_Class = StackWrapper(BO_RowStack, max_move=1) Solver_Class = None class Usk(Somerset): Talon_Class = RedealTalonStack RowStack_Class = StackWrapper(AC_RowStack, base_rank=KING) Solver_Class = None def createGame(self): lay = Klondike.createGame(self, max_rounds=2, rows=10, waste=False, texts=False, round_text=True) lay.createRoundText(self.s.talon, 'ne') def redealCards(self): n = 0 while self.s.talon.cards: self.s.talon.dealRowAvail(rows=self.s.rows[n:], frames=4) n += 1 # ************************************************************************ # * Canister # * American Canister # * British Canister # ************************************************************************ class AmericanCanister(Klondike): Talon_Class = InitialDealTalonStack RowStack_Class = AC_RowStack Solver_Class = FreeCellSolverWrapper(sm='unlimited') def createGame(self): Klondike.createGame(self, max_rounds=1, rows=8, waste=0, texts=0) def startGame(self): self._startDealNumRows(5) self.s.talon.dealRow() self.s.talon.dealRow(rows=self.s.rows[2:6]) class Canister(AmericanCanister): RowStack_Class = RK_RowStack Solver_Class = FreeCellSolverWrapper(sbb='rank', sm='unlimited') shallHighlightMatch = Game._shallHighlightMatch_RK class BritishCanister(AmericanCanister): RowStack_Class = StackWrapper(KingAC_RowStack, max_move=1) Solver_Class = FreeCellSolverWrapper(esf='kings') # ************************************************************************ # * Agnes Sorel # ************************************************************************ class AgnesSorel(Klondike): Talon_Class = DealRowTalonStack Foundation_Class = StackWrapper( SS_FoundationStack, mod=13, base_rank=NO_RANK, max_move=0) RowStack_Class = StackWrapper(SC_RowStack, mod=13, base_rank=NO_RANK) def createGame(self): Klondike.createGame(self, max_rounds=1, waste=0) def startGame(self): Klondike.startGame(self, flip=1) self.s.talon.dealSingleBaseCard() def shallHighlightMatch(self, stack1, card1, stack2, card2): return (card1.color == card2.color and ((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank)) # ************************************************************************ # * 8 x 8 # * Achtmal Acht # * Eight by Eight # ************************************************************************ class EightTimesEight(Klondike): Layout_Method = staticmethod(Layout.gypsyLayout) RowStack_Class = AC_RowStack def createGame(self): Klondike.createGame(self, rows=8) def startGame(self): self._startDealNumRows(7) self.s.talon.dealRow() self.s.talon.dealCards() # deal first card to WasteStack class AchtmalAcht(EightTimesEight): def createGame(self): lay = Klondike.createGame(self, rows=8, max_rounds=3, round_text=True) lay.createRoundText(self.s.talon, 'sw', dx=-lay.XS) class EightByEight_RowStack(RK_RowStack): def acceptsCards(self, from_stack, cards): if not RK_RowStack.acceptsCards(self, from_stack, cards): return False if not self.cards: return len(cards) == 1 return True class EightByEight(EightTimesEight): Layout_Method = staticmethod(Layout.klondikeLayout) # gypsyLayout Talon_Class = CanfieldRush_Talon RowStack_Class = EightByEight_RowStack def createGame(self): lay = Klondike.createGame(self, rows=8, playcards=20, max_rounds=3, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) shallHighlightMatch = Game._shallHighlightMatch_RK # ************************************************************************ # * Batsford # * Batsford Again # ************************************************************************ class Batsford_ReserveStack(ReserveStack): def acceptsCards(self, from_stack, cards): if not ReserveStack.acceptsCards(self, from_stack, cards): return False # must be a King return cards[0].rank == KING def getHelp(self): return _('Reserve. Only Kings are acceptable.') class Batsford(Klondike): def createGame(self, **layout): kwdefault(layout, rows=10, max_rounds=1, playcards=22) round_text = (layout['max_rounds'] > 1) layout['round_text'] = round_text lay = Klondike.createGame(self, **layout) s = self.s x, y = lay.XM, self.height - lay.YS s.reserves.append(Batsford_ReserveStack(x, y, self, max_cards=3)) self.setRegion( s.reserves, (-999, y - lay.YM - lay.CH//2, x + lay.XS - lay.CW//2, 999999), priority=1) lay.createText(s.reserves[0], "se") if round_text: lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) lay.defaultStackGroups() class BatsfordAgain(Batsford): def createGame(self): Batsford.createGame(self, max_rounds=2) # ************************************************************************ # * Jumbo # ************************************************************************ class Jumbo(Klondike): def createGame(self): lay = Klondike.createGame(self, rows=9, max_rounds=2, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) def startGame(self, flip=0): for i in range(9): self.s.talon.dealRow(rows=self.s.rows[:i], flip=flip, frames=0) self._startAndDealRowAndCards() class OpenJumbo(Jumbo): def startGame(self): Jumbo.startGame(self, flip=1) # ************************************************************************ # * Stonewall # * Flower Garden # ************************************************************************ class Stonewall(Klondike): Talon_Class = InitialDealTalonStack RowStack_Class = AC_RowStack DEAL = (0, 1, 0, 1, -1, 0, 1) def createGame(self): lay = Klondike.createGame(self, rows=6, waste=0, max_rounds=1, texts=0) s = self.s h = max(self.height, lay.YM+4*lay.YS) self.setSize(self.width + lay.XM+4*lay.XS, h) for i in range(4): for j in range(4): x, y = self.width + (j-4)*lay.XS, lay.YM + i*lay.YS s.reserves.append(OpenStack(x, y, self, max_accept=0)) lay.defaultStackGroups() def startGame(self): frames = 0 for flip in self.DEAL: if flip < 0: frames = -1 self.startDealSample() else: self.s.talon.dealRow(flip=flip, frames=frames) self.s.talon.dealRow(rows=self.s.reserves) class FlowerGarden(Stonewall): RowStack_Class = StackWrapper(RK_RowStack, max_move=1) Hint_Class = CautiousDefaultHint DEAL = (1, 1, 1, 1, -1, 1, 1) shallHighlightMatch = Game._shallHighlightMatch_RK # ************************************************************************ # * King Albert # * Raglan # * Brigade # * Queen Victoria # ************************************************************************ class KingAlbert(Klondike): Talon_Class = InitialDealTalonStack RowStack_Class = StackWrapper(AC_RowStack, max_move=1) Hint_Class = CautiousDefaultHint ROWS = 9 RESERVES = (2, 2, 2, 1) def createGame(self): lay = Klondike.createGame( self, max_rounds=1, rows=self.ROWS, waste=0, texts=0) s = self.s rw, rh = max(self.RESERVES), len(self.RESERVES) h = max(self.height, lay.YM+rh*lay.YS) self.setSize(self.width + 2*lay.XM+rw*lay.XS, h) for i in range(rh): for j in range(self.RESERVES[i]): x, y = self.width + (j-rw)*lay.XS, lay.YM + i*lay.YS s.reserves.append(OpenStack(x, y, self, max_accept=0)) lay.defaultStackGroups() def startGame(self): Klondike.startGame(self, flip=1, reverse=0) self.s.talon.dealRow(rows=self.s.reserves) class Raglan(KingAlbert): RESERVES = (2, 2, 2) def _shuffleHook(self, cards): # move Aces to bottom of the Talon (i.e. last cards to be dealt) return self._shuffleHookMoveToBottom( cards, lambda c: (c.rank == 0, c.suit)) def startGame(self): for i in range(6): self.s.talon.dealRow(rows=self.s.rows[i:], frames=0) self.startDealSample() self.s.talon.dealRow(rows=self.s.rows[6:]) self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow(rows=self.s.foundations) class Brigade(Raglan): RowStack_Class = StackWrapper(RK_RowStack, max_move=1) ROWS = 7 RESERVES = (4, 4, 4, 1) def startGame(self): self._startDealNumRows(4) self.s.talon.dealRow() self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow(rows=self.s.foundations) shallHighlightMatch = Game._shallHighlightMatch_RK class QueenVictoria(KingAlbert): RowStack_Class = AC_RowStack # ************************************************************************ # * Jane # * Agnes Bernauer # ************************************************************************ class Jane_Talon(OpenTalonStack): rightclickHandler = OpenStack.rightclickHandler doubleclickHandler = OpenStack.doubleclickHandler def canFlipCard(self): return False def canDealCards(self): return len(self.cards) >= 2 def dealCards(self, sound=False): c = 0 if len(self.cards) > 2: c = self.dealRow(self.game.s.reserves, sound=sound) if len(self.cards) == 2: self.game.flipMove(self) self.game.moveMove(1, self, self.game.s.waste, frames=4, shadow=0) self.game.flipMove(self) c = c + 1 return c class Jane(Klondike): Talon_Class = Jane_Talon Foundation_Class = StackWrapper( SS_FoundationStack, mod=13, base_rank=NO_RANK, min_cards=1) RowStack_Class = StackWrapper(AC_RowStack, mod=13, base_rank=NO_RANK) def createGame(self, max_rounds=1, rows=7, reserves=7, playcards=16): lay, s = Layout(self), self.s maxrows = max(rows, 7) w = lay.XM+maxrows*lay.XS+lay.XM+2*lay.XS h = max(lay.YM+2*lay.YS+playcards*lay.YOFFSET+lay.TEXT_HEIGHT, lay.YM+4*lay.YS) self.setSize(w, h) x, y = lay.XM, lay.YM s.talon = self.Talon_Class(x, y, self, max_rounds=max_rounds) lay.createText(s.talon, 's') x += lay.XS s.waste = WasteStack(x, y, self) x += 2*lay.XS for i in range(4): s.foundations.append(self.Foundation_Class(x, y, self, suit=i)) x += lay.XS x, y = lay.XM, lay.YM+lay.YS+lay.TEXT_HEIGHT for i in range(rows): s.rows.append(self.RowStack_Class(x, y, self)) x += lay.XS x0, y = self.width - 2*lay.XS, lay.YM for i in range(reserves): x = x0 + ((i+1) & 1) * lay.XS stack = OpenStack(x, y, self, max_accept=0) stack.CARD_YOFFSET = lay.YM // 3 s.reserves.append(stack) y = y + lay.YS // 2 # not needed, as no cards may be placed on the reserves # self.setRegion(s.reserves, (x0-lay.XM//2, -999, 999999, 999999), # priority=1) lay.defaultStackGroups() self.sg.dropstacks.append(s.talon) def startGame(self, flip=0, reverse=1): for i in range(1, len(self.s.rows)): self.s.talon.dealRow( rows=self.s.rows[i:], flip=flip, frames=0, reverse=reverse) self.startDealSample() self.s.talon.dealRow(reverse=reverse) self.s.talon.dealRow(rows=self.s.reserves) c = self.s.talon.dealSingleBaseCard() # update base rank of row stacks cap = Struct(base_rank=(c.rank - 1) % 13) for s in self.s.rows: s.cap.update(cap.__dict__) self.saveinfo.stack_caps.append((s.id, cap)) shallHighlightMatch = Game._shallHighlightMatch_ACW def _autoDeal(self, sound=True): return 0 class AgnesBernauer_Talon(DealRowTalonStack): def dealCards(self, sound=False): return self.dealRowAvail(self.game.s.reserves, sound=sound) class AgnesBernauer(Jane): Talon_Class = AgnesBernauer_Talon Foundation_Class = StackWrapper( SS_FoundationStack, mod=13, base_rank=NO_RANK, max_move=0) def startGame(self): Jane.startGame(self, flip=1) # ************************************************************************ # * Senate # ************************************************************************ class Senate(Jane): def createGame(self, rows=4): playcards = 10 lay, s = Layout(self), self.s self.setSize(lay.XM+(rows+7)*lay.XS, lay.YM+2*(lay.YS+playcards*lay.YOFFSET)) x, y = lay.XM, lay.YM for i in range(rows): s.rows.append(SS_RowStack(x, y, self)) x += lay.XS for y in lay.YM, lay.YM+lay.YS+playcards*lay.YOFFSET: x = lay.XM+rows*lay.XS+lay.XS//2 for i in range(4): stack = OpenStack(x, y, self, max_accept=0) stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, lay.YOFFSET s.reserves.append(stack) x += lay.XS x = lay.XM+(rows+5)*lay.XS for i in range(2): y = lay.YM+lay.YS for j in range(4): s.foundations.append(SS_FoundationStack(x, y, self, suit=j)) y += lay.YS x += lay.XS x, y = self.width-lay.XS, lay.YM s.talon = AgnesBernauer_Talon(x, y, self) lay.createText(s.talon, 'nw') lay.defaultStackGroups() def startGame(self): self.s.talon.dealRow(rows=self.s.foundations, frames=0) self.startDealSample() self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow() def _shuffleHook(self, cards): # move Aces to top of the Talon (i.e. first cards to be dealt) return self._shuffleHookMoveToTop( cards, lambda c: (c.rank == ACE, (c.deck, c.suit))) shallHighlightMatch = Game._shallHighlightMatch_SS class SenatePlus(Senate): def createGame(self): Senate.createGame(self, rows=5) # ************************************************************************ # * Phoenix # * Arizona # ************************************************************************ class Phoenix(Klondike): Hint_Class = CautiousDefaultHint RowStack_Class = AC_RowStack def createGame(self): lay, s = Layout(self), self.s self.setSize(lay.XM + 10*lay.XS, lay.YM + 4*(lay.YS+lay.YM)) for i in range(2): x = lay.XM + i*lay.XS for j in range(4): y = lay.YM + j*(lay.YS+lay.YM) s.reserves.append(OpenStack(x, y, self, max_accept=0)) for i in range(2): x = lay.XM + (8+i)*lay.XS for j in range(4): y = lay.YM + j*(lay.YS+lay.YM) s.reserves.append(OpenStack(x, y, self, max_accept=0)) for i in range(4): s.foundations.append( SS_FoundationStack(lay.XM+(3+i)*lay.XS, lay.YM, self, i)) for i in range(6): s.rows.append( self.RowStack_Class(lay.XM+(2+i)*lay.XS, lay.YM+lay.YS, self)) s.talon = InitialDealTalonStack( lay.XM+int(4.5*lay.XS), lay.YM+3*(lay.YS+lay.YM), self) lay.defaultStackGroups() def startGame(self): self._startDealNumRows(6) self.s.talon.dealRow(rows=self.s.reserves) class Arizona(Phoenix): RowStack_Class = RK_RowStack shallHighlightMatch = Game._shallHighlightMatch_RK # ************************************************************************ # * Lanes # ************************************************************************ class Lanes(Klondike): Hint_Class = CautiousDefaultHint Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) RowStack_Class = StackWrapper(AC_RowStack, base_rank=ANY_RANK, max_move=1) def createGame(self): lay = Klondike.createGame(self, rows=6, max_rounds=2, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) def _shuffleHook(self, cards): # move Aces to top of the Talon (i.e. first cards to be dealt) return self._shuffleHookMoveToTop(cards, lambda c: (c.rank == ACE, c.suit)) def startGame(self): self.s.talon.dealRow(rows=self.s.foundations, frames=0) self._startDealNumRows(2) self.s.talon.dealRow() self.s.talon.dealCards() # deal first card to WasteStack # ************************************************************************ # * Thirty Six # ************************************************************************ class ThirtySix(Klondike): Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) RowStack_Class = StackWrapper(RK_RowStack, base_rank=ANY_RANK) def createGame(self): Klondike.createGame(self, rows=6, max_rounds=1) def _fillOne(self): for r in self.s.rows: if r.cards: c = r.cards[-1] for f in self.s.foundations: if f.acceptsCards(r, [c]): self.moveMove(1, r, f, frames=4, shadow=0) return 1 return 0 def startGame(self): self.startDealSample() for i in range(6): self.s.talon.dealRow() while True: if not self._fillOne(): break self.s.talon.dealCards() # deal first card to WasteStack shallHighlightMatch = Game._shallHighlightMatch_RK # ************************************************************************ # * Q.C. # ************************************************************************ class Q_C_(Klondike): Hint_Class = CautiousDefaultHint Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) RowStack_Class = StackWrapper(SS_RowStack, base_rank=ANY_RANK, max_move=1) def createGame(self): lay = Klondike.createGame(self, rows=6, max_rounds=2) lay.createRoundText(self.s.talon, 'sss') def startGame(self): self._startDealNumRows(3) self.s.talon.dealRow() while self.s.talon.cards: self.s.talon.dealCards() # deal first card to WasteStack if not self.fillWaste(): break def fillWaste(self): waste = self.s.waste if waste.cards: c = waste.cards[-1] for f in self.s.foundations: if f.acceptsCards(self.s.waste, [c]): waste.moveMove(1, f) return True return False def fillStack(self, stack=None): waste = self.s.waste while True: if not self.fillWaste(): break if stack in self.s.rows and not stack.cards: if not waste.cards: while self.s.talon.cards: self.s.talon.dealCards() if not self.fillWaste(): break if waste.cards: waste.moveMove(1, stack) shallHighlightMatch = Game._shallHighlightMatch_SS # ************************************************************************ # * Northwest Territory # * Artic Garden # ************************************************************************ class NorthwestTerritory(KingAlbert): RowStack_Class = StackWrapper(AC_RowStack, base_rank=KING) RESERVES = (4, 4, 4, 4) ROWS = 8 def startGame(self): Klondike.startGame(self, flip=0, reverse=0) self.s.talon.dealRow(rows=self.s.reserves) class ArticGarden(NorthwestTerritory): def startGame(self): Klondike.startGame(self, flip=1, reverse=0) self.s.talon.dealRow(rows=self.s.reserves) # ************************************************************************ # * Aunt Mary # ************************************************************************ class AuntMary(Klondike): def createGame(self): Klondike.createGame(self, rows=6, max_rounds=1) def startGame(self): for i in range(5): j = i+1 self.s.talon.dealRow(rows=self.s.rows[:j], frames=0, flip=1) self.s.talon.dealRow(rows=self.s.rows[j:], frames=0, flip=0) self.startDealSample() self.s.talon.dealRow() self.s.talon.dealCards() # ************************************************************************ # * Double Dot # ************************************************************************ class DoubleDot(Klondike): Talon_Class = DealRowTalonStack RowStack_Class = StackWrapper(RK_RowStack, dir=-2, mod=13) Foundation_Class = StackWrapper(SS_FoundationStack, dir=2, mod=13) def createGame(self): Klondike.createGame(self, max_rounds=1, rows=8, waste=0) def _shuffleHook(self, cards): return self._shuffleHookMoveToTop( cards, lambda c: ((c.rank == ACE and c.suit in (0, 1)) or (c.rank == 1 and c.suit in (2, 3)), c.suit)) def startGame(self): self.s.talon.dealRow(rows=self.s.foundations, frames=0) self._startAndDealRow() # def shallHighlightMatch(self, stack1, card1, stack2, card2): # return abs(card1.rank-card2.rank) == 2 shallHighlightMatch = Game._shallHighlightMatch_RKW # ************************************************************************ # * Seven Devils # ************************************************************************ class SevenDevils_RowStack(AC_RowStack): def acceptsCards(self, from_stack, cards): if not AC_RowStack.acceptsCards(self, from_stack, cards): return False return from_stack not in self.game.s.reserves class SevenDevils(Klondike): Hint_Class = CautiousDefaultHint RowStack_Class = StackWrapper(SevenDevils_RowStack, max_move=1) def createGame(self): lay, s = Layout(self), self.s self.setSize(lay.XM + 10*lay.XS, lay.YM+3*lay.YS+12*lay.YOFFSET) x, y = lay.XM, lay.YM for i in range(8): s.foundations.append(SS_FoundationStack(x, y, self, suit=i//2)) x += lay.XS x, y = lay.XM+lay.XS//2, lay.YM+lay.YS for i in range(7): s.rows.append(self.RowStack_Class(x, y, self)) x += lay.XS x0, y = self.width - 2*lay.XS, lay.YM for i in range(7): x = x0 + ((i+1) & 1) * lay.XS s.reserves.append(OpenStack(x, y, self, max_accept=0)) y += lay.YS // 2 x, y = lay.XM, self.height-lay.YS s.talon = WasteTalonStack(x, y, self, max_rounds=1) lay.createText(s.talon, 'n') x += lay.XS s.waste = WasteStack(x, y, self) lay.createText(s.waste, 'n') lay.defaultStackGroups() def startGame(self, flip=0, reverse=1): Klondike.startGame(self) self.s.talon.dealRow(rows=self.s.reserves) # ************************************************************************ # * Moving Left # * Souter # ************************************************************************ class MovingLeft(Klondike): def createGame(self): Klondike.createGame(self, max_rounds=1, rows=10, playcards=24) def fillStack(self, stack): if not stack.cards: old_state = self.enterState(self.S_FILL) if stack in self.s.rows: i = list(self.s.rows).index(stack) if i < len(self.s.rows)-1: from_stack = self.s.rows[i+1] pile = from_stack.getPile() if pile: from_stack.moveMove(len(pile), stack) self.leaveState(old_state) class Souter(MovingLeft): def createGame(self): lay = Klondike.createGame(self, max_rounds=2, rows=10, playcards=24, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) # ************************************************************************ # * Big Forty # * Ali Baba # * Cassim # ************************************************************************ class BigForty(Klondike): RowStack_Class = SS_RowStack def createGame(self): Klondike.createGame(self, rows=10) def startGame(self): self._startDealNumRowsAndDealRowAndCards(3) shallHighlightMatch = Game._shallHighlightMatch_SS class AliBaba(BigForty): def _shuffleHook(self, cards): # move Aces to top of the Talon (i.e. first cards to be dealt) return self._shuffleHookMoveToTop(cards, lambda c: (c.rank == ACE, c.suit)) def startGame(self): self.s.talon.dealRow(rows=self.s.foundations, frames=0) BigForty.startGame(self) class Cassim(AliBaba): def createGame(self): Klondike.createGame(self, rows=7) # ************************************************************************ # * Saratoga # ************************************************************************ class Saratoga(Klondike): def createGame(self): Klondike.createGame(self, num_deal=3) def startGame(self): Klondike.startGame(self, flip=1) # ************************************************************************ # * Whitehorse # ************************************************************************ class Whitehorse(Klondike): def createGame(self): Klondike.createGame(self, num_deal=3) def startGame(self): self.startDealSample() self.s.talon.dealRow() self.s.talon.dealCards() def fillStack(self, stack): if not stack.cards: old_state = self.enterState(self.S_FILL) if stack in self.s.rows: if not self.s.waste.cards: self.s.talon.dealCards() if self.s.waste.cards: self.s.waste.moveMove(1, stack) self.leaveState(old_state) # ************************************************************************ # * Boost # ************************************************************************ class Boost(Klondike): def createGame(self): lay = Klondike.createGame(self, rows=4, max_rounds=3, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) # ************************************************************************ # * Gold Rush # ************************************************************************ class GoldRush(Klondike): Talon_Class = CanfieldRush_Talon def createGame(self): lay = Klondike.createGame(self, max_rounds=3, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) # ************************************************************************ # * Gold Mine # ************************************************************************ class GoldMine_RowStack(AC_RowStack): getBottomImage = Stack._getReserveBottomImage class GoldMine(Klondike): RowStack_Class = GoldMine_RowStack def createGame(self): Klondike.createGame(self, max_rounds=1, num_deal=3) def startGame(self): self.startDealSample() self.s.talon.dealCards() # ************************************************************************ # * Lucky Thirteen # * Lucky Piles # ************************************************************************ class LuckyThirteen(Game): Hint_Class = CautiousDefaultHint RowStack_Class = StackWrapper(RK_RowStack, base_rank=NO_RANK) def createGame(self, xoffset=0, playcards=0): lay, s = Layout(self), self.s if xoffset: xoffset = lay.XOFFSET w0 = lay.XS+playcards*lay.XOFFSET self.setSize(lay.XM + 5*w0, lay.YM+4*lay.YS) x, y = lay.XM, lay.YM+lay.YS for i in range(5): stack = self.RowStack_Class(x, y, self, max_move=1) s.rows.append(stack) stack.CARD_XOFFSET = xoffset stack.CARD_YOFFSET = 0 x += w0 x, y = lay.XM+w0, lay.YM+2*lay.YS for i in range(3): stack = self.RowStack_Class(x, y, self, max_move=1) s.rows.append(stack) stack.CARD_XOFFSET = xoffset stack.CARD_YOFFSET = 0 x += w0 x, y = lay.XM, lay.YM+3*lay.YS for i in range(5): stack = self.RowStack_Class(x, y, self, max_move=1) s.rows.append(stack) stack.CARD_XOFFSET = xoffset stack.CARD_YOFFSET = 0 x += w0 x, y = (self.width-4*lay.XS)//2, lay.YM for i in range(4): s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) x += lay.XS x, y = lay.XM, self.height-lay.YS s.talon = InitialDealTalonStack(x, y, self, max_rounds=1) lay.defaultStackGroups() def startGame(self): self._startDealNumRowsAndDealSingleRow(3) shallHighlightMatch = Game._shallHighlightMatch_RK class LuckyPiles(LuckyThirteen): RowStack_Class = StackWrapper(UD_SS_RowStack, base_rank=KING) def createGame(self): LuckyThirteen.createGame(self, xoffset=1, playcards=7) shallHighlightMatch = Game._shallHighlightMatch_SS # ************************************************************************ # * Legion # ************************************************************************ class Legion(Klondike): def createGame(self): Klondike.createGame(self, max_rounds=1, rows=8) def startGame(self): self.startDealSample() self.s.talon.dealRow() for i in (1, 2, 3): self.s.talon.dealRow(rows=self.s.rows[i:-i], flip=0) self.s.talon.dealRow(rows=self.s.rows[i:-i]) self.s.talon.dealCards() # ************************************************************************ # * Big Bertha # ************************************************************************ class BigBertha(Game): def createGame(self): lay, s = Layout(self), self.s self.setSize(lay.XM+15*lay.XS, lay.YM+3*lay.YS+15*lay.YOFFSET) x, y = lay.XM, lay.YM s.talon = InitialDealTalonStack(x, y, self) x, y = lay.XM+3.5*lay.XS, lay.YM for i in range(8): s.foundations.append(SS_FoundationStack(x, y, self, suit=i % 4, max_cards=12)) x += lay.XS x, y = lay.XM, lay.YM+lay.YS for i in range(15): s.rows.append(AC_RowStack(x, y, self)) x += lay.XS x, y = lay.XM, self.height-lay.YS for i in range(14): s.reserves.append(OpenStack(x, y, self, max_accept=0)) x += lay.XS s.foundations.append(RK_FoundationStack(x, y, self, suit=ANY_SUIT, base_rank=KING, dir=0, max_cards=8)) lay.defaultStackGroups() def startGame(self): self._startDealNumRows(5) self.s.talon.dealRow() self.s.talon.dealRow(rows=self.s.reserves) shallHighlightMatch = Game._shallHighlightMatch_AC # ************************************************************************ # * Athena # ************************************************************************ class Athena(Klondike): def startGame(self): self.s.talon.dealRow(frames=0, flip=0) self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0, flip=0) self.startDealSample() self.s.talon.dealRow() self.s.talon.dealCards() # ************************************************************************ # * Kingsley # ************************************************************************ class Kingsley(Klondike): Foundation_Class = StackWrapper(SS_FoundationStack, base_rank=KING, dir=-1) RowStack_Class = StackWrapper(KingAC_RowStack, base_rank=ACE, dir=1) def createGame(self): Klondike.createGame(self, max_rounds=1) # ************************************************************************ # * Scarp # ************************************************************************ class Scarp(Klondike): Talon_Class = DealRowTalonStack RowStack_Class = AC_RowStack def createGame(self): Klondike.createGame(self, max_rounds=1, rows=13, waste=0, playcards=28) def startGame(self): Klondike.startGame(self, flip=1) # ************************************************************************ # * Eight Sages # ************************************************************************ class EightSages_Row(AC_RowStack): def acceptsCards(self, from_stack, cards): if not AC_RowStack.acceptsCards(self, from_stack, cards): return False return from_stack is self.game.s.waste class EightSages(Klondike): RowStack_Class = EightSages_Row def createGame(self): lay = Klondike.createGame(self, max_rounds=2, rows=8, playcards=12, round_text=True) lay.createRoundText(self.s.talon, 'ne', dx=lay.XS) def startGame(self): self.startDealSample() self.s.talon.dealRow() self.s.talon.dealCards() # register the game registerGame(GameInfo(2, Klondike, "Klondike", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(61, CasinoKlondike, "Casino Klondike", GI.GT_KLONDIKE | GI.GT_SCORE, 1, 2, GI.SL_BALANCED)) registerGame(GameInfo(129, VegasKlondike, "Vegas Klondike", GI.GT_KLONDIKE | GI.GT_SCORE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(18, KlondikeByThrees, "Klondike by Threes", GI.GT_KLONDIKE, 1, -1, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(58, ThumbAndPouch, "Thumb and Pouch", GI.GT_KLONDIKE, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(67, Whitehead, "Whitehead", GI.GT_KLONDIKE, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(39, SmallHarp, "Small Harp", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED, altnames=("Die kleine Harfe",))) registerGame(GameInfo(66, Eastcliff, "Eastcliff", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(224, Easthaven, "Easthaven", GI.GT_GYPSY, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(33, Westcliff, "Westcliff", GI.GT_KLONDIKE, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(225, Westhaven, "Westhaven", GI.GT_GYPSY, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(107, PasSeul, "Pas Seul", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(81, BlindAlleys, "Blind Alleys", GI.GT_KLONDIKE, 1, 1, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(215, Somerset, "Somerset", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(231, Canister, "Canister", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(229, AgnesSorel, "Agnes Sorel", GI.GT_GYPSY, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(4, EightTimesEight, "8 x 8", GI.GT_KLONDIKE, 2, -1, GI.SL_BALANCED)) registerGame(GameInfo(127, AchtmalAcht, "Eight Times Eight", GI.GT_KLONDIKE, 2, 2, GI.SL_BALANCED, altnames=("Achtmal Acht",))) registerGame(GameInfo(133, Batsford, "Batsford", GI.GT_KLONDIKE, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(221, Stonewall, "Stonewall", GI.GT_RAGLAN, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(222, FlowerGarden, "Flower Garden", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL, altnames=("The Bouquet", "The Garden",))) registerGame(GameInfo(233, KingAlbert, "King Albert", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL, altnames=("Idiot's Delight",))) registerGame(GameInfo(232, Raglan, "Raglan", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(223, Brigade, "Brigade", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(230, Jane, "Jane", GI.GT_RAGLAN, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(236, AgnesBernauer, "Agnes Bernauer", GI.GT_RAGLAN, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(263, Phoenix, "Phoenix", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(283, Jumbo, "Jumbo", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(333, OpenJumbo, "Open Jumbo", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(326, Lanes, "Lanes", GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED)) registerGame(GameInfo(327, ThirtySix, "Thirty Six", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(350, Q_C_, "Q.C.", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(361, NorthwestTerritory, "Northwest Territory", GI.GT_RAGLAN, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(362, Morehead, "Morehead", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(388, Senate, "Senate", GI.GT_RAGLAN, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(389, SenatePlus, "Senate +", GI.GT_RAGLAN, 2, 0, GI.SL_BALANCED)) registerGame(GameInfo(390, Arizona, "Arizona", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(407, AuntMary, "Aunt Mary", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(420, DoubleDot, "Double Dot", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(434, SevenDevils, "Seven Devils", GI.GT_RAGLAN, 2, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(452, DoubleEasthaven, "Double Easthaven", GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(453, TripleEasthaven, "Triple Easthaven", GI.GT_GYPSY, 3, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(470, MovingLeft, "Moving Left", GI.GT_KLONDIKE, 2, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(471, Souter, "Souter", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(473, BigForty, "Big Forty", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(474, AliBaba, "Ali Baba", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(475, Cassim, "Cassim", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(479, Saratoga, "Saratoga", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(491, Whitehorse, "Whitehorse", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(518, Boost, "Boost", GI.GT_KLONDIKE | GI.GT_ORIGINAL, 1, 2, GI.SL_BALANCED)) registerGame(GameInfo(522, ArticGarden, "Artic Garden", GI.GT_RAGLAN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(532, GoldRush, "Gold Rush", GI.GT_KLONDIKE, 1, 2, GI.SL_BALANCED)) registerGame(GameInfo(539, Usk, "Usk", GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED)) registerGame(GameInfo(541, BatsfordAgain, "Batsford Again", GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED)) registerGame(GameInfo(572, GoldMine, "Gold Mine", GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(585, LuckyThirteen, "Lucky Thirteen", GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(586, LuckyPiles, "Lucky Piles", GI.GT_FAN_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(601, AmericanCanister, "American Canister", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(602, BritishCanister, "British Canister", GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(607, Legion, "Legion", GI.GT_KLONDIKE, 1, 0, GI.SL_BALANCED)) registerGame(GameInfo(627, QueenVictoria, "Queen Victoria", GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(630, BigBertha, "Big Bertha", GI.GT_RAGLAN | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(633, Athena, "Athena", GI.GT_KLONDIKE, 1, -1, GI.SL_BALANCED)) registerGame(GameInfo(634, Chinaman, "Chinaman", GI.GT_KLONDIKE, 1, 1, GI.SL_BALANCED)) registerGame(GameInfo(651, EightByEight, "Eight by Eight", GI.GT_KLONDIKE, 2, 2, GI.SL_BALANCED)) registerGame(GameInfo(667, Kingsley, "Kingsley", GI.GT_KLONDIKE, 1, 0, GI.SL_MOSTLY_LUCK)) registerGame(GameInfo(669, Scarp, "Scarp", GI.GT_GYPSY | GI.GT_ORIGINAL, 3, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(726, EightSages, "Eight Sages", GI.GT_KLONDIKE, 2, 1, GI.SL_MOSTLY_LUCK))