1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
This commit is contained in:
Shlomi Fish 2017-04-17 20:25:13 +03:00
parent dc3f0806f5
commit 7d6c4cf58e
8 changed files with 322 additions and 199 deletions

View file

@ -21,19 +21,28 @@
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
__all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import ACE, KING, NO_RANK, UNLIMITED_ACCEPTS, \
UNLIMITED_MOVES
from pysollib.stack import \
AC_FoundationStack, \
AC_RowStack, \
InitialDealTalonStack, \
RK_RowStack, \
SS_FoundationStack, \
SS_RowStack, \
SuperMoveAC_RowStack, \
TalonStack, \
UD_AC_RowStack, \
UD_SS_RowStack, \
StackWrapper
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import CautiousDefaultHint
from pysollib.hint import FreeCellSolverWrapper from pysollib.hint import FreeCellSolverWrapper
@ -62,7 +71,8 @@ class CastlesInSpain(Game):
# create stacks # create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, suit=r.suit)) s.foundations.append(
self.Foundation_Class(r.x, r.y, self, suit=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self)) s.rows.append(self.RowStack_Class(r.x, r.y, self))
# default # default
@ -99,7 +109,8 @@ class Martha(CastlesInSpain):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # 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)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == 0, c.suit))
def startGame(self): def startGame(self):
CastlesInSpain.startGame(self, flip=(0, 1, 0)) CastlesInSpain.startGame(self, flip=(0, 1, 0))
@ -152,6 +163,7 @@ class SpanishPatience(BakersDozen):
class PortugueseSolitaire(BakersDozen): class PortugueseSolitaire(BakersDozen):
RowStack_Class = StackWrapper(RK_RowStack, base_rank=KING, max_move=1) RowStack_Class = StackWrapper(RK_RowStack, base_rank=KING, max_move=1)
Solver_Class = FreeCellSolverWrapper(sbb='rank', esf='kings') Solver_Class = FreeCellSolverWrapper(sbb='rank', esf='kings')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
return cards return cards
@ -174,7 +186,8 @@ class GoodMeasure(BakersDozen):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
cards = BakersDozen._shuffleHook(self, cards) cards = BakersDozen._shuffleHook(self, cards)
# move 2 Aces to bottom of the Talon (i.e. last cards to be dealt) # move 2 Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == 0, c.suit), 2) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == 0, c.suit), 2)
def startGame(self): def startGame(self):
CastlesInSpain.startGame(self, flip=(1, 1, 1, 1)) CastlesInSpain.startGame(self, flip=(1, 1, 1, 1))
@ -191,8 +204,8 @@ class GoodMeasure(BakersDozen):
class Cruel_Talon(TalonStack): class Cruel_Talon(TalonStack):
def canDealCards(self): def canDealCards(self):
## FIXME: this is to avoid loops in the demo # FIXME: this is to avoid loops in the demo
#if self.game.demo and self.game.moves.index >= 100: # if self.game.demo and self.game.moves.index >= 100:
# return False # return False
if self.round == self.max_rounds: if self.round == self.max_rounds:
return False return False
@ -222,7 +235,7 @@ class Cruel_Talon(TalonStack):
deal[i] = deal[i] + 1 deal[i] = deal[i] + 1
i = (i + 1) % lr i = (i + 1) % lr
extra_cards = extra_cards - 1 extra_cards = extra_cards - 1
##print n, deal # print n, deal
self.game.startDealSample() self.game.startDealSample()
for i in range(lr): for i in range(lr):
k = min(deal[i], n) k = min(deal[i], n)
@ -241,7 +254,7 @@ class Cruel_Talon(TalonStack):
class Cruel(CastlesInSpain): class Cruel(CastlesInSpain):
Talon_Class = StackWrapper(Cruel_Talon, max_rounds=-1) Talon_Class = StackWrapper(Cruel_Talon, max_rounds=-1)
RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK) RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK)
##Solver_Class = FreeCellSolverWrapper(preset='cruel') # Solver_Class = FreeCellSolverWrapper(preset='cruel')
Solver_Class = None Solver_Class = None
def createGame(self): def createGame(self):
@ -249,7 +262,8 @@ class Cruel(CastlesInSpain):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # 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)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == 0, c.suit))
def startGame(self): def startGame(self):
CastlesInSpain.startGame(self, flip=(1, 1, 1)) CastlesInSpain.startGame(self, flip=(1, 1, 1))
@ -272,10 +286,10 @@ class RoyalFamily(Cruel):
l = Cruel.createGame(self) l = Cruel.createGame(self)
l.createRoundText(self.s.talon, 'sw') l.createRoundText(self.s.talon, 'sw')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Kings to bottom of the Talon (i.e. last cards to be dealt) # move Kings to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == KING, c.suit)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == KING, c.suit))
shallHighlightMatch = Game._shallHighlightMatch_AC shallHighlightMatch = Game._shallHighlightMatch_AC
@ -291,7 +305,8 @@ class Indefatigable(Cruel):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # move Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == ACE, c.suit)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == ACE, c.suit))
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
@ -313,13 +328,13 @@ class Perseverance(Cruel, BakersDozen):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Kings to bottom of each stack (???) # move Kings to bottom of each stack (???)
#cards = BakersDozen._shuffleHook(self, cards) # cards = BakersDozen._shuffleHook(self, cards)
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # move Aces to bottom of the Talon (i.e. last cards to be dealt)
cards = Cruel._shuffleHook(self, cards) cards = Cruel._shuffleHook(self, cards)
return cards return cards
## def dealCards(self, sound=True): # def dealCards(self, sound=True):
## Cruel.dealCards(self, sound) # Cruel.dealCards(self, sound)
# ************************************************************************ # ************************************************************************
@ -337,7 +352,8 @@ class RippleFan(CastlesInSpain):
# create stacks # create stacks
s.talon = Cruel_Talon(l.s.talon.x, l.s.talon.y, self, max_rounds=-1) s.talon = Cruel_Talon(l.s.talon.x, l.s.talon.y, self, max_rounds=-1)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(SS_FoundationStack(r.x, r.y, self, suit=r.suit)) s.foundations.append(
SS_FoundationStack(r.x, r.y, self, suit=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(SS_RowStack(r.x, r.y, self, base_rank=NO_RANK)) s.rows.append(SS_RowStack(r.x, r.y, self, base_rank=NO_RANK))
# default # default
@ -355,22 +371,29 @@ registerGame(GameInfo(83, CastlesInSpain, "Castles in Spain",
registerGame(GameInfo(84, Martha, "Martha", registerGame(GameInfo(84, Martha, "Martha",
GI.GT_BAKERS_DOZEN, 1, 0, GI.SL_BALANCED)) GI.GT_BAKERS_DOZEN, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(31, BakersDozen, "Baker's Dozen", registerGame(GameInfo(31, BakersDozen, "Baker's Dozen",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(85, SpanishPatience, "Spanish Patience", registerGame(GameInfo(85, SpanishPatience, "Spanish Patience",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(86, GoodMeasure, "Good Measure", registerGame(GameInfo(86, GoodMeasure, "Good Measure",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(104, Cruel, "Cruel", registerGame(GameInfo(104, Cruel, "Cruel",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, -1, GI.SL_BALANCED)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, -1, GI.SL_BALANCED))
registerGame(GameInfo(291, RoyalFamily, "Royal Family", registerGame(GameInfo(291, RoyalFamily, "Royal Family",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 1, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 1,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(308, PortugueseSolitaire, "Portuguese Solitaire", registerGame(GameInfo(308, PortugueseSolitaire, "Portuguese Solitaire",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(404, Perseverance, "Perseverance", registerGame(GameInfo(404, Perseverance, "Perseverance",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 2, GI.SL_BALANCED)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 2, GI.SL_BALANCED))
registerGame(GameInfo(369, RippleFan, "Ripple Fan", registerGame(GameInfo(369, RippleFan, "Ripple Fan",
GI.GT_BAKERS_DOZEN, 1, -1, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN, 1, -1, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(515, Indefatigable, "Indefatigable", registerGame(GameInfo(515, Indefatigable, "Indefatigable",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 2, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 2,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(664, SpanishPatienceII, "Spanish Patience II", registerGame(GameInfo(664, SpanishPatienceII, "Spanish Patience II",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))

View file

@ -24,16 +24,24 @@
__all__ = [] __all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.util import KING
from pysollib.stack import \
AC_RowStack, \
FreeCell_SS_RowStack, \
InitialDealTalonStack, \
KingSS_RowStack, \
OpenStack, \
ReserveStack, \
SS_FoundationStack, \
SS_RowStack, \
SuperMoveSS_RowStack, \
StackWrapper
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import DefaultHint
from pysollib.hint import FreeCellType_Hint, FreeCellSolverWrapper from pysollib.hint import FreeCellType_Hint, FreeCellSolverWrapper
from pysollib.games.freecell import FreeCell from pysollib.games.freecell import FreeCell
@ -42,6 +50,7 @@ from pysollib.games.freecell import FreeCell
# * Baker's Game # * Baker's Game
# ************************************************************************ # ************************************************************************
class BakersGame(FreeCell): class BakersGame(FreeCell):
RowStack_Class = SuperMoveSS_RowStack RowStack_Class = SuperMoveSS_RowStack
Solver_Class = FreeCellSolverWrapper(sbb='suit') Solver_Class = FreeCellSolverWrapper(sbb='suit')
@ -72,7 +81,8 @@ class EightOff(KingOnlyBakersGame):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
# (piles up to 16 cards are playable without overlap in default window size) # (piles up to 16 cards are playable without
# overlap in default window size)
h = max(2*l.YS, l.YS+(16-1)*l.YOFFSET) h = max(2*l.YS, l.YS+(16-1)*l.YOFFSET)
maxrows = max(rows, reserves) maxrows = max(rows, reserves)
self.setSize(l.XM + maxrows*l.XS, l.YM + l.YS + h + l.YS) self.setSize(l.XM + maxrows*l.XS, l.YM + l.YS + h + l.YS)
@ -106,7 +116,7 @@ class EightOff(KingOnlyBakersGame):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow() self.s.talon.dealRow()
r = self.s.reserves r = self.s.reserves
self.s.talon.dealRow(rows=[r[0],r[2],r[4],r[6]]) self.s.talon.dealRow(rows=[r[0], r[2], r[4], r[6]])
# ************************************************************************ # ************************************************************************
@ -166,7 +176,8 @@ class SeahavenTowers(KingOnlyBakersGame):
class RelaxedSeahavenTowers(SeahavenTowers): class RelaxedSeahavenTowers(SeahavenTowers):
RowStack_Class = KingSS_RowStack RowStack_Class = KingSS_RowStack
Solver_Class = FreeCellSolverWrapper(sbb='suit', esf='kings', sm='unlimited') Solver_Class = FreeCellSolverWrapper(
sbb='suit', esf='kings', sm='unlimited')
# ************************************************************************ # ************************************************************************
@ -188,7 +199,8 @@ class Tuxedo(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
# (piles up to 16 cards are playable without overlap in default window size) # (piles up to 16 cards are playable without
# overlap in default window size)
h = max(3*l.YS, l.YS+(16-1)*l.YOFFSET) h = max(3*l.YS, l.YS+(16-1)*l.YOFFSET)
maxrows = max(rows, reserves) maxrows = max(rows, reserves)
self.setSize(l.XM + (maxrows+1)*l.XS, l.YM + h + l.YS) self.setSize(l.XM + (maxrows+1)*l.XS, l.YM + h + l.YS)
@ -228,11 +240,13 @@ class Tuxedo(Game):
class Penguin(Tuxedo): class Penguin(Tuxedo):
GAME_VERSION = 2 GAME_VERSION = 2
Solver_Class = FreeCellSolverWrapper(sbb='suit', esf='kings', sm='unlimited') Solver_Class = FreeCellSolverWrapper(
sbb='suit', esf='kings', sm='unlimited')
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move base cards to top of the Talon (i.e. first cards to be dealt) # move base cards to top of the Talon (i.e. first cards to be dealt)
return self._shuffleHookMoveToTop(cards, return self._shuffleHookMoveToTop(
cards,
lambda c, rank=cards[-1].rank: (c.rank == rank, 0)) lambda c, rank=cards[-1].rank: (c.rank == rank, 0))
def _updateStacks(self): def _updateStacks(self):
@ -274,7 +288,6 @@ class Opus(Penguin):
Tuxedo.createGame(self, reserves=5) Tuxedo.createGame(self, reserves=5)
# ************************************************************************ # ************************************************************************
# * Flipper # * Flipper
# ************************************************************************ # ************************************************************************
@ -307,7 +320,6 @@ class Flipper(Tuxedo):
shallHighlightMatch = Game._shallHighlightMatch_AC shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game # register the game
registerGame(GameInfo(45, BakersGame, "Baker's Game", registerGame(GameInfo(45, BakersGame, "Baker's Game",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_SKILL)) GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_SKILL))
@ -317,15 +329,17 @@ registerGame(GameInfo(258, EightOff, "Eight Off",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(9, SeahavenTowers, "Seahaven Towers", registerGame(GameInfo(9, SeahavenTowers, "Seahaven Towers",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_SKILL, GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_SKILL,
altnames=("Sea Towers", "Towers") )) altnames=("Sea Towers", "Towers")))
registerGame(GameInfo(6, RelaxedSeahavenTowers, "Relaxed Seahaven Towers", registerGame(GameInfo(6, RelaxedSeahavenTowers, "Relaxed Seahaven Towers",
GI.GT_FREECELL | GI.GT_RELAXED | GI.GT_OPEN, 1, 0, GI.SL_SKILL)) GI.GT_FREECELL | GI.GT_RELAXED | GI.GT_OPEN, 1, 0,
GI.SL_SKILL))
registerGame(GameInfo(64, Penguin, "Penguin", registerGame(GameInfo(64, Penguin, "Penguin",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL, GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL,
altnames=("Beak and Flipper",) )) altnames=("Beak and Flipper",)))
registerGame(GameInfo(427, Opus, "Opus", registerGame(GameInfo(427, Opus, "Opus",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(629, Tuxedo, "Tuxedo", registerGame(GameInfo(629, Tuxedo, "Tuxedo",
GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(713, Flipper, "Flipper", registerGame(GameInfo(713, Flipper, "Flipper",
GI.GT_FREECELL | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_ORIGINAL, 1, 0,
GI.SL_MOSTLY_SKILL))

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,18 +19,30 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
__all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import ACE, ANY_RANK, NO_RANK, KING, QUEEN, RANKS
from pysollib.stack import \
InitialDealTalonStack, \
OpenStack, \
ReserveStack, \
RK_FoundationStack, \
RK_RowStack, \
Spider_SS_RowStack, \
SS_FoundationStack, \
SuperMoveRK_RowStack, \
TalonStack, \
UD_AC_RowStack, \
UD_RK_RowStack, \
UD_SS_RowStack, \
WasteStack, \
WasteTalonStack, \
StackWrapper
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import CautiousDefaultHint, FreeCellType_Hint from pysollib.hint import CautiousDefaultHint, FreeCellType_Hint
@ -56,7 +68,7 @@ class StreetsAndAlleys(Game):
Solver_Class = FreeCellSolverWrapper(preset='streets_and_alleys') Solver_Class = FreeCellSolverWrapper(preset='streets_and_alleys')
Foundation_Class = SS_FoundationStack Foundation_Class = SS_FoundationStack
##RowStack_Class = RK_RowStack # RowStack_Class = RK_RowStack
RowStack_Class = SuperMoveRK_RowStack RowStack_Class = SuperMoveRK_RowStack
# #
@ -74,7 +86,7 @@ class StreetsAndAlleys(Game):
x1 = x0 + w + 2*l.XM x1 = x0 + w + 2*l.XM
x2 = x1 + l.XS + 2*l.XM x2 = x1 + l.XS + 2*l.XM
x3 = x2 + w + l.XM x3 = x2 + w + l.XM
h = l.YM + (4+int(reserves!=0))*l.YS + int(texts)*l.TEXT_HEIGHT h = l.YM + (4+int(reserves != 0))*l.YS + int(texts)*l.TEXT_HEIGHT
self.setSize(x3, h) self.setSize(x3, h)
# create stacks # create stacks
@ -87,7 +99,8 @@ class StreetsAndAlleys(Game):
y += l.YS y += l.YS
x = x1 x = x1
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0)) s.foundations.append(
self.Foundation_Class(x, y, self, suit=i, max_move=0))
y += l.YS y += l.YS
if texts: if texts:
tx, ty, ta, tf = l.getTextAttr(None, "ss") tx, ty, ta, tf = l.getTextAttr(None, "ss")
@ -96,7 +109,7 @@ class StreetsAndAlleys(Game):
self.texts.info = MfxCanvasText(self.canvas, tx, ty, self.texts.info = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font) anchor=ta, font=font)
for x in (x0, x2): for x in (x0, x2):
y = l.YM+l.YS*int(reserves!=0) y = l.YM+l.YS*int(reserves != 0)
for i in range(4): for i in range(4):
stack = self.RowStack_Class(x, y, self) stack = self.RowStack_Class(x, y, self)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
@ -105,7 +118,8 @@ class StreetsAndAlleys(Game):
x, y = self.width - l.XS, self.height - l.YS x, y = self.width - l.XS, self.height - l.YS
s.talon = InitialDealTalonStack(x, y, self) s.talon = InitialDealTalonStack(x, y, self)
if reserves: if reserves:
l.setRegion(s.rows[:4], (-999, l.YM+l.YS-l.CH/2, x1-l.CW/2, 999999)) l.setRegion(
s.rows[:4], (-999, l.YM+l.YS-l.CH/2, x1-l.CW/2, 999999))
else: else:
l.setRegion(s.rows[:4], (-999, -999, x1-l.CW/2, 999999)) l.setRegion(s.rows[:4], (-999, -999, x1-l.CW/2, 999999))
@ -133,7 +147,8 @@ class StreetsAndAlleys(Game):
class BeleagueredCastle(StreetsAndAlleys): class BeleagueredCastle(StreetsAndAlleys):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # 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)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == 0, c.suit))
def startGame(self): def startGame(self):
for i in range(4): for i in range(4):
@ -152,7 +167,8 @@ class BeleagueredCastle(StreetsAndAlleys):
class Citadel(StreetsAndAlleys): class Citadel(StreetsAndAlleys):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to top of the Talon (i.e. first cards to be dealt) # 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)) return self._shuffleHookMoveToTop(
cards, lambda c: (c.rank == 0, c.suit))
# move cards to the Foundations during dealing # move cards to the Foundations during dealing
def startGame(self): def startGame(self):
@ -205,14 +221,14 @@ class Fortress(Game):
if l.s.waste: if l.s.waste:
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, suit=r.suit)) s.foundations.append(
self.Foundation_Class(r.x, r.y, self, suit=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self)) s.rows.append(self.RowStack_Class(r.x, r.y, self))
# default # default
l.defaultAll() l.defaultAll()
return l return l
# #
# game overrides # game overrides
# #
@ -254,7 +270,8 @@ class Bastion(Game):
# create stacks # create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, suit=r.suit)) s.foundations.append(
self.Foundation_Class(r.x, r.y, self, suit=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self)) s.rows.append(self.RowStack_Class(r.x, r.y, self))
for r in l.s.reserves: for r in l.s.reserves:
@ -263,7 +280,6 @@ class Bastion(Game):
l.defaultAll() l.defaultAll()
return l return l
# #
# game overrides # game overrides
# #
@ -276,13 +292,13 @@ class Bastion(Game):
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow(rows=self.s.reserves)
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
class TenByOne(Bastion): class TenByOne(Bastion):
def createGame(self): def createGame(self):
Bastion.createGame(self, reserves=1) Bastion.createGame(self, reserves=1)
def startGame(self): def startGame(self):
for i in range(3): for i in range(3):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
@ -299,6 +315,7 @@ class CastlesEnd_Foundation(SS_FoundationStack):
return True return True
return SS_FoundationStack.acceptsCards(self, from_stack, cards) return SS_FoundationStack.acceptsCards(self, from_stack, cards)
class CastlesEnd_StackMethods: class CastlesEnd_StackMethods:
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
state = self.game.getState() state = self.game.getState()
@ -311,12 +328,14 @@ class CastlesEnd_StackMethods:
s.cap.base_rank = base_rank s.cap.base_rank = base_rank
self.fillStack() self.fillStack()
class CastlesEnd_RowStack(CastlesEnd_StackMethods, UD_AC_RowStack): class CastlesEnd_RowStack(CastlesEnd_StackMethods, UD_AC_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if self.game.getState() == 0: if self.game.getState() == 0:
return False return False
return UD_AC_RowStack.acceptsCards(self, from_stack, cards) return UD_AC_RowStack.acceptsCards(self, from_stack, cards)
class CastlesEnd_Reserve(CastlesEnd_StackMethods, OpenStack): class CastlesEnd_Reserve(CastlesEnd_StackMethods, OpenStack):
pass pass
@ -407,7 +426,8 @@ class Chessboard(Fortress):
l = Fortress.createGame(self) l = Fortress.createGame(self)
tx, ty, ta, tf = l.getTextAttr(self.s.foundations[-1], "e") tx, ty, ta, tf = l.getTextAttr(self.s.foundations[-1], "e")
font = self.app.getFont("canvas_default") font = self.app.getFont("canvas_default")
self.texts.info = MfxCanvasText(self.canvas, tx + l.XM, ty, anchor=ta, font=font) self.texts.info = MfxCanvasText(
self.canvas, tx + l.XM, ty, anchor=ta, font=font)
def updateText(self): def updateText(self):
if self.preview > 1: if self.preview > 1:
@ -428,12 +448,15 @@ class Chessboard(Fortress):
class Stronghold(StreetsAndAlleys): class Stronghold(StreetsAndAlleys):
Hint_Class = FreeCellType_Hint Hint_Class = FreeCellType_Hint
Solver_Class = FreeCellSolverWrapper(sbb='rank') Solver_Class = FreeCellSolverWrapper(sbb='rank')
def createGame(self): def createGame(self):
StreetsAndAlleys.createGame(self, reserves=1) StreetsAndAlleys.createGame(self, reserves=1)
class Fastness(StreetsAndAlleys): class Fastness(StreetsAndAlleys):
Hint_Class = FreeCellType_Hint Hint_Class = FreeCellType_Hint
Solver_Class = FreeCellSolverWrapper(sbb='rank') Solver_Class = FreeCellSolverWrapper(sbb='rank')
def createGame(self): def createGame(self):
StreetsAndAlleys.createGame(self, reserves=2) StreetsAndAlleys.createGame(self, reserves=2)
@ -446,7 +469,8 @@ class Zerline_ReserveStack(ReserveStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not ReserveStack.acceptsCards(self, from_stack, cards): if not ReserveStack.acceptsCards(self, from_stack, cards):
return False return False
return not from_stack is self.game.s.waste return from_stack is not self.game.s.waste
class Zerline(Game): class Zerline(Game):
Hint_Class = BeleagueredCastleType_Hint Hint_Class = BeleagueredCastleType_Hint
@ -482,7 +506,9 @@ class Zerline(Game):
for j in range(decks): for j in range(decks):
y = l.YM+l.TEXT_HEIGHT+l.YS y = l.YM+l.TEXT_HEIGHT+l.YS
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, i, s.foundations.append(
SS_FoundationStack(
x, y, self, i,
base_rank=KING, dir=1, max_move=0, mod=13)) base_rank=KING, dir=1, max_move=0, mod=13))
y += l.YS y += l.YS
x += l.XS x += l.XS
@ -490,13 +516,16 @@ class Zerline(Game):
for j in range(2): for j in range(2):
y = l.YM+l.TEXT_HEIGHT+l.YS y = l.YM+l.TEXT_HEIGHT+l.YS
for i in range(rows/2): for i in range(rows/2):
stack = RK_RowStack(x, y, self, max_move=1, max_accept=1, base_rank=QUEEN) stack = RK_RowStack(
x, y, self, max_move=1, max_accept=1, base_rank=QUEEN)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
s.rows.append(stack) s.rows.append(stack)
y += l.YS y += l.YS
x += l.XM+w+decks*l.XS x += l.XM+w+decks*l.XS
l.setRegion(s.rows[:4], (-999, l.YM+l.YS+l.TEXT_HEIGHT-l.CH/2, w-l.CW/2, 999999)) l.setRegion(
s.rows[:4], (-999, l.YM+l.YS+l.TEXT_HEIGHT-l.CH/2,
w-l.CW/2, 999999))
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -612,10 +641,11 @@ class CastleOfIndolence(Game):
max_move=0)) max_move=0))
y += l.YS y += l.YS
for x in (l.XM, l.XM + w +2*l.XS): for x in (l.XM, l.XM + w + 2*l.XS):
y = l.YM y = l.YM
for i in range(4): for i in range(4):
stack = RK_RowStack(x, y, self, max_move=1, max_accept=1, base_rank=ANY_RANK) stack = RK_RowStack(
x, y, self, max_move=1, max_accept=1, base_rank=ANY_RANK)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
s.rows.append(stack) s.rows.append(stack)
y += l.YS y += l.YS
@ -671,7 +701,8 @@ class Rittenhouse(Game):
# create stacks # create stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
for i in range(4): for i in range(4):
s.foundations.append(Rittenhouse_Foundation(x, y, self, max_move=0)) s.foundations.append(
Rittenhouse_Foundation(x, y, self, max_move=0))
x += l.XS x += l.XS
x += l.XS x += l.XS
for i in range(4): for i in range(4):
@ -688,7 +719,6 @@ class Rittenhouse(Game):
# default # default
l.defaultAll() l.defaultAll()
def startGame(self): def startGame(self):
# move cards to the Foundations during dealing # move cards to the Foundations during dealing
talon = self.s.talon talon = self.s.talon
@ -743,7 +773,8 @@ class Lightweight(StreetsAndAlleys):
for i in range(rows): for i in range(rows):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x += l.XS x += l.XS
s.talon = InitialDealTalonStack(self.width-l.XS, self.height-l.YS, self) s.talon = InitialDealTalonStack(
self.width-l.XS, self.height-l.YS, self)
l.defaultAll() l.defaultAll()
@ -783,6 +814,7 @@ class SelectiveCastle_RowStack(RK_RowStack):
return RK_RowStack.canDropCards(self, stacks) return RK_RowStack.canDropCards(self, stacks)
return (None, 0) return (None, 0)
class SelectiveCastle(StreetsAndAlleys, Chessboard): class SelectiveCastle(StreetsAndAlleys, Chessboard):
Foundation_Class = Chessboard_Foundation Foundation_Class = Chessboard_Foundation
RowStack_Class = StackWrapper(SelectiveCastle_RowStack, mod=13) RowStack_Class = StackWrapper(SelectiveCastle_RowStack, mod=13)
@ -819,7 +851,8 @@ class Soother(Game):
for i in range(2): for i in range(2):
x = l.XM+2.5*l.XS x = l.XM+2.5*l.XS
for j in range(8): for j in range(8):
s.foundations.append(SS_FoundationStack(x, y, self, suit=j%4, max_move=1)) s.foundations.append(
SS_FoundationStack(x, y, self, suit=j % 4, max_move=1))
x += l.XS x += l.XS
y += l.YS y += l.YS
x, y = l.XM, l.YM+2*l.YS x, y = l.XM, l.YM+2*l.YS
@ -835,7 +868,6 @@ class Soother(Game):
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
for i in range(4): for i in range(4):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
@ -860,44 +892,62 @@ class PenelopesWeb(StreetsAndAlleys):
# register the game # register the game
registerGame(GameInfo(146, StreetsAndAlleys, "Streets and Alleys", registerGame(GameInfo(146, StreetsAndAlleys, "Streets and Alleys",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(34, BeleagueredCastle, "Beleaguered Castle", registerGame(GameInfo(34, BeleagueredCastle, "Beleaguered Castle",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(145, Citadel, "Citadel", registerGame(GameInfo(145, Citadel, "Citadel",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(147, Fortress, "Fortress", registerGame(GameInfo(147, Fortress, "Fortress",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_SKILL))
registerGame(GameInfo(148, Chessboard, "Chessboard", registerGame(GameInfo(148, Chessboard, "Chessboard",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_SKILL))
registerGame(GameInfo(300, Stronghold, "Stronghold", registerGame(GameInfo(300, Stronghold, "Stronghold",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(301, Fastness, "Fastness", registerGame(GameInfo(301, Fastness, "Fastness",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN | GI.GT_ORIGINAL,
1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(306, Zerline, "Zerline", registerGame(GameInfo(306, Zerline, "Zerline",
GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(324, Bastion, "Bastion", registerGame(GameInfo(324, Bastion, "Bastion",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(325, TenByOne, "Ten by One", registerGame(GameInfo(325, TenByOne, "Ten by One",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(351, Chequers, "Chequers", registerGame(GameInfo(351, Chequers, "Chequers",
GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(393, CastleOfIndolence, "Castle of Indolence", registerGame(GameInfo(393, CastleOfIndolence, "Castle of Indolence",
GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(395, Zerline3Decks, "Zerline (3 decks)", registerGame(GameInfo(395, Zerline3Decks, "Zerline (3 decks)",
GI.GT_BELEAGUERED_CASTLE | GI.GT_ORIGINAL, 3, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_ORIGINAL, 3, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(400, Rittenhouse, "Rittenhouse", registerGame(GameInfo(400, Rittenhouse, "Rittenhouse",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 2, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(507, Lightweight, "Lightweight", registerGame(GameInfo(507, Lightweight, "Lightweight",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN | GI.GT_ORIGINAL,
2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(508, CastleMount, "Castle Mount", registerGame(GameInfo(508, CastleMount, "Castle Mount",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 3, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 3, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(524, SelectiveCastle, "Selective Castle", registerGame(GameInfo(524, SelectiveCastle, "Selective Castle",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(535, ExiledKings, "Exiled Kings", registerGame(GameInfo(535, ExiledKings, "Exiled Kings",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(626, Soother, "Soother", registerGame(GameInfo(626, Soother, "Soother",
GI.GT_4DECK_TYPE | GI.GT_ORIGINAL, 4, 0, GI.SL_MOSTLY_SKILL)) GI.GT_4DECK_TYPE | GI.GT_ORIGINAL, 4, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(650, CastlesEnd, "Castles End", registerGame(GameInfo(650, CastlesEnd, "Castles End",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(665, PenelopesWeb, "Penelope's Web", registerGame(GameInfo(665, PenelopesWeb, "Penelope's Web",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL))

View file

@ -21,19 +21,26 @@
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
__all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import ACE, NO_RANK, KING, RANKS, UNLIMITED_REDEALS
from pysollib.mfxutil import kwdefault from pysollib.stack import \
from pysollib.stack import * AC_RowStack, \
BasicRowStack, \
InitialDealTalonStack, \
ReserveStack, \
SS_FoundationStack, \
UD_AC_RowStack, \
UD_RK_RowStack, \
UD_SS_RowStack, \
WasteStack, \
WasteTalonStack, \
StackWrapper
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
@ -91,7 +98,8 @@ class Bisley(Game):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Aces to bottom of the Talon (i.e. last cards to be dealt) # move Aces to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == ACE, c.suit)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == ACE, c.suit))
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
@ -128,7 +136,9 @@ class DoubleBisley(Bisley):
s.foundations.append(SS_FoundationStack(x, y, self, s.foundations.append(SS_FoundationStack(x, y, self,
suit=j*2+i/2, max_move=0)) suit=j*2+i/2, max_move=0))
x += l.XS x += l.XS
s.foundations.append(SS_FoundationStack(x, y, self, s.foundations.append(
SS_FoundationStack(
x, y, self,
suit=j*2+i/2, base_rank=KING, max_move=0, dir=-1)) suit=j*2+i/2, base_rank=KING, max_move=0, dir=-1))
y += l.YS y += l.YS
@ -165,7 +175,8 @@ class Gloria(Game):
for j in range(2): for j in range(2):
for i in range(4): for i in range(4):
y = l.YM y = l.YM
s.foundations.append(SS_FoundationStack(x, y, self, suit=j*2+i/2)) s.foundations.append(
SS_FoundationStack(x, y, self, suit=j*2+i/2))
y += l.YS y += l.YS
s.foundations.append(SS_FoundationStack(x, y, self, s.foundations.append(SS_FoundationStack(x, y, self,
suit=j*2+i/2, base_rank=KING, dir=-1)) suit=j*2+i/2, base_rank=KING, dir=-1))
@ -188,7 +199,8 @@ class Gloria(Game):
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move Kings to bottom of the Talon (i.e. last cards to be dealt) # move Kings to bottom of the Talon (i.e. last cards to be dealt)
return self._shuffleHookMoveToBottom(cards, lambda c: (c.rank == KING, c.suit)) return self._shuffleHookMoveToBottom(
cards, lambda c: (c.rank == KING, c.suit))
# ************************************************************************ # ************************************************************************
@ -277,7 +289,6 @@ class HospitalPatience(Game):
self.s.talon.dealCards() # deal first card to WasteStack self.s.talon.dealCards() # deal first card to WasteStack
# ************************************************************************ # ************************************************************************
# * Board Patience # * Board Patience
# ************************************************************************ # ************************************************************************
@ -398,7 +409,6 @@ class Cringle(Game):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
for i in range(4): for i in range(4):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
@ -409,24 +419,24 @@ class Cringle(Game):
shallHighlightMatch = Game._shallHighlightMatch_AC shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game # register the game
registerGame(GameInfo(290, Bisley, "Bisley", registerGame(GameInfo(290, Bisley, "Bisley",
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(372, DoubleBisley, "Double Bisley", registerGame(GameInfo(372, DoubleBisley, "Double Bisley",
GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL,
2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(373, Gloria, "Gloria", registerGame(GameInfo(373, Gloria, "Gloria",
GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL,
2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(374, Realm, "Realm", registerGame(GameInfo(374, Realm, "Realm",
GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL,
1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(375, Mancunian, "Mancunian", registerGame(GameInfo(375, Mancunian, "Mancunian",
GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL,
1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(686, HospitalPatience, "Hospital Patience", registerGame(GameInfo(686, HospitalPatience, "Hospital Patience",
GI.GT_1DECK_TYPE, 1, -1, GI.SL_MOSTLY_LUCK)) GI.GT_1DECK_TYPE, 1, -1, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(692, BoardPatience, "Board Patience", registerGame(GameInfo(692, BoardPatience, "Board Patience",
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(747, Cringle, "Cringle", registerGame(GameInfo(747, Cringle, "Cringle",
GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,28 +19,38 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
__all__ = []
# imports # imports
import sys, math import math
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import ACE, NO_RANK, KING, RANKS, UNLIMITED_CARDS
from pysollib.stack import \
AbstractFoundationStack, \
BasicRowStack, \
DealRowRedealTalonStack, \
OpenStack, \
ReserveStack, \
SS_FoundationStack, \
SS_RowStack, \
WasteStack, \
WasteTalonStack, \
Stack, \
StackWrapper
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class Braid_Hint(DefaultHint): class Braid_Hint(DefaultHint):
# FIXME: demo is not too clever in this game # FIXME: demo is not too clever in this game
pass pass
@ -49,6 +59,7 @@ class Braid_Hint(DefaultHint):
# * # *
# ************************************************************************ # ************************************************************************
class Braid_Foundation(AbstractFoundationStack): class Braid_Foundation(AbstractFoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
kwdefault(cap, mod=13, dir=0, base_rank=NO_RANK, max_move=0) kwdefault(cap, mod=13, dir=0, base_rank=NO_RANK, max_move=0)
@ -64,7 +75,8 @@ class Braid_Foundation(AbstractFoundationStack):
card_dir = self.getRankDir(cards=(self.cards[-1], cards[0])) card_dir = self.getRankDir(cards=(self.cards[-1], cards[0]))
return card_dir in (1, -1) return card_dir in (1, -1)
else: else:
return (self.cards[-1].rank + stack_dir) % self.cap.mod == cards[0].rank return ((self.cards[-1].rank + stack_dir) %
self.cap.mod == cards[0].rank)
class Braid_BraidStack(OpenStack): class Braid_BraidStack(OpenStack):
@ -80,7 +92,7 @@ class Braid_BraidStack(OpenStack):
last_x = 0 last_x = 0
for i in range(n): for i in range(n):
x = int(round(dx * math.sin(i + 1))) x = int(round(dx * math.sin(i + 1)))
##print x, x - last_x # print x, x - last_x
self.CARD_XOFFSET.append(x - last_x) self.CARD_XOFFSET.append(x - last_x)
last_x = x last_x = x
else: else:
@ -122,7 +134,7 @@ class Braid(Game):
def createGame(self): def createGame(self):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
font=self.app.getFont("canvas_default") font = self.app.getFont("canvas_default")
# set window # set window
# (piles up to 20 cards are playable - needed for Braid_BraidStack) # (piles up to 20 cards are playable - needed for Braid_BraidStack)
@ -172,7 +184,6 @@ class Braid(Game):
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
self.sg.dropstacks = [s.braid] + s.rows + [s.waste] self.sg.dropstacks = [s.braid] + s.rows + [s.waste]
# #
# game overrides # game overrides
# #
@ -220,7 +231,6 @@ class Braid(Game):
def _saveGameHook(self, p): def _saveGameHook(self, p):
p.dump(self.base_card.id) p.dump(self.base_card.id)
# #
# game extras # game extras
# #
@ -251,20 +261,25 @@ class LongBraid(Braid):
class Fort(Braid): class Fort(Braid):
Foundation_Classes = [SS_FoundationStack, Foundation_Classes = [SS_FoundationStack,
StackWrapper(SS_FoundationStack, base_rank=KING, dir=-1)] StackWrapper(SS_FoundationStack, base_rank=KING,
dir=-1)]
BRAID_CARDS = 21 BRAID_CARDS = 21
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
# move 4 Kings and 4 Aces to top of the Talon # move 4 Kings and 4 Aces to top of the Talon
# (i.e. first cards to be dealt) # (i.e. first cards to be dealt)
return self._shuffleHookMoveToTop(cards, return self._shuffleHookMoveToTop(
lambda c: (c.rank in (ACE, KING) and c.deck == 0, (c.suit, c.rank))) cards,
lambda c: (c.rank in (ACE, KING) and c.deck == 0,
(c.suit, c.rank)))
def _restoreGameHook(self, game): def _restoreGameHook(self, game):
pass pass
def _loadGameHook(self, p): def _loadGameHook(self, p):
pass pass
def _saveGameHook(self, p): def _saveGameHook(self, p):
pass pass
@ -299,15 +314,16 @@ class Backbone(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
w, h = l.XM+(rows+2)*l.XS, max(l.YM+3*l.XS+10*l.YOFFSET, l.YM+2*l.YS+11*l.YOFFSET+l.TEXT_HEIGHT) w, h = l.XM+(rows+2)*l.XS, max(
l.YM+3*l.XS+10*l.YOFFSET, l.YM+2*l.YS+11*l.YOFFSET+l.TEXT_HEIGHT)
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
y = l.YM y = l.YM
for i in range(4): for i in range(4):
x = l.XM+(rows-8)*l.XS/2 +i*l.XS x = l.XM+(rows-8)*l.XS/2 + i*l.XS
s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x = l.XM+(rows/2+2)*l.XS +i*l.XS x = l.XM+(rows/2+2)*l.XS + i*l.XS
s.foundations.append(SS_FoundationStack(x, y, self, suit=i)) s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x, y = l.XM+rows*l.XS/2, l.YM x, y = l.XM+rows*l.XS/2, l.YM
@ -336,7 +352,6 @@ class Backbone(Game):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
for i in range(10): for i in range(10):
self.s.talon.dealRow(rows=self.s.reserves[:2], frames=0) self.s.talon.dealRow(rows=self.s.reserves[:2], frames=0)
@ -435,9 +450,9 @@ class Casket(Game):
# Casket # Casket
x0, y0 = l.XM+3*l.XS, l.YM+1.5*l.YS x0, y0 = l.XM+3*l.XS, l.YM+1.5*l.YS
for xx, yy in ((0,0), (3,0), for xx, yy in ((0, 0), (3, 0),
(0,1), (3,1), (0, 1), (3, 1),
(0,2),(1,2),(2,2),(3,2), (0, 2), (1, 2), (2, 2), (3, 2),
): ):
x, y = x0+xx*l.XS, y0+yy*l.YS x, y = x0+xx*l.XS, y0+yy*l.YS
stack = Casket_RowStack(x, y, self, max_move=1) stack = Casket_RowStack(x, y, self, max_move=1)
@ -478,7 +493,6 @@ class Casket(Game):
self.sg.openstacks = s.foundations + s.rows + s.reserves self.sg.openstacks = s.foundations + s.rows + s.reserves
self.sg.dropstacks = s.lid + s.rows + [s.waste] + s.reserves self.sg.dropstacks = s.lid + s.rows + [s.waste] + s.reserves
def startGame(self): def startGame(self):
for i in range(13): for i in range(13):
self.s.talon.dealRow(rows=[self.s.jewels], frames=0, flip=0) self.s.talon.dealRow(rows=[self.s.jewels], frames=0, flip=0)
@ -505,7 +519,8 @@ class Casket(Game):
class Well_TalonStack(DealRowRedealTalonStack): class Well_TalonStack(DealRowRedealTalonStack):
def canDealCards(self): def canDealCards(self):
return DealRowRedealTalonStack.canDealCards(self, rows=self.game.s.wastes) return DealRowRedealTalonStack.canDealCards(
self, rows=self.game.s.wastes)
def dealCards(self, sound=False): def dealCards(self, sound=False):
num_cards = 0 num_cards = 0
@ -538,10 +553,10 @@ class Well(Game):
# foundations # foundations
suit = 0 suit = 0
x0, y0 = l.XM+1.5*l.XS, l.YM+1.5*l.YS+l.TEXT_HEIGHT x0, y0 = l.XM+1.5*l.XS, l.YM+1.5*l.YS+l.TEXT_HEIGHT
for xx, yy in ((3,0), for xx, yy in ((3, 0),
(0,3), (0, 3),
(3,3), (3, 3),
(0,0)): (0, 0)):
x, y = x0+xx*l.XS, y0+yy*l.YS x, y = x0+xx*l.XS, y0+yy*l.YS
s.foundations.append(SS_FoundationStack(x, y, self, suit=suit, s.foundations.append(SS_FoundationStack(x, y, self, suit=suit,
base_rank=KING, mod=13, max_cards=26, base_rank=KING, mod=13, max_cards=26,
@ -550,10 +565,10 @@ class Well(Game):
# rows # rows
x0, y0 = l.XM+l.XS, l.YM+l.YS+l.TEXT_HEIGHT x0, y0 = l.XM+l.XS, l.YM+l.YS+l.TEXT_HEIGHT
for xx, yy in ((0,2), for xx, yy in ((0, 2),
(2,0), (2, 0),
(4,2), (4, 2),
(2,4)): (2, 4)):
x, y = x0+xx*l.XS, y0+yy*l.YS x, y = x0+xx*l.XS, y0+yy*l.YS
stack = SS_RowStack(x, y, self, dir=1, mod=13, max_move=1) stack = SS_RowStack(x, y, self, dir=1, mod=13, max_move=1)
stack.getBottomImage = stack._getReserveBottomImage stack.getBottomImage = stack._getReserveBottomImage
@ -562,17 +577,18 @@ class Well(Game):
# left stack # left stack
x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT
stack = SS_RowStack(x, y, self, base_rank=ACE, dir=1, mod=13, max_move=1) stack = SS_RowStack(
x, y, self, base_rank=ACE, dir=1, mod=13, max_move=1)
stack.getBottomImage = stack._getReserveBottomImage stack.getBottomImage = stack._getReserveBottomImage
stack.CARD_YOFFSET = 0 stack.CARD_YOFFSET = 0
s.rows.append(stack) s.rows.append(stack)
# reserves # reserves
x0, y0 = l.XM+2*l.XS, l.YM+2*l.YS+l.TEXT_HEIGHT x0, y0 = l.XM+2*l.XS, l.YM+2*l.YS+l.TEXT_HEIGHT
for xx, yy, anchor in ((0,1,'e'), for xx, yy, anchor in ((0, 1, 'e'),
(1,0,'s'), (1, 0, 's'),
(2,1,'w'), (2, 1, 'w'),
(1,2,'n')): (1, 2, 'n')):
x, y = x0+xx*l.XS, y0+yy*l.YS x, y = x0+xx*l.XS, y0+yy*l.YS
stack = OpenStack(x, y, self) stack = OpenStack(x, y, self)
l.createText(stack, anchor) l.createText(stack, anchor)
@ -596,7 +612,6 @@ class Well(Game):
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
self.sg.dropstacks = s.rows + s.wastes + s.reserves self.sg.dropstacks = s.rows + s.wastes + s.reserves
def startGame(self): def startGame(self):
for i in range(10): for i in range(10):
self.s.talon.dealRow(rows=self.s.reserves, frames=0) self.s.talon.dealRow(rows=self.s.reserves, frames=0)
@ -604,7 +619,6 @@ class Well(Game):
self.s.talon.dealRow(rows=self.s.rows[:4]) self.s.talon.dealRow(rows=self.s.rows[:4])
self.s.talon.dealCards() self.s.talon.dealCards()
def fillStack(self, stack): def fillStack(self, stack):
if not stack.cards and stack in self.s.rows[:4]: if not stack.cards and stack in self.s.rows[:4]:
indx = list(self.s.rows).index(stack) indx = list(self.s.rows).index(stack)
@ -617,14 +631,13 @@ class Well(Game):
shallHighlightMatch = Game._shallHighlightMatch_SSW shallHighlightMatch = Game._shallHighlightMatch_SSW
# register the game # register the game
registerGame(GameInfo(12, Braid, "Braid", registerGame(GameInfo(12, Braid, "Braid",
GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED, GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED,
altnames=("Der Zopf", "Plait", "Pigtail") )) altnames=("Der Zopf", "Plait", "Pigtail")))
registerGame(GameInfo(175, LongBraid, "Long Braid", registerGame(GameInfo(175, LongBraid, "Long Braid",
GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED, GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED,
altnames=("Der lange Zopf",) )) altnames=("Der lange Zopf",)))
registerGame(GameInfo(358, Fort, "Fort", registerGame(GameInfo(358, Fort, "Fort",
GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED)) GI.GT_NAPOLEON, 2, 2, GI.SL_BALANCED))
registerGame(GameInfo(376, Backbone, "Backbone", registerGame(GameInfo(376, Backbone, "Backbone",

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,26 +19,38 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
__all__ = [] __all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import ACE, ANY_RANK, NO_RANK, KING, RANKS, UNLIMITED_CARDS
from pysollib.stack import * from pysollib.stack import \
AC_RowStack, \
KingAC_RowStack, \
OpenStack, \
OpenTalonStack, \
ReserveStack, \
RK_FoundationStack, \
RK_RowStack, \
SS_FoundationStack, \
SS_RowStack, \
TalonStack, \
WasteStack, \
StackWrapper
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class Bristol_Hint(CautiousDefaultHint): class Bristol_Hint(CautiousDefaultHint):
# FIXME: demo is not too clever in this game # FIXME: demo is not too clever in this game
@ -50,12 +62,13 @@ class Bristol_Hint(CautiousDefaultHint):
# Increased score must be in range 0..9999 # Increased score must be in range 0..9999
def _getMovePileScore(self, score, color, r, t, pile, rpile): def _getMovePileScore(self, score, color, r, t, pile, rpile):
# prefer reserves # prefer reserves
if not r in self.game.s.reserves: if r not in self.game.s.reserves:
score = score - 10000 score = score - 10000
# an empty pile doesn't gain anything # an empty pile doesn't gain anything
if len(pile) == len(r.cards): if len(pile) == len(r.cards):
return -1, color return -1, color
return CautiousDefaultHint._getMovePileScore(self, score, color, r, t, pile, rpile) return CautiousDefaultHint._getMovePileScore(
self, score, color, r, t, pile, rpile)
# ************************************************************************ # ************************************************************************
@ -184,8 +197,10 @@ class Dover(Bristol):
Talon_Class = Bristol_Talon Talon_Class = Bristol_Talon
Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0) Foundation_Class = StackWrapper(SS_FoundationStack, max_move=0)
RowStack_Class = StackWrapper(Dover_RowStack, base_rank=NO_RANK, max_move=1) RowStack_Class = StackWrapper(
ReserveStack_Class = StackWrapper(ReserveStack, max_accept=0, max_cards=UNLIMITED_CARDS) Dover_RowStack, base_rank=NO_RANK, max_move=1)
ReserveStack_Class = StackWrapper(
ReserveStack, max_accept=0, max_cards=UNLIMITED_CARDS)
def createGame(self, rows=8, text=False): def createGame(self, rows=8, text=False):
# create layout # create layout
@ -231,7 +246,6 @@ class Dover(Bristol):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
return cards return cards
@ -248,7 +262,8 @@ class NewYork_Hint(CautiousDefaultHint):
if not self.game.s.talon.cards: if not self.game.s.talon.cards:
return return
c = self.game.s.talon.cards[-1].rank - self.game.base_card.rank c = self.game.s.talon.cards[-1].rank - self.game.base_card.rank
if c < 0: c += 13 if c < 0:
c += 13
if 0 <= c <= 3: if 0 <= c <= 3:
r = self.game.s.reserves[0] r = self.game.s.reserves[0]
elif 4 <= c <= 7: elif 4 <= c <= 7:
@ -285,8 +300,10 @@ class NewYork(Dover):
Hint_Class = NewYork_Hint Hint_Class = NewYork_Hint
Foundation_Class = StackWrapper(SS_FoundationStack, mod=13, max_move=0) Foundation_Class = StackWrapper(SS_FoundationStack, mod=13, max_move=0)
Talon_Class = NewYork_Talon Talon_Class = NewYork_Talon
RowStack_Class = StackWrapper(NewYork_RowStack, base_rank=ANY_RANK, mod=13, max_move=1) RowStack_Class = StackWrapper(
ReserveStack_Class = StackWrapper(NewYork_ReserveStack, max_accept=1, max_cards=UNLIMITED_CARDS, mod=13) NewYork_RowStack, base_rank=ANY_RANK, mod=13, max_move=1)
ReserveStack_Class = StackWrapper(
NewYork_ReserveStack, max_accept=1, max_cards=UNLIMITED_CARDS, mod=13)
def createGame(self): def createGame(self):
# extra settings # extra settings
@ -314,7 +331,7 @@ class NewYork(Dover):
n = self.base_card.suit n = self.base_card.suit
self.flipMove(self.s.talon) self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, self.s.foundations[n]) self.moveMove(1, self.s.talon, self.s.foundations[n])
##self.updateText() # self.updateText()
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.fillStack() self.s.talon.fillStack()
@ -368,8 +385,10 @@ class Gotham_RowStack(RK_RowStack):
from_stack in self.game.s.reserves) from_stack in self.game.s.reserves)
return True return True
class Gotham(NewYork): class Gotham(NewYork):
RowStack_Class = StackWrapper(Gotham_RowStack, base_rank=ANY_RANK, mod=13) RowStack_Class = StackWrapper(Gotham_RowStack, base_rank=ANY_RANK, mod=13)
def startGame(self): def startGame(self):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
@ -461,7 +480,6 @@ class Interment(Game):
self.sg.openstacks += s.xwastes self.sg.openstacks += s.xwastes
self.sg.dropstacks.append(s.talon) self.sg.dropstacks.append(s.talon)
def startGame(self): def startGame(self):
for i in range(13): for i in range(13):
self.s.talon.dealRow(rows=[self.s.reserves[0]], flip=0, frames=0) self.s.talon.dealRow(rows=[self.s.reserves[0]], flip=0, frames=0)
@ -470,7 +488,6 @@ class Interment(Game):
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.fillStack() self.s.talon.fillStack()
def fillStack(self, stack): def fillStack(self, stack):
if not stack.cards: if not stack.cards:
old_state = self.enterState(self.S_FILL) old_state = self.enterState(self.S_FILL)
@ -484,17 +501,14 @@ class Interment(Game):
from_stack.moveMove(1, stack) from_stack.moveMove(1, stack)
self.leaveState(old_state) self.leaveState(old_state)
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
def getQuickPlayScore(self, ncards, from_stack, to_stack): def getQuickPlayScore(self, ncards, from_stack, to_stack):
if to_stack in self.s.xwastes: if to_stack in self.s.xwastes:
return 0 return 0
return 1+Game.getQuickPlayScore(self, ncards, from_stack, to_stack) return 1+Game.getQuickPlayScore(self, ncards, from_stack, to_stack)
# register the game # register the game
registerGame(GameInfo(42, Bristol, "Bristol", registerGame(GameInfo(42, Bristol, "Bristol",
GI.GT_FAN_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FAN_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
@ -510,4 +524,3 @@ registerGame(GameInfo(519, Gotham, "Gotham",
GI.GT_FAN_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_FAN_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(604, Interment, "Interment", registerGame(GameInfo(604, Interment, "Interment",
GI.GT_FAN_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_FAN_TYPE, 2, 0, GI.SL_BALANCED))

View file

@ -21,25 +21,25 @@
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------##
__all__ = []
# imports # imports
import sys
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.util import KING
from pysollib.mfxutil import kwdefault from pysollib.stack import \
from pysollib.stack import * BasicRowStack, \
InitialDealTalonStack, \
SS_FoundationStack, \
ReserveStack
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
# ************************************************************************ # ************************************************************************
# * Buffalo Bill # * Buffalo Bill
# * Little Billie # * Little Billie
# ************************************************************************ # ************************************************************************
class BuffaloBill(Game): class BuffaloBill(Game):
# #
@ -51,7 +51,8 @@ class BuffaloBill(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
w, h = l.XM+max(max(rows)*(l.XS+3*l.XOFFSET), 9*l.XS), l.YM+(len(rows)+2)*l.YS w, h = l.XM+max(
max(rows)*(l.XS+3*l.XOFFSET), 9*l.XS), l.YM+(len(rows)+2)*l.YS
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
@ -97,8 +98,9 @@ class BuffaloBill(Game):
class LittleBillie(BuffaloBill): class LittleBillie(BuffaloBill):
def createGame(self): def createGame(self):
#BuffaloBill.createGame(self, rows=(8, 8, 8)) # BuffaloBill.createGame(self, rows=(8, 8, 8))
BuffaloBill.createGame(self, rows=(6,6,6,6)) BuffaloBill.createGame(self, rows=(6, 6, 6, 6))
def startGame(self): def startGame(self):
self.s.talon.dealRow(rows=self.s.reserves, frames=0) self.s.talon.dealRow(rows=self.s.reserves, frames=0)
BuffaloBill.startGame(self) BuffaloBill.startGame(self)
@ -109,5 +111,3 @@ registerGame(GameInfo(338, BuffaloBill, "Buffalo Bill",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(421, LittleBillie, "Little Billie", registerGame(GameInfo(421, LittleBillie, "Little Billie",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -10,7 +10,7 @@ use String::ShellQuote qw/ shell_quote /;
# my $cmd = shell_quote( 'flake8', '.' ); # my $cmd = shell_quote( 'flake8', '.' );
my $cmd = shell_quote( 'flake8', my $cmd = shell_quote( 'flake8',
grep { not($_ eq './pysollib/pysoltk.py' or $_ eq './pysollib/tile/ttk.py') } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/[ay-z]*.py') ); grep { not($_ eq './pysollib/pysoltk.py' or $_ eq './pysollib/tile/ttk.py') } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/[a-by-z]*.py') );
# TEST # TEST
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." ); eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );