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.layout import Layout
|
||||
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
|
||||
registerGame(GameInfo(290, Bisley, "Bisley",
|
||||
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))
|
||||
registerGame(GameInfo(686, HospitalPatience, "Hospital Patience",
|
||||
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]
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // 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
|
||||
registerGame(GameInfo(12, Braid, "Braid",
|
||||
|
@ -388,3 +525,5 @@ registerGame(GameInfo(377, BackbonePlus, "Backbone +",
|
|||
GI.GT_NAPOLEON, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(510, BigBraid, "Big Braid",
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
|
||||
def _canSwapPair(self, from_stack):
|
||||
|
@ -240,7 +251,7 @@ class Hemispheres_RowStack(SC_RowStack):
|
|||
|
||||
|
||||
class Hemispheres(Game):
|
||||
Hint_Class = CautiousDefaultHint
|
||||
Hint_Class = Hemispheres_Hint
|
||||
|
||||
def createGame(self):
|
||||
|
||||
|
|
|
@ -1118,7 +1118,8 @@ class KingTut(RelaxedPyramid):
|
|||
registerGame(GameInfo(38, Pyramid, "Pyramid",
|
||||
GI.GT_PAIRING_TYPE, 1, 2, GI.SL_MOSTLY_LUCK))
|
||||
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",
|
||||
## GI.GT_PAIRING_TYPE, 1, 0))
|
||||
registerGame(GameInfo(592, Giza, "Giza",
|
||||
|
|
|
@ -979,6 +979,111 @@ class BoxingTheCompass(FourWinds):
|
|||
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
|
||||
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))
|
||||
registerGame(GameInfo(676, BoxingTheCompass, "Boxing the Compass",
|
||||
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