1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

flake8 - games/p*

This commit is contained in:
Shlomi Fish 2017-04-18 02:23:26 +03:00
parent 2cd0df484d
commit 84018dbfe2
7 changed files with 234 additions and 154 deletions

View file

@ -24,22 +24,25 @@
__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.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.util import ACE, KING
from pysollib.stack import \
BasicRowStack, \
DealRowTalonStack, \
SS_FoundationStack
# ************************************************************************ # ************************************************************************
# * Parallels # * Parallels
# * British Blockade # * British Blockade
# ************************************************************************ # ************************************************************************
class Parallels_RowStack(BasicRowStack): class Parallels_RowStack(BasicRowStack):
def basicIsBlocked(self): def basicIsBlocked(self):
index = self.index index = self.index
@ -48,7 +51,7 @@ class Parallels_RowStack(BasicRowStack):
return False return False
if not rows[index-10].cards: if not rows[index-10].cards:
return False return False
if index >= 60: # last row if index >= 60: # last row
return False return False
if not rows[index+10].cards: if not rows[index+10].cards:
return False return False
@ -60,9 +63,10 @@ class Parallels_TalonStack(DealRowTalonStack):
return self.dealRow(sound=sound) return self.dealRow(sound=sound)
def dealRow(self, rows=None, flip=1, reverse=0, frames=-1, sound=False): def dealRow(self, rows=None, flip=1, reverse=0, frames=-1, sound=False):
if not rows is None: if rows is not None:
return DealRowTalonStack.dealRowAvail(self, rows=rows, flip=flip, return DealRowTalonStack.dealRowAvail(
reverse=reverse, frames=frames, sound=sound) self, rows=rows, flip=flip,
reverse=reverse, frames=frames, sound=sound)
rows = self.game.s.rows rows = self.game.s.rows
for r in rows[:10]: for r in rows[:10]:
if not r.cards: if not r.cards:
@ -75,8 +79,9 @@ class Parallels_TalonStack(DealRowTalonStack):
if max(column_ncards) != min(column_ncards): if max(column_ncards) != min(column_ncards):
return self._fillRow(frames=frames, sound=sound) return self._fillRow(frames=frames, sound=sound)
r = rows[max_col*10:max_col*10+10] r = rows[max_col*10:max_col*10+10]
return DealRowTalonStack.dealRowAvail(self, rows=r, flip=flip, return DealRowTalonStack.dealRowAvail(
reverse=reverse, frames=frames, sound=sound) self, rows=r, flip=flip,
reverse=reverse, frames=frames, sound=sound)
def _fillRow(self, frames=-1, sound=False): def _fillRow(self, frames=-1, sound=False):
rows = self.game.s.rows rows = self.game.s.rows
@ -98,8 +103,9 @@ class Parallels_TalonStack(DealRowTalonStack):
break break
if s.cards: if s.cards:
if prev_s: if prev_s:
DealRowTalonStack.dealRow(self, rows=[prev_s], DealRowTalonStack.dealRow(
frames=frames, sound=sound) self, rows=[prev_s],
frames=frames, sound=sound)
n += 1 n += 1
filled = True filled = True
break break
@ -114,8 +120,9 @@ class Parallels_TalonStack(DealRowTalonStack):
filled = False filled = False
break break
if not s.cards: if not s.cards:
DealRowTalonStack.dealRow(self, rows=[s], DealRowTalonStack.dealRow(
frames=frames, sound=sound) self, rows=[s],
frames=frames, sound=sound)
n += 1 n += 1
filled = True filled = True
break break
@ -160,9 +167,10 @@ class Parallels(Game):
l.defaultStackGroups() l.defaultStackGroups()
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
return self._shuffleHookMoveToTop(cards, return self._shuffleHookMoveToTop(
lambda c: (c.rank in (ACE, KING) and c.deck == 0, cards,
(c.rank, c.suit))) lambda c: (c.rank in (ACE, KING) and c.deck == 0,
(c.rank, c.suit)))
def startGame(self): def startGame(self):
self.s.talon.dealRow(rows=self.s.foundations, frames=0) self.s.talon.dealRow(rows=self.s.foundations, frames=0)
@ -186,8 +194,3 @@ registerGame(GameInfo(428, Parallels, "Parallels",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(615, BritishBlockade, "British Blockade", registerGame(GameInfo(615, BritishBlockade, "British Blockade",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))

View file

@ -24,21 +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.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 AbstractHint
from pysollib.stack import \
InvisibleStack, \
ReserveStack, \
WasteStack, \
WasteTalonStack
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class PasDeDeux_Hint(AbstractHint): class PasDeDeux_Hint(AbstractHint):
# FIXME: this is very simple # FIXME: this is very simple
@ -100,7 +103,8 @@ class PasDeDeux_RowStack(ReserveStack):
if not self.game.s.waste.cards: if not self.game.s.waste.cards:
return False return False
c = self.game.s.waste.cards[-1] c = self.game.s.waste.cards[-1]
return c.face_up and cards[0].suit == c.suit and cards[0].rank == c.rank return c.face_up and cards[0].suit == c.suit and \
cards[0].rank == c.rank
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):
@ -161,7 +165,8 @@ class PasDeDeux(Game):
for i in range(4): for i in range(4):
for j in range(13): for j in range(13):
x, y, = l.XM + j*l.XS, l.YM + i*l.YS x, y, = l.XM + j*l.XS, l.YM + i*l.YS
s.rows.append(PasDeDeux_RowStack(x, y, self, max_accept=1, max_cards=2)) s.rows.append(
PasDeDeux_RowStack(x, y, self, max_accept=1, max_cards=2))
x, y = self.width - 2*l.XS, self.height - l.YS x, y = self.width - 2*l.XS, self.height - l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=2) s.talon = WasteTalonStack(x, y, self, max_rounds=2)
l.createText(s.talon, "se") l.createText(s.talon, "se")
@ -214,5 +219,5 @@ class PasDeDeux(Game):
# register the game # register the game
registerGame(GameInfo(153, PasDeDeux, "Pas de Deux", registerGame(GameInfo(153, PasDeDeux, "Pas de Deux",
GI.GT_MONTANA | GI.GT_SEPARATE_DECKS, 2, 1, GI.SL_MOSTLY_SKILL)) GI.GT_MONTANA | GI.GT_SEPARATE_DECKS, 2, 1,
GI.SL_MOSTLY_SKILL))

View file

@ -24,20 +24,32 @@
__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.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 AbstractHint
from pysollib.util import ACE, KING, QUEEN
from pysollib.stack import \
BasicRowStack, \
DealRowTalonStack, \
InvisibleStack, \
RK_FoundationStack, \
SS_FoundationStack, \
SS_RowStack, \
Stack, \
StackWrapper, \
WasteStack, \
WasteTalonStack
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class PictureGallery_Hint(AbstractHint): class PictureGallery_Hint(AbstractHint):
def computeHints(self): def computeHints(self):
game = self.game game = self.game
@ -105,7 +117,7 @@ class PictureGallery_Hint(AbstractHint):
lp = len(pile) lp = len(pile)
lr = len(r.cards) lr = len(r.cards)
assert 1 <= lp <= lr assert 1 <= lp <= lr
rpile = r.cards[ : (lr-lp) ] # remaining pile rpile = r.cards[:(lr-lp)] # remaining pile
if not pile or len(pile) != 1 or len(pile) == len(r.cards): if not pile or len(pile) != 1 or len(pile) == len(r.cards):
continue continue
base_score = 60000 base_score = 60000
@ -129,7 +141,8 @@ class PictureGallery_Hint(AbstractHint):
# this Foundation only accepts Aces # this Foundation only accepts Aces
class PictureGallery_Foundation(RK_FoundationStack): class PictureGallery_Foundation(RK_FoundationStack):
def __init__(self, x, y, game): def __init__(self, x, y, game):
RK_FoundationStack.__init__(self, x, y, game, base_rank=ACE, dir=0, max_move=0, max_cards=8) RK_FoundationStack.__init__(
self, x, y, game, base_rank=ACE, dir=0, max_move=0, max_cards=8)
self.CARD_YOFFSET = min(30, self.game.app.images.CARD_YOFFSET + 10) self.CARD_YOFFSET = min(30, self.game.app.images.CARD_YOFFSET + 10)
def getBottomImage(self): def getBottomImage(self):
@ -137,7 +150,8 @@ class PictureGallery_Foundation(RK_FoundationStack):
def closeStack(self): def closeStack(self):
if len(self.cards) == 8: if len(self.cards) == 8:
if self.game.moves.state not in (self.game.S_REDO, self.game.S_RESTORE): if self.game.moves.state not in \
(self.game.S_REDO, self.game.S_RESTORE):
self.game.flipAllMove(self) self.game.flipAllMove(self)
def canFlipCard(self): def canFlipCard(self):
@ -146,7 +160,8 @@ class PictureGallery_Foundation(RK_FoundationStack):
class PictureGallery_TableauStack(SS_RowStack): class PictureGallery_TableauStack(SS_RowStack):
def __init__(self, x, y, game, base_rank, yoffset, dir=3, max_cards=4): def __init__(self, x, y, game, base_rank, yoffset, dir=3, max_cards=4):
SS_RowStack.__init__(self, x, y, game, SS_RowStack.__init__(
self, x, y, game,
base_rank=base_rank, dir=dir, max_cards=max_cards, max_accept=1) base_rank=base_rank, dir=dir, max_cards=max_cards, max_accept=1)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -182,9 +197,12 @@ class PictureGallery(Game):
Foundation_Class = PictureGallery_Foundation Foundation_Class = PictureGallery_Foundation
TableauStack_Classes = [ TableauStack_Classes = [
StackWrapper(PictureGallery_TableauStack, base_rank=3, max_cards=4, dir=3), StackWrapper(
StackWrapper(PictureGallery_TableauStack, base_rank=2, max_cards=4, dir=3), PictureGallery_TableauStack, base_rank=3, max_cards=4, dir=3),
StackWrapper(PictureGallery_TableauStack, base_rank=1, max_cards=4, dir=3), StackWrapper(
PictureGallery_TableauStack, base_rank=2, max_cards=4, dir=3),
StackWrapper(
PictureGallery_TableauStack, base_rank=1, max_cards=4, dir=3),
] ]
RowStack_Class = StackWrapper(PictureGallery_RowStack, max_accept=1) RowStack_Class = StackWrapper(PictureGallery_RowStack, max_accept=1)
Talon_Class = DealRowTalonStack Talon_Class = DealRowTalonStack
@ -221,7 +239,7 @@ class PictureGallery(Game):
for i in range(8): for i in range(8):
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS x = x + l.XS
##self.setRegion(s.rows, (-999, -999, x - l.CW / 2, 999999)) # self.setRegion(s.rows, (-999, -999, x - l.CW / 2, 999999))
x = l.XM + 8 * l.XS + l.XS / 2 x = l.XM + 8 * l.XS + l.XS / 2
y = self.height - l.YS y = self.height - l.YS
s.talon = self.Talon_Class(x, y, self) s.talon = self.Talon_Class(x, y, self)
@ -241,7 +259,6 @@ class PictureGallery(Game):
self.sg.talonstacks = [s.talon] + ws self.sg.talonstacks = [s.talon] + ws
self.sg.dropstacks = s.tableaux + s.rows + ws self.sg.dropstacks = s.tableaux + s.rows + ws
# #
# game overrides # game overrides
# #
@ -274,11 +291,11 @@ class PictureGallery(Game):
return () return ()
# ************************************************************************ # ************************************************************************
# * Great Wheel # * Great Wheel
# ************************************************************************ # ************************************************************************
class GreatWheel_Hint(PictureGallery_Hint): class GreatWheel_Hint(PictureGallery_Hint):
shallMovePile = PictureGallery_Hint._cautiousShallMovePile shallMovePile = PictureGallery_Hint._cautiousShallMovePile
@ -311,8 +328,10 @@ class GreatWheel(PictureGallery):
Hint_Class = GreatWheel_Hint Hint_Class = GreatWheel_Hint
Foundation_Class = GreatWheel_Foundation Foundation_Class = GreatWheel_Foundation
TableauStack_Classes = [ TableauStack_Classes = [
StackWrapper(PictureGallery_TableauStack, base_rank=2, max_cards=5, dir=2), StackWrapper(
StackWrapper(PictureGallery_TableauStack, base_rank=1, max_cards=6, dir=2), PictureGallery_TableauStack, base_rank=2, max_cards=5, dir=2),
StackWrapper(
PictureGallery_TableauStack, base_rank=1, max_cards=6, dir=2),
] ]
RowStack_Class = StackWrapper(GreatWheel_RowStack, max_accept=1) RowStack_Class = StackWrapper(GreatWheel_RowStack, max_accept=1)
Talon_Class = StackWrapper(WasteTalonStack, max_rounds=1) Talon_Class = StackWrapper(WasteTalonStack, max_rounds=1)
@ -321,7 +340,7 @@ class GreatWheel(PictureGallery):
PictureGallery.createGame(self, waste=True) PictureGallery.createGame(self, waste=True)
def fillStack(self, stack): def fillStack(self, stack):
if stack is self.s.waste and not stack.cards : if stack is self.s.waste and not stack.cards:
self.s.talon.dealCards() self.s.talon.dealCards()
if self.s.talon.cards or self.s.waste.cards: if self.s.talon.cards or self.s.waste.cards:
if stack in self.s.rows and len(stack.cards) == 0: if stack in self.s.rows and len(stack.cards) == 0:
@ -339,7 +358,6 @@ class GreatWheel(PictureGallery):
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.dealCards() self.s.talon.dealCards()
def isGameWon(self): def isGameWon(self):
if len(self.s.foundations[0].cards) != 8: if len(self.s.foundations[0].cards) != 8:
return False return False
@ -350,7 +368,6 @@ class GreatWheel(PictureGallery):
return False return False
return True return True
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
if card1.rank == ACE or card2.rank == ACE: if card1.rank == ACE or card2.rank == ACE:
return False return False
@ -362,6 +379,7 @@ class GreatWheel(PictureGallery):
# * Zeus # * Zeus
# ************************************************************************ # ************************************************************************
class MountOlympus_Foundation(SS_FoundationStack): class MountOlympus_Foundation(SS_FoundationStack):
def getHelp(self): def getHelp(self):
return 'Build up in suit by twos.' return 'Build up in suit by twos.'
@ -385,42 +403,43 @@ class MountOlympus(Game):
# create stacks # create stacks
x, y = l.XM+l.XS, l.YM x, y = l.XM+l.XS, l.YM
for i in range(8): for i in range(8):
s.foundations.append(MountOlympus_Foundation(x, y, self, s.foundations.append(
suit=i/2, base_rank=ACE, dir=2, max_move=0, max_cards=7)) MountOlympus_Foundation(
x, y, self,
suit=i/2, base_rank=ACE, dir=2, max_move=0, max_cards=7))
x += l.XS x += l.XS
x, y = l.XM+l.XS, l.YM+l.YS x, y = l.XM+l.XS, l.YM+l.YS
for i in range(8): for i in range(8):
s.foundations.append(MountOlympus_Foundation(x, y, self, s.foundations.append(
suit=i/2, base_rank=1, dir=2, max_move=0, max_cards=6)) MountOlympus_Foundation(
x, y, self,
suit=i/2, base_rank=1, dir=2, max_move=0, max_cards=6))
x += l.XS x += l.XS
x, y = l.XM, l.YM+2*l.YS x, y = l.XM, l.YM+2*l.YS
for i in range(9): for i in range(9):
s.rows.append(self.RowStack_Class(x, y, self, dir=-2)) s.rows.append(self.RowStack_Class(x, y, self, dir=-2))
x += l.XS x += l.XS
s.talon=DealRowTalonStack(l.XM, l.YM, self) s.talon = DealRowTalonStack(l.XM, l.YM, self)
l.createText(s.talon, 's') l.createText(s.talon, 's')
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
return self._shuffleHookMoveToTop(cards, return self._shuffleHookMoveToTop(
cards,
lambda c: (c.rank in (ACE, 1), (c.rank, c.suit))) lambda c: (c.rank in (ACE, 1), (c.rank, c.suit)))
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow(rows=self.s.foundations) self.s.talon.dealRow(rows=self.s.foundations)
self.s.talon.dealRow() self.s.talon.dealRow()
def fillStack(self, stack): def fillStack(self, stack):
if self.s.talon.cards: if self.s.talon.cards:
if stack in self.s.rows and len(stack.cards) == 0: if stack in self.s.rows and len(stack.cards) == 0:
self.s.talon.dealRow(rows=[stack]) self.s.talon.dealRow(rows=[stack])
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and return (card1.suit == card2.suit and
(card1.rank + 2 == card2.rank or card2.rank + 2 == card1.rank)) (card1.rank + 2 == card2.rank or card2.rank + 2 == card1.rank))
@ -434,8 +453,10 @@ class Zeus_RowStack(MountOlympus_RowStack):
return cards[0].rank in (QUEEN, KING) return cards[0].rank in (QUEEN, KING)
return True return True
class Zeus(MountOlympus): class Zeus(MountOlympus):
RowStack_Class = Zeus_RowStack RowStack_Class = Zeus_RowStack
def startGame(self): def startGame(self):
self.s.talon.dealRow(rows=self.s.foundations, frames=0) self.s.talon.dealRow(rows=self.s.foundations, frames=0)
self.startDealSample() self.startDealSample()
@ -462,7 +483,8 @@ class RoyalParade_TableauStack(PictureGallery_TableauStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if self._canSwapPair(from_stack): if self._canSwapPair(from_stack):
return True return True
return PictureGallery_TableauStack.acceptsCards(self, from_stack, cards) return PictureGallery_TableauStack.acceptsCards(
self, from_stack, cards)
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
if self._canSwapPair(to_stack): if self._canSwapPair(to_stack):
@ -525,13 +547,13 @@ class VirginiaReel(RoyalParade):
bottom_cards = [] bottom_cards = []
ranks = [] ranks = []
for c in cards[:]: for c in cards[:]:
if c.rank in (1,2,3) and c.rank not in ranks: if c.rank in (1, 2, 3) and c.rank not in ranks:
ranks.append(c.rank) ranks.append(c.rank)
cards.remove(c) cards.remove(c)
bottom_cards.append(c) bottom_cards.append(c)
if len(ranks) == 3: if len(ranks) == 3:
break break
bottom_cards.sort(lambda a, b: cmp(b.rank, a.rank)) bottom_cards = sorted(bottom_cards, key=lambda x: x.rank)[::-1]
return cards+bottom_cards return cards+bottom_cards
def startGame(self): def startGame(self):
@ -546,14 +568,13 @@ class VirginiaReel(RoyalParade):
pass pass
# register the game # register the game
registerGame(GameInfo(7, PictureGallery, "Picture Gallery", registerGame(GameInfo(7, PictureGallery, "Picture Gallery",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED, GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED,
altnames=("Die Bildgallerie", "Mod-3") )) altnames=("Die Bildgallerie", "Mod-3")))
registerGame(GameInfo(397, GreatWheel, "Great Wheel", registerGame(GameInfo(397, GreatWheel, "Great Wheel",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED, GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED,
ranks=range(12) # without Kings ranks=range(12) # without Kings
)) ))
registerGame(GameInfo(398, MountOlympus, "Mount Olympus", registerGame(GameInfo(398, MountOlympus, "Mount Olympus",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
@ -564,5 +585,3 @@ registerGame(GameInfo(546, RoyalParade, "Royal Parade",
rules_filename='virginiareel.html')) rules_filename='virginiareel.html'))
registerGame(GameInfo(547, VirginiaReel, "Virginia Reel", registerGame(GameInfo(547, VirginiaReel, "Virginia Reel",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -24,23 +24,37 @@
__all__ = [] __all__ = []
# imports # imports
import sys
# 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.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
from pysollib.util import ACE, ANY_RANK, ANY_SUIT, RANKS
from pysollib.stack import \
AC_RowStack, \
AbstractFoundationStack, \
DealRowTalonStack, \
InitialDealTalonStack, \
RK_RowStack, \
Stack, \
UD_AC_RowStack, \
UD_RK_RowStack, \
WasteStack, \
WasteTalonStack, \
cardsFaceDown, \
isRankSequence, \
ReserveStack
# ************************************************************************ # ************************************************************************
# * PileOn # * PileOn
# ************************************************************************ # ************************************************************************
class PileOn_RowStack(RK_RowStack): class PileOn_RowStack(RK_RowStack):
getBottomImage = Stack._getReserveBottomImage getBottomImage = Stack._getReserveBottomImage
@ -55,7 +69,7 @@ class PileOn_RowStack(RK_RowStack):
class PileOn(Game): class PileOn(Game):
Hint_Class = DefaultHint Hint_Class = DefaultHint
##Hint_Class = CautiousDefaultHint # Hint_Class = CautiousDefaultHint
TWIDTH = 4 TWIDTH = 4
NSTACKS = 15 NSTACKS = 15
PLAYCARDS = 4 PLAYCARDS = 4
@ -70,7 +84,7 @@ class PileOn(Game):
# set window # set window
# (set size so that at least 4 cards are fully playable) # (set size so that at least 4 cards are fully playable)
#w = max(2*l.XS, l.XS+(self.PLAYCARDS-1)*l.XOFFSET+2*l.XM) # w = max(2*l.XS, l.XS+(self.PLAYCARDS-1)*l.XOFFSET+2*l.XM)
w = l.XS+(self.PLAYCARDS-1)*l.XOFFSET+3*l.XOFFSET w = l.XS+(self.PLAYCARDS-1)*l.XOFFSET+3*l.XOFFSET
twidth, theight = self.TWIDTH, int((self.NSTACKS-1)/self.TWIDTH+1) twidth, theight = self.TWIDTH, int((self.NSTACKS-1)/self.TWIDTH+1)
self.setSize(l.XM+twidth*w, l.YM+theight*l.YS) self.setSize(l.XM+twidth*w, l.YM+theight*l.YS)
@ -82,7 +96,8 @@ class PileOn(Game):
for j in range(twidth): for j in range(twidth):
if i*twidth+j >= self.NSTACKS: if i*twidth+j >= self.NSTACKS:
break break
stack = PileOn_RowStack(x, y, self, dir=0, max_cards=self.PLAYCARDS) stack = PileOn_RowStack(
x, y, self, dir=0, max_cards=self.PLAYCARDS)
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)
x = x + w x = x + w
@ -122,12 +137,12 @@ class SmallPileOn(PileOn):
PLAYCARDS = 4 PLAYCARDS = 4
## class PileOn2Decks(PileOn): # class PileOn2Decks(PileOn):
## TWIDTH = 4 # TWIDTH = 4
## NSTACKS = 15 # NSTACKS = 15
## PLAYCARDS = 8 # PLAYCARDS = 8
## registerGame(GameInfo(341, PileOn2Decks, "PileOn (2 decks)", # registerGame(GameInfo(341, PileOn2Decks, "PileOn (2 decks)",
## GI.GT_2DECK_TYPE | GI.GT_OPEN,, 2, 0)) # GI.GT_2DECK_TYPE | GI.GT_OPEN,, 2, 0))
# ************************************************************************ # ************************************************************************
@ -179,7 +194,6 @@ class Foursome(Game):
self.flipMove(self.s.foundations[0]) self.flipMove(self.s.foundations[0])
self.leaveState(old_state) self.leaveState(old_state)
shallHighlightMatch = Game._shallHighlightMatch_ACW shallHighlightMatch = Game._shallHighlightMatch_ACW
@ -282,7 +296,6 @@ class FourByFour(Game):
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow(rows=self.s.foundations) self.s.talon.dealRow(rows=self.s.foundations)
@ -369,6 +382,7 @@ class Footling(FourByFour):
class DoubleFootling(Footling): class DoubleFootling(Footling):
def createGame(self): def createGame(self):
Footling.createGame(self, rows=10, reserves=5, playcards=18) Footling.createGame(self, rows=10, reserves=5, playcards=18)
def startGame(self): def startGame(self):
for i in range(9): for i in range(9):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
@ -380,20 +394,22 @@ class DoubleFootling(Footling):
# register the game # register the game
registerGame(GameInfo(41, PileOn, "PileOn", registerGame(GameInfo(41, PileOn, "PileOn",
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,
altnames=("Fifteen Puzzle",) )) altnames=("Fifteen Puzzle",)))
registerGame(GameInfo(289, SmallPileOn, "Small PileOn", registerGame(GameInfo(289, SmallPileOn, "Small PileOn",
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,
ranks=(0, 5, 6, 7, 8, 9, 10, 11, 12), ranks=(0, 5, 6, 7, 8, 9, 10, 11, 12),
rules_filename = "pileon.html")) rules_filename="pileon.html"))
registerGame(GameInfo(554, Foursome, "Foursome", registerGame(GameInfo(554, Foursome, "Foursome",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(555, Quartets, "Quartets", registerGame(GameInfo(555, Quartets, "Quartets",
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(703, FourByFour, "Four by Four", registerGame(GameInfo(703, FourByFour, "Four by Four",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(740, Footling, "Footling", registerGame(GameInfo(740, Footling, "Footling",
GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0,
GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(741, DoubleFootling, "Double Footling", registerGame(GameInfo(741, DoubleFootling, "Double Footling",
GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0,
GI.SL_MOSTLY_SKILL))

View file

@ -27,16 +27,23 @@ __all__ = []
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
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 AbstractHint
from pysollib.util import ANY_RANK, ANY_SUIT
from pysollib.stack import \
AbstractFoundationStack, \
DealRowTalonStack, \
Stack, \
ReserveStack
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class PushPin_Hint(AbstractHint): class PushPin_Hint(AbstractHint):
def computeHints(self): def computeHints(self):
@ -58,6 +65,7 @@ class PushPin_Foundation(AbstractFoundationStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
return True return True
class PushPin_Talon(DealRowTalonStack): class PushPin_Talon(DealRowTalonStack):
def dealCards(self, sound=False): def dealCards(self, sound=False):
for r in self.game.s.rows: for r in self.game.s.rows:
@ -66,6 +74,7 @@ class PushPin_Talon(DealRowTalonStack):
return self.dealRowAvail(rows=[self.game.s.rows[0]], sound=sound) return self.dealRowAvail(rows=[self.game.s.rows[0]], sound=sound)
getBottomImage = Stack._getNoneBottomImage getBottomImage = Stack._getNoneBottomImage
class PushPin_RowStack(ReserveStack): class PushPin_RowStack(ReserveStack):
def _checkPair(self, ps, ns): def _checkPair(self, ps, ns):
@ -100,22 +109,23 @@ class PushPin_RowStack(ReserveStack):
self.game.fillEmptyStacks() self.game.fillEmptyStacks()
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
if not to_stack is self.game.s.foundations[0]: if to_stack is not self.game.s.foundations[0]:
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow) self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
else: else:
ReserveStack.moveMove(self, ncards, to_stack, frames=frames, shadow=shadow) ReserveStack.moveMove(
self, ncards, to_stack, frames=frames, shadow=shadow)
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1): def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
game = self.game game = self.game
old_state = game.enterState(game.S_FILL) old_state = game.enterState(game.S_FILL)
f = game.s.foundations[0] f = game.s.foundations[0]
game.updateStackMove(game.s.talon, 2|16) # for undo game.updateStackMove(game.s.talon, 2 | 16) # for undo
if not game.demo: if not game.demo:
game.playSample("droppair", priority=200) game.playSample("droppair", priority=200)
game.moveMove(n, self, f, frames=frames, shadow=shadow) game.moveMove(n, self, f, frames=frames, shadow=shadow)
game.moveMove(n, other_stack, f, frames=frames, shadow=shadow) game.moveMove(n, other_stack, f, frames=frames, shadow=shadow)
self.fillStack() self.fillStack()
game.updateStackMove(game.s.talon, 1|16) # for redo game.updateStackMove(game.s.talon, 1 | 16) # for redo
game.leaveState(old_state) game.leaveState(old_state)
getBottomImage = Stack._getBlankBottomImage getBottomImage = Stack._getBlankBottomImage
@ -148,7 +158,7 @@ class PushPin(Game):
if n > 52: if n > 52:
break break
k = j k = j
if i%2: if i % 2:
k = xx-j-1 k = xx-j-1
x, y = l.XM + k*l.XS, l.YM + i*l.YS x, y = l.XM + k*l.XS, l.YM + i*l.YS
s.rows.append(self.RowStack_Class(x, y, self)) s.rows.append(self.RowStack_Class(x, y, self))
@ -258,7 +268,7 @@ class Accordion_RowStack(PushPin_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not self.cards: if not self.cards:
return False return False
if abs(self.id - from_stack.id) not in (1,3): if abs(self.id - from_stack.id) not in (1, 3):
return False return False
c1, c2 = self.cards[-1], cards[0] c1, c2 = self.cards[-1], cards[0]
if c1.rank == c2.rank: if c1.rank == c2.rank:
@ -283,27 +293,31 @@ class Accordion(PushPin):
# * Accordion (fixed) # * Accordion (fixed)
# ************************************************************************ # ************************************************************************
class Accordion2_RowStack(Accordion_RowStack): class Accordion2_RowStack(Accordion_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not Accordion_RowStack.acceptsCards(self, from_stack, cards): if not Accordion_RowStack.acceptsCards(self, from_stack, cards):
return False return False
# accepts only from right stack # accepts only from right stack
return self.id < from_stack.id return self.id < from_stack.id
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
game = self.game game = self.game
old_state = game.enterState(game.S_FILL) old_state = game.enterState(game.S_FILL)
f = game.s.foundations[0] f = game.s.foundations[0]
game.updateStackMove(game.s.talon, 2|16) # for undo game.updateStackMove(game.s.talon, 2 | 16) # for undo
game.moveMove(ncards, to_stack, f, frames=frames, shadow=shadow) game.moveMove(ncards, to_stack, f, frames=frames, shadow=shadow)
game.moveMove(ncards, self, to_stack, frames=frames, shadow=shadow) game.moveMove(ncards, self, to_stack, frames=frames, shadow=shadow)
self.fillStack() self.fillStack()
game.updateStackMove(game.s.talon, 1|16) # for redo game.updateStackMove(game.s.talon, 1 | 16) # for redo
game.leaveState(old_state) game.leaveState(old_state)
class Accordion2(Accordion): class Accordion2(Accordion):
RowStack_Class = Accordion2_RowStack RowStack_Class = Accordion2_RowStack
def isGameWon(self): def isGameWon(self):
return len(self.s.foundations[0].cards) == 51 return len(self.s.foundations[0].cards) == 51
@ -311,9 +325,11 @@ class Accordion2(Accordion):
# * Relaxed Accordion # * Relaxed Accordion
# ************************************************************************ # ************************************************************************
class RelaxedAccordion_RowStack(Accordion2_RowStack): class RelaxedAccordion_RowStack(Accordion2_RowStack):
acceptsCards = Accordion_RowStack.acceptsCards acceptsCards = Accordion_RowStack.acceptsCards
class RelaxedAccordion(Accordion2): class RelaxedAccordion(Accordion2):
RowStack_Class = RelaxedAccordion_RowStack RowStack_Class = RelaxedAccordion_RowStack
@ -322,12 +338,12 @@ registerGame(GameInfo(287, PushPin, "Push Pin",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(288, RoyalMarriage, "Royal Marriage", registerGame(GameInfo(288, RoyalMarriage, "Royal Marriage",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
## registerGame(GameInfo(303, Queens, "Queens", # registerGame(GameInfo(303, Queens, "Queens",
## GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0)) # GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0))
registerGame(GameInfo(656, Accordion, "Bayan", registerGame(GameInfo(656, Accordion, "Bayan",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(772, Accordion2, "Accordion", registerGame(GameInfo(772, Accordion2, "Accordion",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED, GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED,
altnames=('Idle Year', 'Methuselah', 'Tower of Babel') )) altnames=('Idle Year', 'Methuselah', 'Tower of Babel')))
registerGame(GameInfo(773, RelaxedAccordion, "Relaxed Accordion", registerGame(GameInfo(773, RelaxedAccordion, "Relaxed Accordion",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED)) GI.GT_1DECK_TYPE, 1, 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,22 +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.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
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from pysollib.util import ANY_RANK, ANY_SUIT, JACK, KING, NO_RANK, QUEEN, \
UNLIMITED_CARDS, UNLIMITED_REDEALS
from pysollib.stack import \
AbstractFoundationStack, \
BasicRowStack, \
DealReserveRedealTalonStack, \
DealRowTalonStack, \
FaceUpWasteTalonStack, \
InitialDealTalonStack, \
OpenStack, \
Stack, \
StackWrapper, \
TalonStack, \
WasteStack, \
WasteTalonStack, \
getNumberOfFreeStacks, \
ReserveStack
# ************************************************************************ # ************************************************************************
# * # *
@ -73,7 +89,8 @@ class Pyramid_StackMethods:
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1): def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
if not self.game.demo: if not self.game.demo:
self.game.playSample("droppair", priority=200) self.game.playSample("droppair", priority=200)
assert n == 1 and self.acceptsCards(other_stack, [other_stack.cards[-1]]) assert n == 1 and self.acceptsCards(
other_stack, [other_stack.cards[-1]])
old_state = self.game.enterState(self.game.S_FILL) old_state = self.game.enterState(self.game.S_FILL)
f = self.game.s.foundations[0] f = self.game.s.foundations[0]
self.game.moveMove(n, self, f, frames=frames, shadow=shadow) self.game.moveMove(n, self, f, frames=frames, shadow=shadow)
@ -84,7 +101,8 @@ class Pyramid_StackMethods:
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
if to_stack in self.game.s.foundations: if to_stack in self.game.s.foundations:
self.game.moveMove(ncards, self, to_stack, frames=frames, shadow=shadow) self.game.moveMove(
ncards, self, to_stack, frames=frames, shadow=shadow)
self.fillStack() self.fillStack()
else: else:
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow) self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
@ -192,7 +210,7 @@ class Pyramid(Game):
for i in range(size-1): for i in range(size-1):
for j in range(i+1): for j in range(i+1):
k = n+i+1 k = n+i+1
rows[n].blockmap = [rows[k],rows[k+1]] rows[n].blockmap = [rows[k], rows[k+1]]
n += 1 n += 1
return rows return rows
@ -216,11 +234,10 @@ class Pyramid(Game):
elif j == size-i-1: # right elif j == size-i-1: # right
rows[n].blockmap = [rows[k-1]] rows[n].blockmap = [rows[k-1]]
else: else:
rows[n].blockmap = [rows[k-1],rows[k]] rows[n].blockmap = [rows[k-1], rows[k]]
n += 1 n += 1
return rows return rows
def createGame(self, pyramid_len=7, reserves=0, waste=True, texts=True): def createGame(self, pyramid_len=7, reserves=0, waste=True, texts=True):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
@ -269,7 +286,6 @@ class Pyramid(Game):
if s.waste: if s.waste:
self.sg.openstacks.append(s.waste) self.sg.openstacks.append(s.waste)
# #
# game overrides # game overrides
# #
@ -364,7 +380,6 @@ class Thirteen(Pyramid):
self.sg.openstacks = s.rows + self.sg.talonstacks self.sg.openstacks = s.rows + self.sg.talonstacks
self.sg.dropstacks = s.rows + self.sg.talonstacks self.sg.dropstacks = s.rows + self.sg.talonstacks
# #
# game overrides # game overrides
# #
@ -426,11 +441,12 @@ class Thirteens(Pyramid):
# * Suit Elevens # * Suit Elevens
# ************************************************************************ # ************************************************************************
class Elevens_RowStack(Giza_Reserve): class Elevens_RowStack(Giza_Reserve):
ACCEPTED_SUM = 9 ACCEPTED_SUM = 9
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
#if self.basicIsBlocked(): # if self.basicIsBlocked():
# return False # return False
if from_stack is self or not self.cards or len(cards) != 1: if from_stack is self or not self.cards or len(cards) != 1:
return False return False
@ -457,7 +473,7 @@ class Elevens_Reserve(ReserveStack):
if not ReserveStack.acceptsCards(self, from_stack, cards): if not ReserveStack.acceptsCards(self, from_stack, cards):
return False return False
c = cards[0] c = cards[0]
if not c.rank in self.ACCEPTED_CARDS: if c.rank not in self.ACCEPTED_CARDS:
return False return False
for s in self.game.s.reserves: for s in self.game.s.reserves:
if s.cards and s.cards[0].rank == c.rank: if s.cards and s.cards[0].rank == c.rank:
@ -495,7 +511,7 @@ class Elevens(Pyramid):
for i in range(reserves): for i in range(reserves):
stack = self.Reserve_Class(x, y, self) stack = self.Reserve_Class(x, y, self)
s.reserves.append(stack) s.reserves.append(stack)
stack.CARD_XOFFSET = l.XOFFSET # for fifteens stack.CARD_XOFFSET = l.XOFFSET # for fifteens
x += l.XS x += l.XS
if texts: if texts:
@ -507,12 +523,10 @@ class Elevens(Pyramid):
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow() self.s.talon.dealRow()
def fillStack(self, stack): def fillStack(self, stack):
old_state = self.enterState(self.S_FILL) old_state = self.enterState(self.S_FILL)
if stack in self.s.rows: if stack in self.s.rows:
@ -530,7 +544,6 @@ class Elevens(Pyramid):
s.moveMove(1, self.s.foundations[0], frames=4) s.moveMove(1, self.s.foundations[0], frames=4)
self.leaveState(old_state) self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
# FIXME # FIXME
return False return False
@ -564,6 +577,7 @@ class SuitElevens_RowStack(Elevens_RowStack):
return False return False
return cards[0].suit == self.cards[0].suit return cards[0].suit == self.cards[0].suit
class SuitElevens_Reserve(Elevens_Reserve): class SuitElevens_Reserve(Elevens_Reserve):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not Elevens_Reserve.acceptsCards(self, from_stack, cards): if not Elevens_Reserve.acceptsCards(self, from_stack, cards):
@ -573,9 +587,11 @@ class SuitElevens_Reserve(Elevens_Reserve):
return False return False
return True return True
class SuitElevens(Elevens): class SuitElevens(Elevens):
RowStack_Class = SuitElevens_RowStack RowStack_Class = SuitElevens_RowStack
Reserve_Class = SuitElevens_Reserve Reserve_Class = SuitElevens_Reserve
def createGame(self): def createGame(self):
Elevens.createGame(self, rows=3, cols=5) Elevens.createGame(self, rows=3, cols=5)
@ -586,6 +602,7 @@ class SuitElevens(Elevens):
class Fifteens_RowStack(Elevens_RowStack): class Fifteens_RowStack(Elevens_RowStack):
ACCEPTED_SUM = 13 ACCEPTED_SUM = 13
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not Elevens_RowStack.acceptsCards(self, from_stack, cards): if not Elevens_RowStack.acceptsCards(self, from_stack, cards):
return False return False
@ -637,7 +654,7 @@ class Fifteens(Elevens):
reserve_ranks = [c.rank for c in reserve.cards] reserve_ranks = [c.rank for c in reserve.cards]
reserve_ranks.sort() reserve_ranks.sort()
if (9 in reserve_ranks or JACK in reserve_ranks if (9 in reserve_ranks or JACK in reserve_ranks
or QUEEN in reserve_ranks or KING in reserve_ranks): or QUEEN in reserve_ranks or KING in reserve_ranks):
if reserve_ranks == [9, JACK, QUEEN, KING]: if reserve_ranks == [9, JACK, QUEEN, KING]:
self._dropReserve() self._dropReserve()
else: else:
@ -666,9 +683,9 @@ class TripleAlliance_Reserve(ReserveStack):
if len(r_ranks) == 2: if len(r_ranks) == 2:
return r_ranks[1]-r_ranks[0] in (1, 12) return r_ranks[1]-r_ranks[0] in (1, 12)
for i in range(3): for i in range(3):
j, k = (i+1)%3, (i+2)%3 j, k = (i+1) % 3, (i+2) % 3
if ((r_ranks[i]+1) % 13 == r_ranks[j] and if ((r_ranks[i]+1) % 13 == r_ranks[j] and
(r_ranks[j]+1) % 13 == r_ranks[k]): (r_ranks[j]+1) % 13 == r_ranks[k]):
return True return True
return False return False
@ -768,12 +785,10 @@ class Pharaohs(Pyramid):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow(frames=4) self.s.talon.dealRow(frames=4)
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank + card2.rank == 11 or return (card1.rank + card2.rank == 11 or
card1.rank == card2.rank) card1.rank == card2.rank)
@ -855,7 +870,7 @@ class Apophis_Hint(Pyramid_Hint):
return return
reserves = self.game.s.reserves reserves = self.game.s.reserves
for i in range(3): for i in range(3):
for j in range(i+1,3): for j in range(i+1, 3):
r1 = reserves[i] r1 = reserves[i]
r2 = reserves[j] r2 = reserves[j]
if r1.cards and r2.acceptsCards(r1, r1.cards[-1:]): if r1.cards and r2.acceptsCards(r1, r1.cards[-1:]):
@ -923,6 +938,7 @@ class Apophis(Pharaohs):
# * Cheops # * Cheops
# ************************************************************************ # ************************************************************************
class Cheops_StackMethods(Pyramid_StackMethods): class Cheops_StackMethods(Pyramid_StackMethods):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if self.basicIsBlocked(): if self.basicIsBlocked():
@ -931,16 +947,19 @@ class Cheops_StackMethods(Pyramid_StackMethods):
return False return False
c = self.cards[-1] c = self.cards[-1]
return (c.face_up and cards[0].face_up and return (c.face_up and cards[0].face_up and
abs(cards[0].rank-c.rank) in (0,1)) abs(cards[0].rank-c.rank) in (0, 1))
class Cheops_Talon(Cheops_StackMethods, Pyramid_Talon): class Cheops_Talon(Cheops_StackMethods, Pyramid_Talon):
def clickHandler(self, event): def clickHandler(self, event):
return FaceUpWasteTalonStack.clickHandler(self, event) return FaceUpWasteTalonStack.clickHandler(self, event)
class Cheops_Waste(Cheops_StackMethods, Pyramid_Waste): class Cheops_Waste(Cheops_StackMethods, Pyramid_Waste):
def clickHandler(self, event): def clickHandler(self, event):
return WasteStack.clickHandler(self, event) return WasteStack.clickHandler(self, event)
class Cheops_RowStack(Cheops_StackMethods, Pyramid_RowStack): class Cheops_RowStack(Cheops_StackMethods, Pyramid_RowStack):
def clickHandler(self, event): def clickHandler(self, event):
return OpenStack.clickHandler(self, event) return OpenStack.clickHandler(self, event)
@ -954,7 +973,7 @@ class Cheops(Pyramid):
WasteStack_Class = Cheops_Waste WasteStack_Class = Cheops_Waste
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return abs(card1.rank-card2.rank) in (0,1) return abs(card1.rank-card2.rank) in (0, 1)
# ************************************************************************ # ************************************************************************
@ -963,13 +982,13 @@ class Cheops(Pyramid):
class Exit_RowStack(Elevens_RowStack): class Exit_RowStack(Elevens_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
#if self.basicIsBlocked(): # if self.basicIsBlocked():
# return False # return False
if from_stack is self or not self.cards or len(cards) != 1: if from_stack is self or not self.cards or len(cards) != 1:
return False return False
c1 = self.cards[-1] c1 = self.cards[-1]
c2 = cards[0] c2 = cards[0]
#if not c1.face_up or not c2.face_up: # if not c1.face_up or not c2.face_up:
# return False # return False
return self.game._checkPair(c1, c2) return self.game._checkPair(c1, c2)
@ -1034,7 +1053,7 @@ class Exit(Game):
swap_index = jack_indexes[1] swap_index = jack_indexes[1]
if len(jack_indexes) >= 2: if len(jack_indexes) >= 2:
break break
if not swap_index is None: if swap_index is not None:
i = -1 i = -1
if cards[-1].rank == JACK: # paranoia if cards[-1].rank == JACK: # paranoia
i = -2 i = -2
@ -1050,8 +1069,8 @@ class Exit(Game):
self.s.talon.dealRow(rows=self.s.reserves, frames=4) self.s.talon.dealRow(rows=self.s.reserves, frames=4)
self.s.talon.dealRow(rows=self.s.reserves, frames=4) self.s.talon.dealRow(rows=self.s.reserves, frames=4)
## def getAutoStacks(self, event=None): # def getAutoStacks(self, event=None):
## return ((), (), self.sg.dropstacks) # return ((), (), self.sg.dropstacks)
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return self._checkPair(card1, card2) return self._checkPair(card1, card2)
@ -1115,7 +1134,8 @@ class KingTut(RelaxedPyramid):
s.rows = self._createPyramid(l, x, y, 7) s.rows = self._createPyramid(l, x, y, 7)
x, y = l.XM, self.height-l.YS x, y = l.XM, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=UNLIMITED_REDEALS, num_deal=3) s.talon = WasteTalonStack(
x, y, self, max_rounds=UNLIMITED_REDEALS, num_deal=3)
l.createText(s.talon, "n") l.createText(s.talon, "n")
x += l.XS x += l.XS
s.waste = Pyramid_Waste(x, y, self, max_accept=1) s.waste = Pyramid_Waste(x, y, self, max_accept=1)
@ -1221,7 +1241,6 @@ class UpAndDown(Pyramid):
self.sg.dropstacks.append(s.talon) self.sg.dropstacks.append(s.talon)
self.sg.openstacks.append(s.waste) self.sg.openstacks.append(s.waste)
def startGame(self): def startGame(self):
self.startDealSample() self.startDealSample()
self.s.talon.dealRow(frames=4) self.s.talon.dealRow(frames=4)
@ -1260,9 +1279,11 @@ class Hurricane_StackMethods(Pyramid_StackMethods):
frames=frames, shadow=shadow) frames=frames, shadow=shadow)
self.fillStack() self.fillStack()
class Hurricane_RowStack(Hurricane_StackMethods, BasicRowStack): class Hurricane_RowStack(Hurricane_StackMethods, BasicRowStack):
pass pass
class Hurricane_Reserve(Hurricane_StackMethods, OpenStack): class Hurricane_Reserve(Hurricane_StackMethods, OpenStack):
pass pass
@ -1281,10 +1302,10 @@ class Hurricane(Pyramid):
self.setSize(w, h) self.setSize(w, h)
# create stacks # create stacks
for xx, yy in ((0,0),(1,0),(2,0),(3,0), for xx, yy in ((0, 0), (1, 0), (2, 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 = l.XM + 1.5*l.XS + ww*xx, l.YM + l.YS*yy x, y = l.XM + 1.5*l.XS + ww*xx, l.YM + l.YS*yy
stack = Hurricane_Reserve(x, y, self, max_accept=1) stack = Hurricane_Reserve(x, y, self, max_accept=1)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
@ -1310,7 +1331,6 @@ class Hurricane(Pyramid):
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
def startGame(self): def startGame(self):
for i in range(2): for i in range(2):
self.s.talon.dealRow(rows=self.s.reserves, frames=0) self.s.talon.dealRow(rows=self.s.reserves, frames=0)
@ -1318,7 +1338,6 @@ class Hurricane(Pyramid):
self.s.talon.dealRow(rows=self.s.reserves) self.s.talon.dealRow(rows=self.s.reserves)
self.s.talon.dealRow() self.s.talon.dealRow()
def fillStack(self, stack): def fillStack(self, stack):
if stack in self.s.rows and not stack.cards and self.s.talon.cards: if stack in self.s.rows and not stack.cards and self.s.talon.cards:
old_state = self.enterState(self.S_FILL) old_state = self.enterState(self.S_FILL)
@ -1327,15 +1346,15 @@ class Hurricane(Pyramid):
self.leaveState(old_state) self.leaveState(old_state)
# register the game # register the game
registerGame(GameInfo(38, Pyramid, "Pyramid", registerGame(GameInfo(38, Pyramid, "Pyramid",
GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(193, RelaxedPyramid, "Relaxed Pyramid", registerGame(GameInfo(193, RelaxedPyramid, "Relaxed Pyramid",
GI.GT_PAIRING_TYPE | GI.GT_RELAXED, 1, 2, GI.SL_MOSTLY_LUCK, GI.GT_PAIRING_TYPE | GI.GT_RELAXED, 1, 2,
altnames=(" Pyramid's Stones",) )) GI.SL_MOSTLY_LUCK,
##registerGame(GameInfo(44, Thirteen, "Thirteen", altnames=(" Pyramid's Stones",)))
## GI.GT_PAIRING_TYPE, 1, 0)) # registerGame(GameInfo(44, Thirteen, "Thirteen",
# GI.GT_PAIRING_TYPE, 1, 0))
registerGame(GameInfo(592, Giza, "Giza", registerGame(GameInfo(592, Giza, "Giza",
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0, GI.SL_BALANCED)) GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(593, Thirteens, "Thirteens", registerGame(GameInfo(593, Thirteens, "Thirteens",
@ -1354,7 +1373,7 @@ registerGame(GameInfo(655, Pharaohs, "Pharaohs",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(657, Baroness, "Baroness", registerGame(GameInfo(657, Baroness, "Baroness",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED, GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED,
altnames=('Five Piles',) )) altnames=('Five Piles',)))
registerGame(GameInfo(658, Apophis, "Apophis", registerGame(GameInfo(658, Apophis, "Apophis",
GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(659, Cheops, "Cheops", registerGame(GameInfo(659, Cheops, "Cheops",
@ -1362,7 +1381,8 @@ registerGame(GameInfo(659, Cheops, "Cheops",
registerGame(GameInfo(674, Exit, "Exit", registerGame(GameInfo(674, Exit, "Exit",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(677, TwoPyramids, "Two Pyramids", registerGame(GameInfo(677, TwoPyramids, "Two Pyramids",
GI.GT_PAIRING_TYPE | GI.GT_ORIGINAL, 2, 2, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE | GI.GT_ORIGINAL, 2, 2,
GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(681, KingTut, "King Tut", registerGame(GameInfo(681, KingTut, "King Tut",
GI.GT_PAIRING_TYPE, 1, -1, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, -1, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(699, DoublePyramid, "Double Pyramid", registerGame(GameInfo(699, DoublePyramid, "Double Pyramid",
@ -1370,6 +1390,7 @@ registerGame(GameInfo(699, DoublePyramid, "Double Pyramid",
registerGame(GameInfo(700, Triangle, "Triangle", registerGame(GameInfo(700, Triangle, "Triangle",
GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(701, UpAndDown, "Up and Down", registerGame(GameInfo(701, UpAndDown, "Up and Down",
GI.GT_PAIRING_TYPE | GI.GT_ORIGINAL, 2, 2, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE | GI.GT_ORIGINAL, 2, 2,
GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(735, Hurricane, "Hurricane", registerGame(GameInfo(735, Hurricane, "Hurricane",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))

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/[a-oy-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-py-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." );