mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ 6 new games
+ new action: `show descript. of piles'; new class: StackDesc * Stack.getHelp: rename `Row' -> `Tableau' * misc. improvements git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@29 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
8e2cc715a9
commit
3814cf1cd4
21 changed files with 460 additions and 98 deletions
|
@ -501,7 +501,6 @@ class Application:
|
|||
self.toolbar = None
|
||||
self.canvas = None
|
||||
self.statusbar = None
|
||||
self.cardsets_cache = {}
|
||||
#
|
||||
self.game = None
|
||||
self.dataloader = None
|
||||
|
@ -521,6 +520,7 @@ class Application:
|
|||
self.progress_images = []
|
||||
self.cardset_manager = CardsetManager()
|
||||
self.cardset = None # current cardset
|
||||
self.cardsets_cache = {}
|
||||
self.tabletile_manager = TileManager()
|
||||
self.tabletile_index = 0 # current table tile
|
||||
self.sample_manager = SampleManager()
|
||||
|
|
|
@ -116,6 +116,7 @@ class Game:
|
|||
self.cards = []
|
||||
self.stackmap = {} # dict with (x,y) tuples as key
|
||||
self.allstacks = []
|
||||
self.stackdesc_list = []
|
||||
self.demo_logo = None
|
||||
self.pause_logo = None
|
||||
self.s = Struct( # stacks
|
||||
|
@ -701,6 +702,7 @@ class Game:
|
|||
if break_pause and self.pause:
|
||||
self.doPause()
|
||||
self.interruptSleep()
|
||||
self.deleteStackDesc()
|
||||
if self.busy: return 1
|
||||
if self.drag.stack:
|
||||
self.drag.stack.cancelDrag()
|
||||
|
@ -715,12 +717,14 @@ class Game:
|
|||
self.app.menubar.disableMenus()
|
||||
|
||||
|
||||
|
||||
#
|
||||
# UI & graphics support
|
||||
#
|
||||
|
||||
def clickHandler(self, *args):
|
||||
self.interruptSleep()
|
||||
self.deleteStackDesc()
|
||||
if self.demo:
|
||||
self.stopDemo()
|
||||
return EVENT_PROPAGATE
|
||||
|
@ -793,7 +797,7 @@ class Game:
|
|||
def _unmapHandler(self, event):
|
||||
# pause game if root window has been iconified
|
||||
if event.widget is self.top and not self.pause:
|
||||
self.doPause()
|
||||
self.app.menubar.mPause()
|
||||
|
||||
|
||||
#
|
||||
|
@ -2461,6 +2465,29 @@ in the current implementation.''' % version
|
|||
if kw.has_key('help') and self.app.opt.helpbar:
|
||||
self.app.helpbar.updateText(info=kw['help'])
|
||||
|
||||
#
|
||||
# Piles descriptions
|
||||
#
|
||||
|
||||
def showStackDesc(self):
|
||||
from pysoltk import StackDesc
|
||||
from stack import InitialDealTalonStack
|
||||
sd_list = []
|
||||
for s in self.allstacks:
|
||||
sd = (s.__class__.__name__, s.cap.base_rank, s.cap.dir)
|
||||
if sd in sd_list:
|
||||
# one of each uniq pile
|
||||
continue
|
||||
if isinstance(s, InitialDealTalonStack):
|
||||
continue
|
||||
self.stackdesc_list.append(StackDesc(self, s))
|
||||
sd_list.append(sd)
|
||||
|
||||
def deleteStackDesc(self):
|
||||
if self.stackdesc_list:
|
||||
for sd in self.stackdesc_list:
|
||||
sd.delete()
|
||||
self.stackdesc_list = []
|
||||
|
||||
#
|
||||
# subclass hooks
|
||||
|
|
|
@ -154,7 +154,7 @@ class Strategy_RowStack(BasicRowStack):
|
|||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
def getHelp(self):
|
||||
return _('Row. Build regardless of rank and suit.')
|
||||
return _('Tableau. Build regardless of rank and suit.')
|
||||
|
||||
|
||||
class Strategy(Game):
|
||||
|
|
|
@ -101,7 +101,7 @@ class Calculation_RowStack(BasicRowStack):
|
|||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
def getHelp(self):
|
||||
return _('Row. Build regardless of rank and suit.')
|
||||
return _('Tableau. Build regardless of rank and suit.')
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
|
|
@ -57,7 +57,7 @@ class CurdsAndWhey_RowStack(BasicRowStack):
|
|||
return isSameSuitSequence(cards) or isRankSequence(cards, dir=0)
|
||||
|
||||
def getHelp(self):
|
||||
return _('Row. Build down by suit or of the same rank.')
|
||||
return _('Tableau. Build down by suit or of the same rank.')
|
||||
|
||||
|
||||
class CurdsAndWhey(Game):
|
||||
|
|
|
@ -41,6 +41,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
|
||||
|
||||
from fortythieves import FortyThieves_Hint
|
||||
from spider import Spider_Hint
|
||||
|
@ -138,7 +139,7 @@ class Congress(Diplomat):
|
|||
# game layout (just rearrange the stacks a little bit)
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
def createGame(self, max_rounds=1):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
|
@ -160,11 +161,18 @@ class Congress(Diplomat):
|
|||
stack.CARD_YOFFSET = 0
|
||||
s.rows.append(stack)
|
||||
x, y, = l.XM, l.YM
|
||||
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
|
||||
s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
|
||||
l.createText(s.talon, "ss")
|
||||
x = x + l.XS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
l.createText(s.waste, "ss")
|
||||
if max_rounds > 1:
|
||||
tx, ty, ta, tf = l.getTextAttr(s.waste, "ne")
|
||||
font = self.app.getFont("canvas_default")
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas,
|
||||
tx, ty,
|
||||
anchor=ta,
|
||||
font=font)
|
||||
|
||||
# define stack-groups
|
||||
l.defaultStackGroups()
|
||||
|
@ -251,6 +259,22 @@ class LittleNapoleon(Diplomat):
|
|||
return 0
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Twin Queens
|
||||
# ************************************************************************/
|
||||
|
||||
class TwinQueens(Congress):
|
||||
Foundation_Classes = [
|
||||
StackWrapper(SS_FoundationStack, base_rank=KING, mod=13),
|
||||
StackWrapper(SS_FoundationStack, base_rank=KING, mod=13),
|
||||
]
|
||||
RowStack_Class = StackWrapper(SS_RowStack, max_move=1)
|
||||
|
||||
def createGame(self):
|
||||
Congress.createGame(self, max_rounds=2)
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(149, Diplomat, "Diplomat",
|
||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
||||
|
@ -268,4 +292,6 @@ registerGame(GameInfo(548, Parliament, "Parliament",
|
|||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(549, Wheatsheaf, "Wheatsheaf",
|
||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(563, TwinQueens, "Twin Queens",
|
||||
GI.GT_FORTY_THIEVES, 2, 1, GI.SL_MOSTLY_SKILL))
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
__all__ = []
|
||||
|
||||
# imports
|
||||
import sys
|
||||
|
||||
# PySol imports
|
||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||
|
@ -43,6 +42,9 @@ from pysollib.layout import Layout
|
|||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||
from pysollib.pysoltk import MfxCanvasText
|
||||
|
||||
from gypsy import DieRussische_Foundation
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
@ -440,7 +442,7 @@ class Indian_RowStack(SequenceRowStack):
|
|||
def _isSequence(self, cards):
|
||||
return isAnySuitButOwnSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
return _('Row. Build down in any suit but the same.')
|
||||
return _('Tableau. Build down in any suit but the same.')
|
||||
|
||||
|
||||
class Indian(FortyThieves):
|
||||
|
@ -805,8 +807,6 @@ class Waterloo(FortyThieves):
|
|||
# // Junction
|
||||
# ************************************************************************/
|
||||
|
||||
from gypsy import DieRussische_Foundation
|
||||
|
||||
class Junction(Game):
|
||||
|
||||
def createGame(self, rows=7):
|
||||
|
@ -849,6 +849,89 @@ class Junction(Game):
|
|||
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // The Spark
|
||||
# ************************************************************************/
|
||||
|
||||
class TheSpark_Talon(TalonStack):
|
||||
|
||||
def canDealCards(self):
|
||||
return len(self.cards) > 0
|
||||
|
||||
def dealCards(self, sound=0):
|
||||
old_state = self.game.enterState(self.game.S_DEAL)
|
||||
num_cards = 0
|
||||
if self.cards:
|
||||
if sound and not self.game.demo:
|
||||
self.game.playSample("dealwaste")
|
||||
for i in range(self.num_deal):
|
||||
for r in self.game.s.reserves:
|
||||
if not self.cards:
|
||||
break
|
||||
self.game.flipMove(self)
|
||||
self.game.moveMove(1, self, r, frames=4, shadow=0)
|
||||
num_cards += 1
|
||||
self.game.leaveState(old_state)
|
||||
return num_cards
|
||||
|
||||
|
||||
class TheSpark(Game):
|
||||
Hint_Class = CautiousDefaultHint
|
||||
|
||||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
w, h = l.XM+8*l.XS, l.YM+4*l.YS
|
||||
self.setSize(w, h)
|
||||
|
||||
x, y = l.XM, l.YM
|
||||
for i in range(8):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self,
|
||||
suit=i/2, base_rank=KING, mod=13))
|
||||
x += l.XS
|
||||
x, y = l.XM, l.YM+l.YS
|
||||
s.talon = TheSpark_Talon(x, y, self, max_rounds=1, num_deal=3)
|
||||
l.createText(s.talon, 'se')
|
||||
y += l.YS
|
||||
for i in (0,1):
|
||||
stack = WasteStack(x, y, self)
|
||||
s.reserves.append(stack)
|
||||
l.createText(stack, 'se')
|
||||
y += l.YS
|
||||
y = l.YM+l.YS*3/2
|
||||
for i in range(2):
|
||||
x = l.XM+2*l.XS
|
||||
for j in range(6):
|
||||
stack = SS_RowStack(x, y, self, max_move=1)
|
||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
|
||||
s.rows.append(stack)
|
||||
x += l.XS
|
||||
y += l.YS
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
# move Aces to top of the Talon (i.e. first cards to be dealt)
|
||||
return self._shuffleHookMoveToTop(cards,
|
||||
lambda c: (c.rank == KING, c.suit))
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.s.talon.dealRow(rows=self.s.foundations, frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
|
||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(13, FortyThieves, "Forty Thieves",
|
||||
|
@ -941,5 +1024,7 @@ registerGame(GameInfo(540, Waterloo, "Waterloo",
|
|||
registerGame(GameInfo(556, Junction, "Junction",
|
||||
GI.GT_FORTY_THIEVES, 4, 0, GI.SL_MOSTLY_SKILL,
|
||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12) ))
|
||||
registerGame(GameInfo(564, TheSpark, "The Spark",
|
||||
GI.GT_FORTY_THIEVES, 2, 0, GI.SL_MOSTLY_LUCK))
|
||||
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ class Golf_RowStack(BasicRowStack):
|
|||
def clickHandler(self, event):
|
||||
return self.doubleclickHandler(event)
|
||||
def getHelp(self):
|
||||
return _('Row. No building.')
|
||||
return _('Tableau. No building.')
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -411,7 +411,7 @@ class BlackHole_RowStack(ReserveStack):
|
|||
def clickHandler(self, event):
|
||||
return self.doubleclickHandler(event)
|
||||
def getHelp(self):
|
||||
return _('Row. No building.')
|
||||
return _('Tableau. No building.')
|
||||
|
||||
|
||||
class BlackHole(Game):
|
||||
|
|
|
@ -539,13 +539,68 @@ class Elba(Gypsy):
|
|||
|
||||
class Millie(Gypsy):
|
||||
Layout_Method = Layout.klondikeLayout
|
||||
RowStack_Class = AC_RowStack
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Hypotenuse
|
||||
# // Eternal Triangle
|
||||
# // Right Triangle
|
||||
# ************************************************************************/
|
||||
|
||||
class Hypotenuse(Gypsy):
|
||||
Layout_Method = Layout.klondikeLayout
|
||||
RowStack_Class = KingAC_RowStack
|
||||
|
||||
def createGame(self):
|
||||
Gypsy.createGame(self, rows=10, playcards=24)
|
||||
|
||||
def startGame(self, flip=0, reverse=1):
|
||||
for i in range(1, 10):
|
||||
self.s.talon.dealRow(rows=self.s.rows[:i], flip=0, frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
|
||||
class EternalTriangle(Hypotenuse):
|
||||
|
||||
def startGame(self, flip=0, reverse=1):
|
||||
for i in range(1, 10):
|
||||
self.s.talon.dealRow(rows=self.s.rows[i:], frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
|
||||
class RightTriangle_Talon(OpenStack, DealRowTalonStack):
|
||||
def __init__(self, x, y, game, max_rounds=1, num_deal=1, **cap):
|
||||
Stack.__init__(self, x, y, game, cap=cap)
|
||||
self.max_rounds = max_rounds
|
||||
self.num_deal = num_deal
|
||||
self.round = 1
|
||||
self.base_cards = [] # for DealBaseCard_StackMethods
|
||||
|
||||
def canFlipCard(self):
|
||||
return False
|
||||
|
||||
def getBottomImage(self):
|
||||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
def getHelp(self):
|
||||
return ''
|
||||
|
||||
class RightTriangle(Hypotenuse):
|
||||
Talon_Class = StackWrapper(RightTriangle_Talon, max_accept=1, max_move=1)
|
||||
|
||||
def createGame(self):
|
||||
Gypsy.createGame(self, rows=10, playcards=24)
|
||||
self.sg.dropstacks.append(self.s.talon)
|
||||
self.sg.openstacks.append(self.s.talon)
|
||||
self.sg.reservestacks.append(self.s.talon)
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(1, Gypsy, "Gypsy",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
|
@ -593,4 +648,11 @@ registerGame(GameInfo(487, Millie, "Millie",
|
|||
GI.GT_GYPSY, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(498, Steve, "Steve",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(566, Hypotenuse, "Hypotenuse",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(567, EternalTriangle, "Eternal Triangle",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL,
|
||||
altnames=('Lobachevsky',) ))
|
||||
registerGame(GameInfo(568, RightTriangle, "Right Triangle",
|
||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
|
||||
|
|
|
@ -224,12 +224,14 @@ class Arabella(DoubleKlondike):
|
|||
# ************************************************************************/
|
||||
|
||||
class BigDeal(DoubleKlondike):
|
||||
def createGame(self, rows=12, max_rounds=2):
|
||||
RowStack_Class = KingAC_RowStack
|
||||
|
||||
def createGame(self, rows=12, max_rounds=2, XOFFSET=0):
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+(rows+2)*l.XS, l.YM+8*l.YS)
|
||||
x, y = l.XM, l.YM
|
||||
for i in range(rows):
|
||||
s.rows.append(AC_RowStack(x, y, self, base_rank=KING))
|
||||
s.rows.append(self.RowStack_Class(x, y, self))
|
||||
x += l.XS
|
||||
for i in range(2):
|
||||
y = l.YM
|
||||
|
@ -242,16 +244,39 @@ class BigDeal(DoubleKlondike):
|
|||
l.createText(s.talon, 'n')
|
||||
x += l.XS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
s.waste.CARD_XOFFSET = XOFFSET
|
||||
l.createText(s.waste, 'n')
|
||||
if max_rounds > 1:
|
||||
tx, ty, ta, tf = l.getTextAttr(s.talon, 'nn')
|
||||
ty -= 2*l.TEXT_MARGIN
|
||||
ty -= l.TEXT_MARGIN
|
||||
font = self.app.getFont('canvas_default')
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, anchor=ta, font=font)
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
|
||||
anchor=ta, font=font)
|
||||
self.setRegion(s.rows, (-999, -999, l.XM+rows*l.XS-l.CW/2, 999999), priority=1)
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Delivery
|
||||
# ************************************************************************/
|
||||
|
||||
class Delivery(BigDeal):
|
||||
RowStack_Class = StackWrapper(SS_RowStack, max_move=1)
|
||||
|
||||
def createGame(self):
|
||||
dx = self.app.images.CARDW/10
|
||||
BigDeal.createGame(self, rows=12, max_rounds=1, XOFFSET=dx)
|
||||
|
||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||
|
||||
def startGame(self):
|
||||
for i in range(2):
|
||||
self.s.talon.dealRow(frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(21, DoubleKlondike, "Double Klondike",
|
||||
|
@ -277,4 +302,6 @@ registerGame(GameInfo(497, Arabella, "Arabella",
|
|||
GI.GT_KLONDIKE, 3, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(545, BigDeal, "Big Deal",
|
||||
GI.GT_KLONDIKE | GI.GT_ORIGINAL, 4, 1, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(562, Delivery, "Delivery",
|
||||
GI.GT_FORTY_THIEVES | GI.GT_ORIGINAL, 4, 0, GI.SL_BALANCED))
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ class ThumbAndPouch_RowStack(SequenceRowStack):
|
|||
def _isSequence(self, cards):
|
||||
return isAnySuitButOwnSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
return _('Row. Build down in any suit but the same.')
|
||||
return _('Tableau. Build down in any suit but the same.')
|
||||
|
||||
|
||||
class ThumbAndPouch(Klondike):
|
||||
|
|
|
@ -86,8 +86,8 @@ class Numerica_RowStack(BasicRowStack):
|
|||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
def getHelp(self):
|
||||
##return _('Row. Accepts any one card from the Waste.')
|
||||
return _('Row. Build regardless of rank and suit.')
|
||||
##return _('Tableau. Accepts any one card from the Waste.')
|
||||
return _('Tableau. Build regardless of rank and suit.')
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -233,8 +233,8 @@ class PussInTheCorner_RowStack(BasicRowStack):
|
|||
def getBottomImage(self):
|
||||
return self.game.app.images.getReserveBottom()
|
||||
def getHelp(self):
|
||||
##return _('Row. Accepts any one card from the Waste.')
|
||||
return _('Row. Build regardless of rank and suit.')
|
||||
##return _('Tableau. Accepts any one card from the Waste.')
|
||||
return _('Tableau. Build regardless of rank and suit.')
|
||||
|
||||
|
||||
class PussInTheCorner(Numerica):
|
||||
|
@ -587,7 +587,7 @@ class Strategerie_RowStack(BasicRowStack):
|
|||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
def getHelp(self):
|
||||
return _('Row. Build regardless of rank and suit.')
|
||||
return _('Tableau. Build regardless of rank and suit.')
|
||||
|
||||
|
||||
class Strategerie_ReserveStack(ReserveStack):
|
||||
|
|
|
@ -146,22 +146,22 @@ class Foursome(Game):
|
|||
|
||||
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
|
||||
max_rows = max(8, rows)
|
||||
self.setSize(l.XM+max_rows*l.XS, l.YM+2*l.YS+13*l.YOFFSET)
|
||||
x, y = l.XM+l.XS*(max_rows-4)/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
|
||||
x, y = l.XM+l.XS*(max_rows-rows)/2, 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)
|
||||
s.talon = self.Talon_Class(l.XM, l.YM, self)
|
||||
if texts:
|
||||
l.createText(s.talon, 'n')
|
||||
l.createText(s.talon, 'ne')
|
||||
l.defaultStackGroups()
|
||||
|
||||
def startGame(self):
|
||||
|
|
|
@ -233,21 +233,6 @@ class Alhambra_RowStack(UD_SS_RowStack):
|
|||
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])
|
||||
|
|
|
@ -746,22 +746,23 @@ class Marshal(Game):
|
|||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+8*l.XS, l.YM+5*l.YS)
|
||||
self.setSize(l.XM+9*l.XS, l.YM+5*l.YS)
|
||||
|
||||
x, y = l.XM, l.YM
|
||||
for i in range(4):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
|
||||
x += l.XS
|
||||
y += l.YS
|
||||
x, y = self.width-l.XS, l.YM
|
||||
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, l.YM+l.YS
|
||||
s.talon = TalonStack(x, y, self)
|
||||
y += l.YS
|
||||
x, y = (self.width-l.XS)/2, self.height-l.YS
|
||||
s.talon = DealRowTalonStack(x, y, self)
|
||||
l.createText(s.talon, 'se')
|
||||
y = l.YM+l.YS
|
||||
y = l.YM
|
||||
for i in range(4):
|
||||
x = l.XM+2*l.XS
|
||||
x = l.XM+l.XS*3/2
|
||||
for j in range(6):
|
||||
stack = UD_SS_RowStack(x, y, self, base_rank=NO_RANK)
|
||||
s.rows.append(stack)
|
||||
|
@ -788,6 +789,75 @@ class Marshal(Game):
|
|||
(abs(card1.rank-card2.rank) == 1))
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Royal Aids
|
||||
# ************************************************************************/
|
||||
|
||||
class RoyalAids_RowStack(KingAC_RowStack):
|
||||
def getBottomImage(self):
|
||||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
|
||||
class RoyalAids(Game):
|
||||
|
||||
Hint_Class = CautiousDefaultHint
|
||||
|
||||
def createGame(self):
|
||||
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+8*l.XS, l.YM+4*l.YS)
|
||||
|
||||
x0 = l.XM+1.5*l.XS
|
||||
for k in (0,1):
|
||||
suit = 0
|
||||
for i, j in ((1,0), (0,0.5), (2,0.5), (1,1)):
|
||||
x, y = x0+i*l.XS, l.YM+j*l.YS
|
||||
s.foundations.append(AC_FoundationStack(x, y, self, suit=suit))
|
||||
suit += 1
|
||||
x0 += 3.5*l.XS
|
||||
|
||||
x, y = l.XM, l.YM+l.YS
|
||||
s.talon = WasteTalonStack(x, y, self, max_rounds=UNLIMITED_REDEALS)
|
||||
l.createText(s.talon, 'se')
|
||||
y += l.YS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
l.createText(s.waste, 'se')
|
||||
|
||||
x, y = l.XM+4*l.XS, l.YM+2*l.YS
|
||||
for i in (0,1):
|
||||
stack = RoyalAids_RowStack(x, y, self, max_move=1)
|
||||
s.rows.append(stack)
|
||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
|
||||
x += l.XS
|
||||
x, y = l.XM+3*l.XS, l.YM+3*l.YS
|
||||
for i in range(4):
|
||||
stack = BasicRowStack(x, y, self)
|
||||
s.reserves.append(stack)
|
||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = 0, 0
|
||||
x += l.XS
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
return self._shuffleHookMoveToTop(cards,
|
||||
lambda c: (c.rank == ACE, (c.deck, c.suit)))
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.s.talon.dealRow(rows=self.s.foundations, frames=0)
|
||||
for i in range(6):
|
||||
self.s.talon.dealRow(rows=self.s.reserves, frames=0)
|
||||
self.startDealSample()
|
||||
for i in range(4):
|
||||
self.s.talon.dealRow(rows=self.s.reserves)
|
||||
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(330, Sultan, "Sultan",
|
||||
|
@ -819,3 +889,5 @@ registerGame(GameInfo(477, CornerSuite, "Corner Suite",
|
|||
GI.GT_2DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(559, Marshal, "Marshal",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(565, RoyalAids, "Royal Aids",
|
||||
GI.GT_2DECK_TYPE, 2, UNLIMITED_REDEALS, GI.SL_BALANCED))
|
||||
|
|
|
@ -77,6 +77,7 @@ class Windmill(Game):
|
|||
]
|
||||
RowStack_Class = Windmill_RowStack
|
||||
|
||||
FOUNDATIONS_LAYOUT = ((1,0.6), (3,0.6), (1,3.4), (3,3.4))
|
||||
ROWS_LAYOUT = ((2,0), (2,1), (0,2), (1,2), (3,2), (4,2), (2,3), (2,4))
|
||||
FILL_STACK = True
|
||||
|
||||
|
@ -84,12 +85,14 @@ class Windmill(Game):
|
|||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
def createGame(self, card_x_space=20):
|
||||
# create layout
|
||||
l, s = Layout(self, card_x_space=20), self.s
|
||||
l, s = Layout(self, card_x_space=card_x_space), self.s
|
||||
|
||||
# set window
|
||||
self.setSize(7*l.XS+l.XM, 5*l.YS+l.YM+l.YM)
|
||||
max_x = max([i[0] for i in self.FOUNDATIONS_LAYOUT+self.ROWS_LAYOUT])
|
||||
max_y = max([i[1] for i in self.FOUNDATIONS_LAYOUT+self.ROWS_LAYOUT])
|
||||
self.setSize((3+max_x)*l.XS+l.XM, (1+max_y)*l.YS+l.YM+l.YM)
|
||||
|
||||
# create stacks
|
||||
x = l.XM
|
||||
|
@ -109,7 +112,7 @@ class Windmill(Game):
|
|||
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)):
|
||||
for d in self.FOUNDATIONS_LAYOUT:
|
||||
x, y = x0 + d[0] * l.XS, y0 + d[1] * l.YS
|
||||
s.foundations.append(fnd_cls(x, y, self))
|
||||
|
||||
|
@ -158,22 +161,38 @@ class DutchSolitaire_RowStack(UD_RK_RowStack):
|
|||
|
||||
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),
|
||||
StackWrapper(BlackHole_Foundation, suit=ANY_SUIT, mod=13,
|
||||
max_cards=UNLIMITED_CARDS, min_cards=1),
|
||||
StackWrapper(BlackHole_Foundation, suit=ANY_SUIT, mod=13,
|
||||
max_cards=UNLIMITED_CARDS, min_cards=1),
|
||||
]
|
||||
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))
|
||||
FOUNDATIONS_LAYOUT = ((1,1), (3,1), (1,3), (3,3))
|
||||
ROWS_LAYOUT = ((2,0.5), (-0.5,2), (0.5,2), (3.5,2), (4.5,2), (2,3.5))
|
||||
FILL_STACK = False
|
||||
|
||||
def createGame(self):
|
||||
Windmill.createGame(self, card_x_space=10)
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
return cards
|
||||
# move 5 Aces to top of the Talon (i.e. first cards to be dealt)
|
||||
def select_cards(c):
|
||||
if c.rank == ACE:
|
||||
if c.suit in (0, 1):
|
||||
return True, c.suit
|
||||
if c.suit == 3 and c.deck == 0:
|
||||
return True, c.suit
|
||||
return False, None
|
||||
return self._shuffleHookMoveToTop(cards, select_cards)
|
||||
|
||||
def startGame(self):
|
||||
self.s.talon.dealRow(rows=self.s.foundations, frames=0)
|
||||
for i in range(8):
|
||||
self.s.talon.dealRow(frames=0)
|
||||
self.startDealSample()
|
||||
#self.s.talon.dealRow(rows=(self.s.foundations[0],))
|
||||
#self.s.talon.dealRow()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
def getAutoStacks(self, event=None):
|
||||
|
|
|
@ -140,7 +140,7 @@ class Moosehide_RowStack(Yukon_AC_RowStack):
|
|||
def _isSequence(self, c1, c2):
|
||||
return (c1.suit != c2.suit and c1.rank == c2.rank+1)
|
||||
def getHelp(self):
|
||||
return _('Row. Build down in any suit but the same, can move any face-up cards regardless of sequence.')
|
||||
return _('Tableau. Build down in any suit but the same, can move any face-up cards regardless of sequence.')
|
||||
|
||||
class Moosehide(Yukon):
|
||||
RowStack_Class = StackWrapper(Moosehide_RowStack, base_rank=KING)
|
||||
|
@ -199,7 +199,7 @@ class Alaska_RowStack(Yukon_SS_RowStack):
|
|||
((c1.rank + self.cap.dir) % self.cap.mod == c2.rank or
|
||||
(c2.rank + self.cap.dir) % self.cap.mod == c1.rank))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down by suit, can move any face-up cards regardless of sequence.')
|
||||
return _('Tableau. Build up or down by suit, can move any face-up cards regardless of sequence.')
|
||||
|
||||
|
||||
class Alaska(RussianSolitaire):
|
||||
|
@ -216,7 +216,7 @@ class Roslin_RowStack(Yukon_AC_RowStack):
|
|||
((c1.rank + self.cap.dir) % self.cap.mod == c2.rank or
|
||||
(c2.rank + self.cap.dir) % self.cap.mod == c1.rank))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down by alternate color, can move any face-up cards regardless of sequence.')
|
||||
return _('Tableau. Build up or down by alternate color, can move any face-up cards regardless of sequence.')
|
||||
|
||||
|
||||
class Roslin(Yukon):
|
||||
|
|
|
@ -500,7 +500,7 @@ class Layout:
|
|||
if rows < maxrows: x += (maxrows-rows) * XS/2
|
||||
##y += YM * (3 - foundrows)
|
||||
y += text_height
|
||||
self.setRegion(self.s.rows, (-999, y - YM / 2, 999999, 999999))
|
||||
self.setRegion(self.s.rows, (-999, y-CH/2, 999999, 999999))
|
||||
for i in range(rows):
|
||||
self.s.rows.append(S(x, y))
|
||||
x = x + XS
|
||||
|
|
|
@ -1556,8 +1556,8 @@ class TalonStack(Stack,
|
|||
##round = _('Round #%d.') % self.round
|
||||
return _('Talon.')+' '+nredeals ##+' '+round
|
||||
|
||||
def getBaseCard(self):
|
||||
return self._getBaseCard()
|
||||
#def getBaseCard(self):
|
||||
# return self._getBaseCard()
|
||||
|
||||
|
||||
# A single click deals one card to each of the RowStacks.
|
||||
|
@ -1777,6 +1777,9 @@ class AbstractFoundationStack(OpenStack):
|
|||
if len(self.cards) == self.cap.max_cards:
|
||||
self.game.closeStackMove(self)
|
||||
|
||||
def getHelp(self):
|
||||
return _('Foundation.')
|
||||
|
||||
|
||||
# A SameSuit_FoundationStack is the typical Foundation stack.
|
||||
# It builds up in rank and suit.
|
||||
|
@ -1874,7 +1877,7 @@ class BasicRowStack(OpenStack):
|
|||
|
||||
def getHelp(self):
|
||||
if self.cap.max_accept == 0:
|
||||
return _('Row. No building.')
|
||||
return _('Tableau. No building.')
|
||||
return ''
|
||||
|
||||
#def getBaseCard(self):
|
||||
|
@ -1904,9 +1907,9 @@ class AC_RowStack(SequenceRowStack):
|
|||
def _isSequence(self, cards):
|
||||
return isAlternateColorSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up by alternate color.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down by alternate color.')
|
||||
else: return _('Row. Build by same rank.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up by alternate color.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down by alternate color.')
|
||||
else: return _('Tableau. Build by same rank.')
|
||||
|
||||
# A SameColor_RowStack builds down by rank and same color.
|
||||
# e.g. Klondike
|
||||
|
@ -1914,27 +1917,27 @@ class SC_RowStack(SequenceRowStack):
|
|||
def _isSequence(self, cards):
|
||||
return isSameColorSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up by color.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down by color.')
|
||||
else: return _('Row. Build by same rank.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up by color.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down by color.')
|
||||
else: return _('Tableau. Build by same rank.')
|
||||
|
||||
# A SameSuit_RowStack builds down by rank and suit.
|
||||
class SS_RowStack(SequenceRowStack):
|
||||
def _isSequence(self, cards):
|
||||
return isSameSuitSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up by suit.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down by suit.')
|
||||
else: return _('Row. Build by same rank.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up by suit.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down by suit.')
|
||||
else: return _('Tableau. Build by same rank.')
|
||||
|
||||
# A Rank_RowStack builds down by rank ignoring suit.
|
||||
class RK_RowStack(SequenceRowStack):
|
||||
def _isSequence(self, cards):
|
||||
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up regardless of suit.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down regardless of suit.')
|
||||
else: return _('Row. Build by same rank.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up regardless of suit.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down regardless of suit.')
|
||||
else: return _('Tableau. Build by same rank.')
|
||||
|
||||
# A Freecell_AlternateColor_RowStack
|
||||
class FreeCell_AC_RowStack(AC_RowStack):
|
||||
|
@ -1960,9 +1963,9 @@ class Spider_SS_RowStack(SS_RowStack):
|
|||
def _isAcceptableSequence(self, cards):
|
||||
return isRankSequence(cards, self.cap.mod, self.cap.dir)
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up regardless of suit.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down regardless of suit.')
|
||||
else: return _('Row. Build by same rank.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up regardless of suit.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down regardless of suit.')
|
||||
else: return _('Tableau. Build by same rank.')
|
||||
|
||||
# A Yukon_AlternateColor_RowStack builds down by rank and alternate color,
|
||||
# but can move any face-up cards regardless of sequence.
|
||||
|
@ -1983,10 +1986,12 @@ class Yukon_AC_RowStack(BasicRowStack):
|
|||
return 1
|
||||
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up by alternate color, can move any face-up cards regardless of sequence.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down by alternate color, can move any face-up cards regardless of sequence.')
|
||||
else: return _('Row. Build by same rank, can move any face-up cards regardless of sequence.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up by alternate color, can move any face-up cards regardless of sequence.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down by alternate color, can move any face-up cards regardless of sequence.')
|
||||
else: return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.')
|
||||
|
||||
def getBaseCard(self):
|
||||
return self._getBaseCard()
|
||||
|
||||
# A Yukon_SameSuit_RowStack builds down by rank and suit,
|
||||
# but can move any face-up cards regardless of sequence.
|
||||
|
@ -1994,9 +1999,9 @@ class Yukon_SS_RowStack(Yukon_AC_RowStack):
|
|||
def _isSequence(self, c1, c2):
|
||||
return (c1.rank + self.cap.dir) % self.cap.mod == c2.rank and c1.suit == c2.suit
|
||||
def getHelp(self):
|
||||
if self.cap.dir > 0: return _('Row. Build up by suit, can move any face-up cards regardless of sequence.')
|
||||
elif self.cap.dir < 0: return _('Row. Build down by suit, can move any face-up cards regardless of sequence.')
|
||||
else: return _('Row. Build by same rank, can move any face-up cards regardless of sequence.')
|
||||
if self.cap.dir > 0: return _('Tableau. Build up by suit, can move any face-up cards regardless of sequence.')
|
||||
elif self.cap.dir < 0: return _('Tableau. Build down by suit, can move any face-up cards regardless of sequence.')
|
||||
else: return _('Tableau. Build by same rank, can move any face-up cards regardless of sequence.')
|
||||
|
||||
#
|
||||
# King-versions of some of the above stacks: they accepts only Kings or
|
||||
|
@ -2028,7 +2033,7 @@ class UD_SC_RowStack(SequenceRowStack):
|
|||
return (isSameColorSequence(cards, self.cap.mod, 1) or
|
||||
isSameColorSequence(cards, self.cap.mod, -1))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down by color.')
|
||||
return _('Tableau. Build up or down by color.')
|
||||
|
||||
# up or down by alternate color
|
||||
class UD_AC_RowStack(SequenceRowStack):
|
||||
|
@ -2039,7 +2044,7 @@ class UD_AC_RowStack(SequenceRowStack):
|
|||
return (isAlternateColorSequence(cards, self.cap.mod, 1) or
|
||||
isAlternateColorSequence(cards, self.cap.mod, -1))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down by alternate color.')
|
||||
return _('Tableau. Build up or down by alternate color.')
|
||||
|
||||
# up or down by suit
|
||||
class UD_SS_RowStack(SequenceRowStack):
|
||||
|
@ -2050,7 +2055,7 @@ class UD_SS_RowStack(SequenceRowStack):
|
|||
return (isSameSuitSequence(cards, self.cap.mod, 1) or
|
||||
isSameSuitSequence(cards, self.cap.mod, -1))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down by suit.')
|
||||
return _('Tableau. Build up or down by suit.')
|
||||
|
||||
# up or down by rank ignoring suit
|
||||
class UD_RK_RowStack(SequenceRowStack):
|
||||
|
@ -2061,7 +2066,7 @@ class UD_RK_RowStack(SequenceRowStack):
|
|||
return (isRankSequence(cards, self.cap.mod, 1) or
|
||||
isRankSequence(cards, self.cap.mod, -1))
|
||||
def getHelp(self):
|
||||
return _('Row. Build up or down regardless of suit.')
|
||||
return _('Tableau. Build up or down regardless of suit.')
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
__all__ = ['PysolMenubar']
|
||||
|
||||
# imports
|
||||
import math, os, re, sys, types
|
||||
import math, os, re, types
|
||||
import Tkinter, tkColorChooser, tkFileDialog
|
||||
|
||||
# PySol imports
|
||||
|
@ -318,6 +318,8 @@ class PysolMenubar(PysolMenubarActions):
|
|||
menu.add_separator()
|
||||
menu.add_command(label=n_("&Demo"), command=self.mDemo, accelerator=m+"D")
|
||||
menu.add_command(label=n_("Demo (&all games)"), command=self.mMixedDemo)
|
||||
menu.add_separator()
|
||||
menu.add_command(label=n_("Show descriptions od piles"), command=self.mStackDesk, accelerator="F2")
|
||||
menu = MfxMenu(self.__menubar, label=n_("&Options"))
|
||||
menu.add_command(label=n_("&Player options..."), command=self.mOptPlayerOptions)
|
||||
submenu = MfxMenu(menu, label=n_("&Automatic play"))
|
||||
|
@ -425,8 +427,8 @@ class PysolMenubar(PysolMenubarActions):
|
|||
self._bindKey("", "Print", self.mScreenshot)
|
||||
self._bindKey(ctrl, "u", self.mPlayNextMusic) # undocumented
|
||||
self._bindKey("", "p", self.mPause)
|
||||
self._bindKey("", "Pause", self.mPause)
|
||||
self._bindKey("", "Escape", self.mIconify)
|
||||
self._bindKey("", "Pause", self.mPause) # undocumented
|
||||
self._bindKey("", "Escape", self.mIconify) # undocumented
|
||||
# ASD and LKJ
|
||||
self._bindKey("", "a", self.mDrop)
|
||||
self._bindKey(ctrl, "a", self.mDrop1)
|
||||
|
@ -436,6 +438,8 @@ class PysolMenubar(PysolMenubarActions):
|
|||
self._bindKey(ctrl, "l", self.mDrop1)
|
||||
self._bindKey("", "k", self.mUndo)
|
||||
self._bindKey("", "j", self.mDeal)
|
||||
|
||||
self._bindKey("", "F2", self.mStackDesk)
|
||||
#
|
||||
self._bindKey("", "slash", self.mGameInfo) # undocumented, devel
|
||||
|
||||
|
@ -1053,5 +1057,14 @@ class PysolMenubar(PysolMenubarActions):
|
|||
self.app.toolbar.config(w, v)
|
||||
self.top.update_idletasks()
|
||||
|
||||
#
|
||||
# stacks descriptions
|
||||
#
|
||||
|
||||
def mStackDesk(self, *event):
|
||||
if self.game.stackdesc_list:
|
||||
self.game.deleteStackDesc()
|
||||
else:
|
||||
if self._cancelDrag(break_pause=True): return
|
||||
self.game.showStackDesc()
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ __all__ = ['MfxMessageDialog',
|
|||
'MfxSimpleEntry',
|
||||
'MfxTooltip',
|
||||
'MfxScrolledCanvas',
|
||||
'StackDesc',
|
||||
]
|
||||
|
||||
# imports
|
||||
|
@ -669,3 +670,43 @@ class MfxScrolledCanvas:
|
|||
return self._yview('moveto', 1)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
class StackDesc:
|
||||
|
||||
def __init__(self, game, stack):
|
||||
self.game = game
|
||||
self.stack = stack
|
||||
self.canvas = game.canvas
|
||||
|
||||
font = game.app.getFont('canvas_small')
|
||||
##print self.app.cardset.CARDW, self.app.images.CARDW
|
||||
cardw = game.app.images.CARDW
|
||||
x, y = stack.x+cardw/2, stack.y
|
||||
text = stack.getHelp()+'\n'+stack.getBaseCard()
|
||||
text = text.strip()
|
||||
if text:
|
||||
frame = Tkinter.Frame(self.canvas, highlightthickness=1,
|
||||
highlightbackground='black')
|
||||
label = Tkinter.Message(frame, font=font, text=text, width=cardw-8,
|
||||
fg='#000000', bg='#ffffe0')
|
||||
label.pack()
|
||||
self.label = label
|
||||
self.id = self.canvas.create_window(x, y, window=frame, anchor='n')
|
||||
self.binding = label.bind('<ButtonPress>', self.buttonPressEvent)
|
||||
else:
|
||||
self.id = None
|
||||
|
||||
def buttonPressEvent(self, *event):
|
||||
self.game.deleteStackDesc()
|
||||
|
||||
def delete(self):
|
||||
if self.id:
|
||||
self.canvas.delete(self.id)
|
||||
self.label.unbind('<ButtonPress>', self.binding)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue