mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ 3 new games
git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@105 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
56c3a15bce
commit
218c50aa5c
5 changed files with 340 additions and 2 deletions
|
@ -32,6 +32,7 @@ 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, DefaultHint, CautiousDefaultHint
|
||||||
|
from pysollib.pysoltk import MfxCanvasText
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
@ -275,6 +276,83 @@ class HospitalPatience(Game):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Board Patience
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class BoardPatience(Game):
|
||||||
|
Hint_Class = CautiousDefaultHint
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
self.setSize(l.XM+10*l.XS, l.YM+2*l.YS+12*l.YOFFSET)
|
||||||
|
|
||||||
|
# extra settings
|
||||||
|
self.base_card = None
|
||||||
|
|
||||||
|
# create stacks
|
||||||
|
x, y = l.XM+3*l.XS, l.YM
|
||||||
|
for i in range(4):
|
||||||
|
s.foundations.append(SS_FoundationStack(x, y, self,
|
||||||
|
suit=i, mod=13))
|
||||||
|
x = x + l.XS
|
||||||
|
tx, ty, ta, tf = l.getTextAttr(s.foundations[-1], "ne")
|
||||||
|
font = self.app.getFont("canvas_default")
|
||||||
|
self.texts.info = MfxCanvasText(self.canvas, tx, ty,
|
||||||
|
anchor=ta, font=font)
|
||||||
|
x, y = l.XM, l.YM+l.YS
|
||||||
|
for i in range(10):
|
||||||
|
s.rows.append(UD_AC_RowStack(x, y, self, mod=13))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
x, y = l.XM, l.YM
|
||||||
|
s.talon = InitialDealTalonStack(x, y, self)
|
||||||
|
|
||||||
|
# default
|
||||||
|
l.defaultAll()
|
||||||
|
|
||||||
|
def updateText(self):
|
||||||
|
if self.preview > 1:
|
||||||
|
return
|
||||||
|
if not self.texts.info:
|
||||||
|
return
|
||||||
|
if not self.base_card:
|
||||||
|
t = ""
|
||||||
|
else:
|
||||||
|
t = RANKS[self.base_card.rank]
|
||||||
|
self.texts.info.config(text=t)
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
# deal base_card to Foundations, update foundations cap.base_rank
|
||||||
|
self.base_card = self.s.talon.getCard()
|
||||||
|
for s in self.s.foundations:
|
||||||
|
s.cap.base_rank = self.base_card.rank
|
||||||
|
n = self.base_card.suit
|
||||||
|
self.flipMove(self.s.talon)
|
||||||
|
self.moveMove(1, self.s.talon, self.s.foundations[n], frames=0)
|
||||||
|
# deal to rows
|
||||||
|
for i in range(4):
|
||||||
|
self.s.talon.dealRow(frames=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealRowAvail()
|
||||||
|
|
||||||
|
shallHighlightMatch = Game._shallHighlightMatch_ACW
|
||||||
|
|
||||||
|
def _restoreGameHook(self, game):
|
||||||
|
self.base_card = self.cards[game.loadinfo.base_card_id]
|
||||||
|
for s in self.s.foundations:
|
||||||
|
s.cap.base_rank = self.base_card.rank
|
||||||
|
|
||||||
|
def _loadGameHook(self, p):
|
||||||
|
self.loadinfo.addattr(base_card_id=None) # register extra load var.
|
||||||
|
self.loadinfo.base_card_id = p.load()
|
||||||
|
|
||||||
|
def _saveGameHook(self, p):
|
||||||
|
p.dump(self.base_card.id)
|
||||||
|
|
||||||
|
|
||||||
# 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))
|
||||||
|
@ -288,4 +366,6 @@ 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",
|
||||||
|
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
|
@ -372,6 +372,143 @@ class BigBraid(Braid):
|
||||||
Foundation_Classes = [Braid_Foundation, Braid_Foundation, Braid_Foundation]
|
Foundation_Classes = [Braid_Foundation, Braid_Foundation, Braid_Foundation]
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Casket
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Casket_Hint(CautiousDefaultHint):
|
||||||
|
def computeHints(self):
|
||||||
|
CautiousDefaultHint.computeHints(self)
|
||||||
|
if self.hints:
|
||||||
|
return
|
||||||
|
if not self.game.s.waste.cards:
|
||||||
|
return
|
||||||
|
r = self.game.s.waste.cards[-1].rank
|
||||||
|
if 0 <= r <= 3:
|
||||||
|
to_stack = self.game.s.reserves[0]
|
||||||
|
elif 4 <= r <= 7:
|
||||||
|
to_stack = self.game.s.reserves[1]
|
||||||
|
else:
|
||||||
|
to_stack = self.game.s.reserves[2]
|
||||||
|
self.addHint(5000, 1, self.game.s.waste, to_stack)
|
||||||
|
|
||||||
|
|
||||||
|
class JewelsStack(OpenStack):
|
||||||
|
def canFlipCard(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Casket_RowStack(SS_RowStack):
|
||||||
|
def getBottomImage(self):
|
||||||
|
return self.game.app.images.getReserveBottom()
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not SS_RowStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
if not self.cards:
|
||||||
|
# don't accepts from lid
|
||||||
|
return from_stack not in self.game.s.lid
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class Casket_Reserve(ReserveStack):
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not ReserveStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
return from_stack is self.game.s.waste
|
||||||
|
|
||||||
|
|
||||||
|
class Casket(Game):
|
||||||
|
Hint_Class = Casket_Hint
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
# create layout
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
font=self.app.getFont("canvas_default")
|
||||||
|
|
||||||
|
# set window
|
||||||
|
self.setSize(l.XM+10*l.XS, l.YM+4.5*l.YS)
|
||||||
|
|
||||||
|
|
||||||
|
# register extra stack variables
|
||||||
|
s.addattr(jewels=None)
|
||||||
|
s.addattr(lid=[])
|
||||||
|
|
||||||
|
# create stacks
|
||||||
|
# Lid
|
||||||
|
x0, y0 = l.XM+2.5*l.XS, l.YM
|
||||||
|
for xx, yy in ((0, 0.5),
|
||||||
|
(1, 0.25),
|
||||||
|
(2, 0),
|
||||||
|
(3, 0.25),
|
||||||
|
(4, 0.5),
|
||||||
|
):
|
||||||
|
x, y = x0+xx*l.XS, y0+yy*l.YS
|
||||||
|
s.lid.append(BasicRowStack(x, y, self, max_accept=0))
|
||||||
|
|
||||||
|
# Casket
|
||||||
|
x0, y0 = l.XM+3*l.XS, l.YM+1.5*l.YS
|
||||||
|
for xx, yy in ((0,0), (3,0),
|
||||||
|
(0,1), (3,1),
|
||||||
|
(0,2),(1,2),(2,2),(3,2),
|
||||||
|
):
|
||||||
|
x, y = x0+xx*l.XS, y0+yy*l.YS
|
||||||
|
stack = Casket_RowStack(x, y, self, max_move=1)
|
||||||
|
stack.CARD_YOFFSET = 0
|
||||||
|
s.rows.append(stack)
|
||||||
|
|
||||||
|
# Reserves
|
||||||
|
x, y = l.XM, l.YM+1.5*l.YS
|
||||||
|
for i in range(3):
|
||||||
|
stack = Casket_Reserve(x, y, self, max_cards=UNLIMITED_CARDS)
|
||||||
|
l.createText(stack, "ne")
|
||||||
|
s.reserves.append(stack)
|
||||||
|
y += l.YS
|
||||||
|
|
||||||
|
# Foundations
|
||||||
|
x = l.XM+8*l.XS
|
||||||
|
for i in range(2):
|
||||||
|
y = l.YM
|
||||||
|
for j in range(4):
|
||||||
|
s.foundations.append(SS_FoundationStack(x, y, self, suit=j))
|
||||||
|
y += l.YS
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
# Jewels
|
||||||
|
x, y = l.XM+4.5*l.XS, l.YM+2*l.YS
|
||||||
|
s.jewels = JewelsStack(x, y, self)
|
||||||
|
l.createText(s.jewels, "s")
|
||||||
|
|
||||||
|
# waste & talon
|
||||||
|
x, y = l.XM, l.YM
|
||||||
|
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
|
||||||
|
l.createText(s.talon, "s")
|
||||||
|
x += l.XS
|
||||||
|
s.waste = WasteStack(x, y, self, max_cards=1)
|
||||||
|
|
||||||
|
# define stack-groups
|
||||||
|
self.sg.talonstacks = [s.talon] + [s.waste]
|
||||||
|
self.sg.openstacks = s.foundations + s.rows + s.reserves
|
||||||
|
self.sg.dropstacks = s.lid + s.rows + [s.waste] + s.reserves
|
||||||
|
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
for i in range(13):
|
||||||
|
self.s.talon.dealRow(rows=[self.s.jewels], frames=0, flip=0)
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealToStacksOrFoundations(stacks=self.s.lid)
|
||||||
|
self.s.talon.dealToStacksOrFoundations(stacks=self.s.rows)
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
def fillStack(self, stack):
|
||||||
|
if not stack.cards and stack in self.s.lid:
|
||||||
|
if self.s.jewels.cards:
|
||||||
|
old_state = self.enterState(self.S_FILL)
|
||||||
|
self.s.jewels.flipMove()
|
||||||
|
self.s.jewels.moveMove(1, stack)
|
||||||
|
self.leaveState(old_state)
|
||||||
|
|
||||||
|
shallHighlightMatch = Game._shallHighlightMatch_SS
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(12, Braid, "Braid",
|
registerGame(GameInfo(12, Braid, "Braid",
|
||||||
|
@ -388,3 +525,5 @@ registerGame(GameInfo(377, BackbonePlus, "Backbone +",
|
||||||
GI.GT_NAPOLEON, 2, 0, GI.SL_BALANCED))
|
GI.GT_NAPOLEON, 2, 0, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(510, BigBraid, "Big Braid",
|
registerGame(GameInfo(510, BigBraid, "Big Braid",
|
||||||
GI.GT_NAPOLEON | GI.GT_ORIGINAL, 3, 2, GI.SL_BALANCED))
|
GI.GT_NAPOLEON | GI.GT_ORIGINAL, 3, 2, GI.SL_BALANCED))
|
||||||
|
registerGame(GameInfo(694, Casket, "Casket",
|
||||||
|
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||||
|
|
|
@ -187,6 +187,17 @@ class Dial(Game):
|
||||||
|
|
||||||
BLACK, RED = 0, 1
|
BLACK, RED = 0, 1
|
||||||
|
|
||||||
|
|
||||||
|
class Hemispheres_Hint(DefaultHint):
|
||||||
|
def shallMovePile(self, from_stack, to_stack, pile, rpile):
|
||||||
|
if not self._defaultShallMovePile(from_stack, to_stack, pile, rpile):
|
||||||
|
return False
|
||||||
|
if from_stack in self.game.s.rows and to_stack in self.game.s.rows:
|
||||||
|
# check for loops
|
||||||
|
return len(from_stack.cards) == 1
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Hemispheres_RowStack(SC_RowStack):
|
class Hemispheres_RowStack(SC_RowStack):
|
||||||
|
|
||||||
def _canSwapPair(self, from_stack):
|
def _canSwapPair(self, from_stack):
|
||||||
|
@ -240,7 +251,7 @@ class Hemispheres_RowStack(SC_RowStack):
|
||||||
|
|
||||||
|
|
||||||
class Hemispheres(Game):
|
class Hemispheres(Game):
|
||||||
Hint_Class = CautiousDefaultHint
|
Hint_Class = Hemispheres_Hint
|
||||||
|
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
|
|
||||||
|
|
|
@ -1118,7 +1118,8 @@ class KingTut(RelaxedPyramid):
|
||||||
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, GI.SL_MOSTLY_LUCK,
|
||||||
|
altnames=(" Pyramid's Stones",) ))
|
||||||
##registerGame(GameInfo(44, Thirteen, "Thirteen",
|
##registerGame(GameInfo(44, Thirteen, "Thirteen",
|
||||||
## GI.GT_PAIRING_TYPE, 1, 0))
|
## GI.GT_PAIRING_TYPE, 1, 0))
|
||||||
registerGame(GameInfo(592, Giza, "Giza",
|
registerGame(GameInfo(592, Giza, "Giza",
|
||||||
|
|
|
@ -979,6 +979,111 @@ class BoxingTheCompass(FourWinds):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# /***********************************************************************
|
||||||
|
# // Colonel
|
||||||
|
# ************************************************************************/
|
||||||
|
|
||||||
|
class Colonel_Hint(DefaultHint):
|
||||||
|
def _getMoveCardBonus(self, r, t, pile, rpile):
|
||||||
|
if r in self.game.s.rows and t in self.game.s.rows:
|
||||||
|
if rpile:
|
||||||
|
return 0
|
||||||
|
return DefaultHint._getMoveCardBonus(self, r, t, pile, rpile)
|
||||||
|
|
||||||
|
|
||||||
|
class Colonel_RowStack(SS_RowStack):
|
||||||
|
|
||||||
|
def _getStackIndex(self, stack):
|
||||||
|
index = list(self.game.s.rows).index(stack)
|
||||||
|
if index < 12:
|
||||||
|
row = 0
|
||||||
|
elif 12 <= index < 24:
|
||||||
|
row = 1
|
||||||
|
else:
|
||||||
|
row = 2
|
||||||
|
return index, row
|
||||||
|
|
||||||
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not SS_RowStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
|
|
||||||
|
self_index, self_row = self._getStackIndex(self)
|
||||||
|
|
||||||
|
if self_row in (1,2):
|
||||||
|
above_stack = self.game.s.rows[self_index-12]
|
||||||
|
if not above_stack.cards:
|
||||||
|
return False
|
||||||
|
|
||||||
|
below_stack = None
|
||||||
|
if self_row in (0,1):
|
||||||
|
below_stack = self.game.s.rows[self_index+12]
|
||||||
|
|
||||||
|
# from_stack is waste
|
||||||
|
if from_stack is self.game.s.waste:
|
||||||
|
if below_stack is None or not below_stack.cards:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# from_stack in rows
|
||||||
|
from_index, from_row = self._getStackIndex(from_stack)
|
||||||
|
if below_stack and below_stack.cards:
|
||||||
|
return from_stack is below_stack
|
||||||
|
return from_row > self_row
|
||||||
|
|
||||||
|
def canMoveCards(self, cards):
|
||||||
|
self_index, self_row = self._getStackIndex(self)
|
||||||
|
if self_row in (0,1):
|
||||||
|
below_stack = self.game.s.rows[self_index+12]
|
||||||
|
if below_stack.cards:
|
||||||
|
return False
|
||||||
|
return SS_RowStack.canMoveCards(self, cards)
|
||||||
|
|
||||||
|
def getBottomImage(self):
|
||||||
|
return self.game.app.images.getReserveBottom()
|
||||||
|
|
||||||
|
|
||||||
|
class Colonel(Game):
|
||||||
|
Hint_Class = Colonel_Hint
|
||||||
|
|
||||||
|
def createGame(self):
|
||||||
|
l, s = Layout(self), self.s
|
||||||
|
self.setSize(l.XM+12*l.XS, l.YM+5*l.YS)
|
||||||
|
|
||||||
|
x, y = l.XM+2*l.XS, l.YM
|
||||||
|
for i in range(8):
|
||||||
|
s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4,
|
||||||
|
max_move=0))
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
|
y = l.YM+l.YS
|
||||||
|
for i in range(3):
|
||||||
|
x = l.XM
|
||||||
|
for j in range(12):
|
||||||
|
stack = Colonel_RowStack(x, y, self, max_move=1)
|
||||||
|
stack.CARD_YOFFSET = 0
|
||||||
|
s.rows.append(stack)
|
||||||
|
x += l.XS
|
||||||
|
y += l.YS
|
||||||
|
|
||||||
|
x, y = l.XM+5*l.XS, l.YM+4*l.YS
|
||||||
|
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
|
||||||
|
l.createText(s.talon, 'sw')
|
||||||
|
x += l.XS
|
||||||
|
s.waste = WasteStack(x, y, self)
|
||||||
|
l.createText(s.waste, 'se')
|
||||||
|
|
||||||
|
l.defaultStackGroups()
|
||||||
|
|
||||||
|
|
||||||
|
def startGame(self):
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRow()
|
||||||
|
self.s.talon.dealCards()
|
||||||
|
|
||||||
|
shallHighlightMatch = Game._shallHighlightMatch_SS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# register the game
|
# register the game
|
||||||
registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
|
registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
|
||||||
|
@ -1017,4 +1122,6 @@ registerGame(GameInfo(675, FourWinds, "Four Winds",
|
||||||
GI.GT_1DECK_TYPE, 1, 1, GI.SL_BALANCED))
|
GI.GT_1DECK_TYPE, 1, 1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(676, BoxingTheCompass, "Boxing the Compass",
|
registerGame(GameInfo(676, BoxingTheCompass, "Boxing the Compass",
|
||||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED))
|
GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED))
|
||||||
|
registerGame(GameInfo(693, Colonel, "Colonel",
|
||||||
|
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue