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

+ new file pysollib/games/grandduchess.py

+ 7 new games
* misc. improvements


git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@28 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2006-07-26 21:10:13 +00:00
parent 602ccc743f
commit 06ac5b6386
13 changed files with 495 additions and 166 deletions

View file

@ -688,6 +688,8 @@ class Application:
else:
self.requestCompatibleCardsetType(self.nextgame.id)
finally:
# hide main window
self.wm_withdraw()
# update options
self.opt.last_gameid = id
# save options

View file

@ -22,6 +22,7 @@ import fortythieves
import freecell
import glenwood
import golf
import grandduchess
import grandfathersclock
import gypsy
import harp

View file

@ -32,7 +32,6 @@
__all__ = []
# imports
import sys
# PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI
@ -41,6 +40,8 @@ from pysollib.stack import *
from pysollib.game import Game
from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText
# /***********************************************************************
# // Tam O'Shanter
@ -48,26 +49,40 @@ from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
class TamOShanter(Game):
Talon_Class = DealRowTalonStack
Foundation_Class = RK_FoundationStack
RowStack_Class = StackWrapper(BasicRowStack, max_move=1, max_accept=0)
def createGame(self):
def createGame(self, rows=4, texts=False, yoffset=None):
# create layout
l, s = Layout(self), self.s
# set window
self.setSize(l.XM + 6*l.XS, l.YM + 4*l.YS)
if yoffset is None:
yoffset = l.YOFFSET
max_rows = max(rows, 4*self.gameinfo.decks)
self.setSize(l.XM+(2+max_rows)*l.XS, l.YM+2*l.YS+12*yoffset)
# create stacks
x, y, = l.XM, l.YM
if texts:
x, y, = l.XM, l.YM+l.YS/2
else:
x, y, = l.XM, l.YM
s.talon = self.Talon_Class(x, y, self)
l.createText(s.talon, "ss")
if texts:
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = l.XM+2*l.XS, l.YM
for i in range(4):
s.foundations.append(RK_FoundationStack(x, y, self))
for i in range(4*self.gameinfo.decks):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i%4))
x += l.XS
x, y = l.XM+2*l.XS, l.YM+l.YS
for i in range(4):
s.rows.append(self.RowStack_Class(x, y, self))
for i in range(rows):
stack = self.RowStack_Class(x, y, self)
s.rows.append(stack)
stack.CARD_YOFFSET = yoffset
x += l.XS
# define stack-groups
@ -345,25 +360,15 @@ class Colorado(Game):
# // Amazons
# ************************************************************************/
class Amazons_Talon(DealRowTalonStack):
class Amazons_Talon(RedealTalonStack):
def canDealCards(self):
## FIXME: this is to avoid loops in the demo
if self.game.demo and self.game.moves.index >= 100:
return False
if self.round == self.max_rounds:
return False
return not self.game.isGameWon()
def dealCards(self, sound=0):
self.game.startDealSample()
if not self.cards:
self.game.nextRoundMove(self)
n = self._moveAllToTalon()
self.game.stopSamples()
return n
n = self.dealRowAvail()
self.game.stopSamples()
return n
RedealTalonStack.redealCards(self, frames=4, sound=sound)
return self.dealRowAvail(sound=sound)
def dealRowAvail(self, rows=None, flip=1, reverse=0, frames=-1, sound=0):
if rows is None:
@ -373,19 +378,9 @@ class Amazons_Talon(DealRowTalonStack):
if len(f.cards) < 7:
rows.append(self.game.s.rows[i])
i += 1
return DealRowTalonStack.dealRowAvail(self, rows=rows, flip=flip,
return RedealTalonStack.dealRowAvail(self, rows=rows, flip=flip,
reverse=reverse, frames=frames, sound=sound)
def _moveAllToTalon(self):
# move all cards to the Talon
num_cards = 0
for r in self.game.s.rows:
for i in range(len(r.cards)):
num_cards += 1
self.game.moveMove(1, r, self, frames=4)
self.game.flipMove(self)
return num_cards
class Amazons_Foundation(AbstractFoundationStack):
def acceptsCards(self, from_stack, cards):
@ -407,80 +402,60 @@ class Amazons_Foundation(AbstractFoundationStack):
return i == j
class Amazons(Game):
def createGame(self):
# create layout
l, s = Layout(self), self.s
# set window
self.setSize(l.XM + 6*l.XS, l.YM + 4*l.YS)
# create stacks
x, y, = l.XM, l.YM
s.talon = Amazons_Talon(x, y, self, max_rounds=-1)
l.createText(s.talon, "ss")
x, y = l.XM+2*l.XS, l.YM
for i in range(4):
s.foundations.append(Amazons_Foundation(x, y, self, suit=i, max_cards=7))
x += l.XS
x, y = l.XM+2*l.XS, l.YM+l.YS
for i in range(4):
s.rows.append(BasicRowStack(x, y, self, max_move=1, max_accept=0))
x += l.XS
# define stack-groups
l.defaultStackGroups()
class Amazons(AuldLangSyne):
Talon_Class = StackWrapper(Amazons_Talon, max_rounds=-1)
Foundation_Class = StackWrapper(Amazons_Foundation, max_cards=7)
def _shuffleHook(self, cards):
return cards
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
def getAutoStacks(self, event=None):
return ((), (), self.sg.dropstacks)
# /***********************************************************************
# // Scuffle
# // Acquaintance
# ************************************************************************/
class Acquaintance_Talon(TalonStack): # TalonStack
class Scuffle_Talon(RedealTalonStack):
def canDealCards(self):
if self.round == self.max_rounds and not self.cards:
return False
if self.round == self.max_rounds:
return len(self.cards) != 0
return not self.game.isGameWon()
def _redeal(self):
# move all cards to the Talon
lr = len(self.game.s.rows)
num_cards = 0
assert len(self.cards) == 0
rows = self.game.s.rows
for r in rows:
for i in range(len(r.cards)):
num_cards = num_cards + 1
self.game.moveMove(1, r, self, frames=4)
self.game.flipMove(self)
assert len(self.cards) == num_cards
if num_cards == 0: # game already finished
return
self.game.nextRoundMove(self)
def dealCards(self, sound=0, shuffle=True):
if self.cards:
return self.dealRowAvail(sound=sound)
RedealTalonStack.redealCards(self, frames=4,
shuffle=shuffle, sound=sound)
return self.dealRowAvail(sound=sound)
class Scuffle(AuldLangSyne):
Talon_Class = StackWrapper(Scuffle_Talon, max_rounds=3)
def createGame(self):
AuldLangSyne.createGame(self, texts=True, yoffset=0)
class Acquaintance_Talon(Scuffle_Talon):
def dealCards(self, sound=0):
if sound:
self.game.startDealSample()
if len(self.cards) == 0:
self._redeal()
n = self.dealRowAvail(sound=sound)
if sound:
self.game.stopSamples()
return n
Scuffle_Talon.dealCards(self, sound=sound, shuffle=False)
class Acquaintance(AuldLangSyne):
Talon_Class = StackWrapper(Acquaintance_Talon, max_rounds=3)
def createGame(self, texts=False, yoffset=None):
AuldLangSyne.createGame(self, texts=True)
class DoubleAcquaintance(AuldLangSyne):
Talon_Class = StackWrapper(Acquaintance_Talon, max_rounds=3)
def createGame(self):
AuldLangSyne.createGame(self, rows=8, texts=True)
# register the game
@ -500,4 +475,8 @@ registerGame(GameInfo(406, Amazons, "Amazons",
))
registerGame(GameInfo(490, Acquaintance, "Acquaintance",
GI.GT_NUMERICA, 1, 2, GI.SL_BALANCED))
registerGame(GameInfo(553, Scuffle, "Scuffle",
GI.GT_NUMERICA, 1, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(560, DoubleAcquaintance, "Double Acquaintance",
GI.GT_NUMERICA, 2, 2, GI.SL_BALANCED))

View file

@ -107,10 +107,12 @@ class FortyThieves(Game):
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds, num_deal=num_deal)
l.createText(s.talon, "n")
if max_rounds > 1:
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas,
x + l.CW / 2, y - l.TEXT_HEIGHT,
anchor="s",
font=self.app.getFont("canvas_default"))
tx, ty-l.TEXT_MARGIN,
anchor=ta,
font=font)
x = x - l.XS
s.waste = WasteStack(x, y, self)
s.waste.CARD_XOFFSET = -l.XOFFSET
@ -799,6 +801,55 @@ class Waterloo(FortyThieves):
return 0
# /***********************************************************************
# // Junction
# ************************************************************************/
from gypsy import DieRussische_Foundation
class Junction(Game):
def createGame(self, rows=7):
l, s = Layout(self), self.s
self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+12*l.YOFFSET)
y = l.YM
for i in range(2):
x = l.XM+2*l.XS
for j in range(8):
s.foundations.append(DieRussische_Foundation(x, y, self,
suit=j%4, max_cards=8))
x += l.XS
y += l.YS
x, y = l.XM+(10-rows)*l.XS/2, l.YM+2*l.YS
for i in range(rows):
s.rows.append(AC_RowStack(x, y, self))
x += l.XS
x, y = l.XM, l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, 'ne')
y += l.YS
s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'ne')
l.defaultStackGroups()
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
# register the game
registerGame(GameInfo(13, FortyThieves, "Forty Thieves",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_SKILL,
@ -887,5 +938,8 @@ registerGame(GameInfo(529, SanJuanHill, "San Juan Hill",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(540, Waterloo, "Waterloo",
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(556, Junction, "Junction",
GI.GT_FORTY_THIEVES, 4, 0, GI.SL_MOSTLY_SKILL,
ranks=(0, 6, 7, 8, 9, 10, 11, 12) ))

View file

@ -0,0 +1,139 @@
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; see the file COPYING.
## If not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
##---------------------------------------------------------------------------##
__all__ = []
# imports
import sys
# PySol imports
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.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText
# /***********************************************************************
# // Grand Duchess
# ************************************************************************/
class GrandDuchess_Talon(RedealTalonStack):
def canDealCards(self):
if self.round == self.max_rounds:
return len(self.cards) != 0
return not self.game.isGameWon()
def dealCards(self, sound=0):
rows = self.game.s.rows
reserves = self.game.s.reserves
if not self.cards:
RedealTalonStack.redealCards(self, rows=rows+reserves, sound=0)
if sound and not self.game.demo:
self.game.startDealSample()
num_cards = 0
if self.round != 4:
num_cards += self.dealRowAvail(rows=[reserves[0]], flip=0)
num_cards += self.dealRowAvail()
if self.round != 4:
num_cards += self.dealRowAvail(rows=[reserves[1]], flip=0)
if not self.cards:
for s in reserves:
self.game.flipAllMove(s)
if sound and not self.game.demo:
self.game.stopSamples()
return num_cards
class GrandDuchess_Reserve(ArbitraryStack):
def canFlipCard(self):
return False
class GrandDuchess(Game):
#
# game layout
#
def createGame(self):
# create layout
l, s = Layout(self), self.s
# set window
w, h = l.XM+9*l.XS, l.YM+2*l.YS+18*l.YOFFSET
self.setSize(w, h)
# create stacks
x, y = l.XM, l.YM
for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x += l.XS
for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self,
suit=i, base_rank=KING, dir=-1))
x += l.XS
x, y = l.XM+2*l.XS, l.YM+l.YS
for i in range(4):
stack = BasicRowStack(x, y, self, max_move=1, max_accept=0)
stack.CARD_YOFFSET = l.YOFFSET
s.rows.append(stack)
x += l.XS
x, y = l.XM, l.YM+l.YS
s.reserves.append(GrandDuchess_Reserve(x, y, self))
x, y = l.XM+7*l.XS, l.YM+l.YS
s.reserves.append(GrandDuchess_Reserve(x, y, self))
x, y = self.width-l.XS, self.height-l.YS
s.talon = GrandDuchess_Talon(x, y, self, max_rounds=4)
l.createText(s.talon, 'n')
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
font = self.app.getFont("canvas_default")
s.talon.texts.rounds = MfxCanvasText(self.canvas,
tx, ty-l.TEXT_MARGIN,
anchor=ta, font=font)
# define stack-groups
l.defaultStackGroups()
#
# game overrides
#
def startGame(self):
self.startDealSample()
self.s.talon.dealRow(rows=[self.s.reserves[0]], flip=0)
self.s.talon.dealRow()
self.s.talon.dealRow(rows=[self.s.reserves[1]], flip=0)
def getAutoStacks(self, event=None):
return ((), (), self.sg.dropstacks)
registerGame(GameInfo(557, GrandDuchess, "Grand Duchess",
GI.GT_2DECK_TYPE, 2, 3))

View file

@ -356,7 +356,8 @@ class AgnesSorel(Klondike):
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color == card2.color and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
# /***********************************************************************
@ -638,7 +639,8 @@ class Jane(Klondike):
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
((card1.rank + 1) % 13 == card2.rank or (card2.rank + 1) % 13 == card1.rank))
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
def _autoDeal(self, sound=1):
return 0

View file

@ -106,29 +106,33 @@ class Numerica(Game):
def createGame(self, rows=4):
# create layout
l, s = Layout(self), self.s
decks = self.gameinfo.decks
foundations = 4*decks
# set window
# (piles up to 20 cards are playable in default window size)
h = max(2*l.YS, 20*l.YOFFSET)
self.setSize(l.XM+(1.5+rows)*l.XS+l.XM, l.YM + l.YS + h)
max_rows = max(rows, foundations)
self.setSize(l.XM+(1.5+max_rows)*l.XS+l.XM, l.YM + l.YS + h)
# create stacks
x0 = l.XM + l.XS * 3 / 2
x, y = x0 + (rows-4)*l.XS/2, l.YM
for i in range(4):
if decks == 1:
x = x0 + (rows-4)*l.XS/2
else:
x = x0
y = l.YM
for i in range(foundations):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i))
x = x + l.XS
x, y = x0, l.YM + l.YS
for i in range(rows):
s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.XS
self.setRegion(s.rows, (x0 - l.XS / 2, y, 999999, 999999))
self.setRegion(s.rows, (x0-l.XS/2, y-l.CH/2, 999999, 999999))
x = l.XM
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
s.talon.texts.ncards = MfxCanvasText(self.canvas,
x + l.CW / 2, y - l.YM,
anchor="s",
font=self.app.getFont("canvas_default"))
l.createText(s.talon, 'n')
y = y + l.YS
s.waste = WasteStack(x, y, self, max_cards=1)
@ -153,6 +157,11 @@ class Numerica(Game):
return ()
class Numerica2Decks(Numerica):
def createGame(self):
Numerica.createGame(self, rows=6)
# /***********************************************************************
# // Lady Betty
# ************************************************************************/
@ -642,3 +651,7 @@ registerGame(GameInfo(435, Shifting, "Shifting",
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(472, Strategerie, "Strategerie",
GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(558, Numerica2Decks, "Numerica (2 decks)",
GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED))

View file

@ -43,7 +43,7 @@ from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
# /***********************************************************************
# //
# // PileOn
# ************************************************************************/
class PileOn_RowStack(RK_RowStack):
@ -127,10 +127,81 @@ class SmallPileOn(PileOn):
PLAYCARDS = 4
class PileOn2Decks(PileOn):
TWIDTH = 4
NSTACKS = 15
PLAYCARDS = 8
## class PileOn2Decks(PileOn):
## TWIDTH = 4
## NSTACKS = 15
## PLAYCARDS = 8
## registerGame(GameInfo(341, PileOn2Decks, "PileOn (2 decks)",
## GI.GT_2DECK_TYPE | GI.GT_OPEN,, 2, 0))
# /***********************************************************************
# // Foursome
# // Quartets
# ************************************************************************/
class Foursome(Game):
Hint_Class = CautiousDefaultHint
Talon_Class = DealRowTalonStack
def createGame(self, rows=6, texts=True):
l, s = Layout(self), self.s
max_rows = max(6, rows)
self.setSize(l.XM+max_rows*l.XS, l.YM+3*l.YS+13*l.YOFFSET)
x, y = l.XM+(max_rows-6)*l.XS/2, l.YM
for i in range(4):
s.reserves.append(ReserveStack(x, y, self))
x += l.XS
x = l.XM+(max_rows-1)*l.XS
s.foundations.append(AbstractFoundationStack(x, y, self,
suit=ANY_SUIT, max_cards=52, max_accept=0))
x, y = l.XM, l.YM+l.YS
for i in range(rows):
s.rows.append(UD_AC_RowStack(x, y, self, mod=13))
x += l.XS
s.talon = self.Talon_Class(self.width-l.XS, self.height-l.YS, self)
if texts:
l.createText(s.talon, 'n')
l.defaultStackGroups()
def startGame(self):
self.startDealSample()
self.s.talon.dealRow(rows=self.s.reserves)
self.s.talon.dealRow()
def fillStack(self, stack):
if not self.s.reserves[0].cards:
return
rank = self.s.reserves[0].cards[0].rank
for r in self.s.reserves[1:]:
if not r.cards or r.cards[0].rank != rank:
return
old_state = self.enterState(self.S_FILL)
self.playSample("droppair", priority=200)
for r in self.s.reserves:
self.moveMove(1, r, self.s.foundations[0], frames=4)
self.flipMove(self.s.foundations[0])
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color != card2.color and
((card1.rank + 1) % 13 == card2.rank or
(card2.rank + 1) % 13 == card1.rank))
class Quartets(Foursome):
Talon_Class = InitialDealTalonStack
def createGame(self):
Foursome.createGame(self, rows=8, texts=False)
def startGame(self):
for i in range(5):
self.s.talon.dealRow(frames=0)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
# register the game
@ -141,7 +212,9 @@ registerGame(GameInfo(289, SmallPileOn, "Small PileOn",
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),
rules_filename = "pileon.html"))
## registerGame(GameInfo(341, PileOn2Decks, "PileOn (2 decks)",
## GI.GT_2DECK_TYPE | GI.GT_OPEN,, 2, 0))
registerGame(GameInfo(554, Foursome, "Foursome",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(555, Quartets, "Quartets",
GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL))

View file

@ -222,11 +222,32 @@ class Kingdom(RoyalCotillion):
# // Granada
# ************************************************************************/
class Alhambra_Hint(CautiousDefaultHint):
def _getDropCardScore(self, score, color, r, t, ncards):
return 93000, color
class Alhambra_RowStack(UD_SS_RowStack):
def getBottomImage(self):
return self.game.app.images.getReserveBottom()
class Alhambra_Talon__(RedealTalonStack):
def canDealCards(self):
if self.round == self.max_rounds:
return len(self.cards) != 0
return not self.game.isGameWon()
def dealCards(self, sound=0):
if self.cards:
return self.dealRowAvail(sound=sound)
RedealTalonStack.redealCards(self, frames=0,
shuffle=False, sound=sound)
return self.dealRowAvail(sound=sound)
class Alhambra_Talon(DealRowTalonStack):
def canDealCards(self):
r_cards = sum([len(r.cards) for r in self.game.s.rows])
@ -259,7 +280,7 @@ class Alhambra_Talon(DealRowTalonStack):
class Alhambra(Game):
Hint_Class = CautiousDefaultHint
Hint_Class = Alhambra_Hint
def createGame(self, rows=1):
# create layout

View file

@ -731,64 +731,63 @@ class CornerSuite(Game):
# /***********************************************************************
# // Scuffle
# // Marshal
# ************************************************************************/
class Scuffle_Talon(RedealTalonStack):
def canDealCards(self):
if self.round == self.max_rounds:
return len(self.cards) != 0
return not self.game.isGameWon()
def dealCards(self, sound=0):
if self.cards:
return self.dealRowAvail(sound=sound)
RedealTalonStack.redealCards(self, shuffle=True, sound=sound)
return self.dealRowAvail(sound=sound)
class Marshal_Hint(CautiousDefaultHint):
def _getDropCardScore(self, score, color, r, t, ncards):
return 93000, color
class Scuffle_RowStack(BasicRowStack):
##clickHandler = BasicRowStack.doubleclickHandler
pass
class Marshal(Game):
class Scuffle(Game):
Hint_Class = Marshal_Hint
def createGame(self):
l, s = Layout(self), self.s
self.setSize(l.XM+6*l.XS, l.YM+2*l.YS)
self.setSize(l.XM+8*l.XS, l.YM+5*l.YS)
s.talon = Scuffle_Talon(l.XM, l.YM+l.YS/2, self, max_rounds=3)
l.createText(s.talon, 's')
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn')
font = self.app.getFont('canvas_default')
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = l.XM+2*l.XS, l.YM
x, y = l.XM, l.YM
for i in range(4):
s.foundations.append(RK_FoundationStack(x, y, self))
s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x += l.XS
x, y = l.XM+2*l.XS, l.YM+l.YS
for i in range(4):
stack = Scuffle_RowStack(x, y, self, max_move=1)
s.rows.append(stack)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
s.foundations.append(SS_FoundationStack(x, y, self,
suit=i, base_rank=KING, dir=-1))
x += l.XS
x, y = l.XM, l.YM+l.YS
s.talon = TalonStack(x, y, self)
l.createText(s.talon, 'se')
y = l.YM+l.YS
for i in range(4):
x = l.XM+2*l.XS
for j in range(6):
stack = UD_SS_RowStack(x, y, self, base_rank=NO_RANK)
s.rows.append(stack)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
x += l.XS
y += l.YS
l.defaultStackGroups()
def _shuffleHook(self, cards):
return self._shuffleHookMoveToTop(cards,
lambda c: (c.rank == ACE, c.suit))
def startGame(self):
self.startDealSample()
self.s.talon.dealRow(rows=self.s.foundations)
self.s.talon.dealRow()
def fillStack(self, stack):
if stack in self.s.rows and not stack.cards:
if self.s.talon.cards:
old_state = self.enterState(self.S_FILL)
self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, stack)
self.leaveState(old_state)
def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and
(abs(card1.rank-card2.rank) == 1))
# register the game
registerGame(GameInfo(330, Sultan, "Sultan",
@ -818,5 +817,5 @@ registerGame(GameInfo(438, SixesAndSevens, "Sixes and Sevens",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(477, CornerSuite, "Corner Suite",
GI.GT_2DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(553, Scuffle, "Scuffle",
GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(559, Marshal, "Marshal",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))

View file

@ -42,6 +42,9 @@ from pysollib.game import Game
from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from golf import BlackHole_Foundation
# /***********************************************************************
# //
# ************************************************************************/
@ -63,10 +66,18 @@ class Windmill_RowStack(ReserveStack):
# /***********************************************************************
# // Windmill
# // Dutch Solitaire
# ************************************************************************/
class Windmill(Game):
Foundation_Classes = [
StackWrapper(Windmill_Foundation, mod=13, min_cards=1, max_cards=52),
StackWrapper(Windmill_Foundation, base_rank=KING, dir=-1),
]
RowStack_Class = Windmill_RowStack
ROWS_LAYOUT = ((2,0), (2,1), (0,2), (1,2), (3,2), (4,2), (2,3), (2,4))
FILL_STACK = True
#
@ -89,16 +100,18 @@ class Windmill(Game):
s.waste = WasteStack(x, y, self)
l.createText(s.waste, "ss")
x0, y0 = x + l.XS, y
for d in ((2,0), (2,1), (0,2), (1,2), (3,2), (4,2), (2,3), (2,4)):
for d in self.ROWS_LAYOUT:
x, y = x0 + d[0] * l.XS, y0 + d[1] * l.YS
s.rows.append(Windmill_RowStack(x, y, self))
stack = self.RowStack_Class(x, y, self)
s.rows.append(stack)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
x, y = x0 + 2 * l.XS, y0 + 2 * l.YS
s.foundations.append(Windmill_Foundation(x, y, self,
mod=13, min_cards=1, max_cards=52))
fnd_cls = self.Foundation_Classes[0]
s.foundations.append(fnd_cls(x, y, self))
fnd_cls = self.Foundation_Classes[1]
for d in ((1,0.6), (3,0.6), (1,3.4), (3,3.4)):
x, y = x0 + d[0] * l.XS, y0 + d[1] * l.YS
s.foundations.append(Windmill_Foundation(x, y, self,
base_rank=KING, dir=-1))
s.foundations.append(fnd_cls(x, y, self))
# define stack-groups
l.defaultStackGroups()
@ -138,6 +151,34 @@ class Windmill(Game):
return ((), (), ())
class DutchSolitaire_RowStack(UD_RK_RowStack):
def getBottomImage(self):
return self.game.app.images.getReserveBottom()
class DutchSolitaire(Windmill):
Foundation_Classes = [
StackWrapper(BlackHole_Foundation, suit=ANY_SUIT, mod=13, max_cards=UNLIMITED_CARDS),
StackWrapper(BlackHole_Foundation, suit=ANY_SUIT, mod=13, max_cards=UNLIMITED_CARDS),
]
RowStack_Class = DutchSolitaire_RowStack
##ROWS_LAYOUT = ((2,0), (2,1), (0,2), (1,2), (3,2), (4,2), (2,3), (2,4))
ROWS_LAYOUT = ((2,0), (2,1), (1,2), (3,2), (2,3), (2,4))
FILL_STACK = False
def _shuffleHook(self, cards):
return cards
def startGame(self):
self.startDealSample()
#self.s.talon.dealRow(rows=(self.s.foundations[0],))
#self.s.talon.dealRow()
self.s.talon.dealCards() # deal first card to WasteStack
def getAutoStacks(self, event=None):
return (self.sg.dropstacks, self.sg.dropstacks, self.sg.dropstacks)
# /***********************************************************************
# // Napoleon's Tomb
@ -330,4 +371,6 @@ registerGame(GameInfo(483, Czarina, "Czarina",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(484, FourSeasons, "Four Seasons",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(561, DutchSolitaire, "Dutch Solitaire",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -121,9 +121,10 @@ class Layout:
##self.RIGHT_MARGIN = layout_x_margin-layout_card_x_space
##self.BOTTOM_MARGIN = layout_y_margin-layout_card_y_space
self.TEXT_MARGIN = 10
##self.TEXT_HEIGHT = 30
font = game.app.getFont("canvas_default")
##self.TEXT_MARGIN = 10
self.TEXT_MARGIN = font[1]
##self.TEXT_HEIGHT = 30
self.TEXT_HEIGHT = 18+font[1]
self.__dict__.update(kw)
@ -150,29 +151,30 @@ class Layout:
def getTextAttr(self, stack, anchor):
x, y = 0, 0
delta_x, delta_y = 4, 4
if stack is not None:
x, y = stack.x, stack.y
if anchor == "n":
return (x+self.CW/2, y-4, "s", "%d")
return (x+self.CW/2, y-delta_y, "s", "%d")
if anchor == "nn":
return (x+self.CW/2, y-self.TEXT_MARGIN, "s", "%d")
if anchor == "s":
return (x+self.CW/2, y+self.CH+4, "n", "%d")
return (x+self.CW/2, y+self.CH+delta_y, "n", "%d")
if anchor == "ss":
return (x+self.CW/2, y+self.CH+self.TEXT_MARGIN, "n", "%d")
if anchor == "nw":
return (x-self.TEXT_MARGIN, y, "ne", "%d")
return (x-delta_x, y, "ne", "%d")
if anchor == "sw":
return (x-self.TEXT_MARGIN, y+self.CH, "se", "%d")
return (x-delta_x, y+self.CH, "se", "%d")
f = "%2d"
if self.game.gameinfo.decks > 1:
f = "%3d"
if anchor == "ne":
return (x+self.CW+self.TEXT_MARGIN, y, "nw", f)
return (x+self.CW+delta_x, y, "nw", f)
if anchor == "se":
return (x+self.CW+self.TEXT_MARGIN, y+self.CH, "sw", f)
return (x+self.CW+delta_x, y+self.CH, "sw", f)
if anchor == "e":
return (x+self.CW+self.TEXT_MARGIN, y+self.CH/2, "w", f)
return (x+self.CW+delta_x, y+self.CH/2, "w", f)
raise Exception, anchor
def createText(self, stack, anchor, dx=0, dy=0, text_format=""):

View file

@ -1398,7 +1398,8 @@ class DealBaseCard_StackMethods:
class RedealCards_StackMethods:
def redealCards(self, rows=None, sound=0, shuffle=False, reverse=False, frames=4):
def redealCards(self, rows=None, sound=0,
shuffle=False, reverse=False, frames=0):
if sound and self.game.app.opt.animations:
self.game.startDealSample()
lr = len(self.game.s.rows)
@ -1413,7 +1414,7 @@ class RedealCards_StackMethods:
for r in rows:
for i in range(len(r.cards)):
num_cards += 1
self.game.moveMove(1, r, self, frames=0)
self.game.moveMove(1, r, self, frames=frames)
if self.cards[-1].face_up:
self.game.flipMove(self)
assert len(self.cards) == num_cards
@ -1798,11 +1799,11 @@ class SS_FoundationStack(AbstractFoundationStack):
# A Rank_FoundationStack builds up in rank and ignores color and suit.
class RK_FoundationStack(SS_FoundationStack):
def __init__(self, x, y, game, suit=ANY_SUIT, **cap):
apply(SS_FoundationStack.__init__, (self, x, y, game, suit), cap)
apply(SS_FoundationStack.__init__, (self, x, y, game, ANY_SUIT), cap)
def assertStack(self):
SS_FoundationStack.assertStack(self)
assert self.cap.suit == ANY_SUIT
##assert self.cap.suit == ANY_SUIT
assert self.cap.color == ANY_COLOR
def getHelp(self):