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

+ added solitaire wizard to Tk-binding

* improved solitaire wizard


git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@158 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2007-05-04 21:17:52 +00:00
parent 8766c00a53
commit 92cab44b85
9 changed files with 511 additions and 96 deletions

View file

@ -29,6 +29,7 @@ from hint import AbstractHint, DefaultHint, CautiousDefaultHint
from wizardutil import WizardWidgets
# /***********************************************************************
# //
# ************************************************************************/
@ -48,59 +49,118 @@ class CustomGame(Game):
v = ss[w.var_name]
s[w.var_name] = v
##from pprint import pprint; pprint(s)
foundation = StackWrapper(
s['found_type'],
base_rank=s['found_base_card'],
dir=s['found_dir'],
max_move=s['found_max_move'],
)
max_rounds = s['redeals']
if max_rounds >= 0:
max_rounds += 1
talon = StackWrapper(
s['talon'],
max_rounds=max_rounds,
)
row = StackWrapper(
s['rows_type'],
base_rank=s['rows_base_card'],
dir=s['rows_dir'],
max_move=s['rows_max_move'],
)
kw = {'rows' : s['rows_num'],
# foundations
kw = {
'dir': s['found_dir'],
'base_rank': s['found_base_card'],
}
if s['found_type'] not in (Spider_SS_Foundation,
Spider_AC_Foundation,):
kw['max_move'] = s['found_max_move']
else:
kw['dir'] = -kw['dir']
if s['found_base_card'] == KING:
kw['base_rank'] = ACE
elif s['found_base_card'] == ACE:
kw['base_rank'] = KING
if s['found_wrap']:
kw['mod'] = 13
foundation = StackWrapper(s['found_type'], **kw)
# talon
kw = {
'max_rounds': s['redeals'],
}
if s['redeals'] >= 0:
kw['max_rounds'] += 1
talon = StackWrapper(s['talon'], **kw)
# rows
kw = {
'base_rank': s['rows_base_card'],
'dir': s['rows_dir'],
'max_move': s['rows_max_move'],
}
if s['rows_wrap']:
kw['mod'] = 13
row = StackWrapper(s['rows_type'], **kw)
# layout
layout_kw = {'rows' : s['rows_num'],
'waste' : False,
'texts' : True,
}
if s['talon'] is InitialDealTalonStack:
kw['texts'] = False
if s['talon'] is WasteTalonStack:
kw['waste'] = True
kw['waste_class'] = WasteStack
if int(s['reserves_num']):
kw['reserves'] = s['reserves_num']
kw['reserve_class'] = s['reserves_type']
layout_kw['texts'] = False
layout_kw['playcards'] = 12+s['deal_to_rows']
kw['playcards'] = 12+s['deal_to_rows']
# reserves
if s['reserves_num']:
layout_kw['reserves'] = s['reserves_num']
kw = {
'max_accept': s['reserves_max_accept'],
}
if s['reserves_max_accept']:
layout_kw['reserve_class'] = StackWrapper(ReserveStack, **kw)
else:
layout_kw['reserve_class'] = StackWrapper(OpenStack, **kw)
# waste
if s['talon'] is WasteTalonStack:
layout_kw['waste'] = True
layout_kw['waste_class'] = WasteStack
Layout(self).createGame(layout_method = s['layout'],
talon_class = talon,
foundation_class = foundation,
row_class = row,
**kw
**layout_kw
)
# shallHighlightMatch
for c, f in (
((AC_RowStack, UD_AC_RowStack),
self._shallHighlightMatch_AC),
((SS_RowStack, UD_SS_RowStack),
self._shallHighlightMatch_SS),
((RK_RowStack, UD_RK_RowStack),
self._shallHighlightMatch_RK),
):
((Spider_AC_RowStack, Spider_SS_RowStack),
(self._shallHighlightMatch_RK,
self._shallHighlightMatch_RKW)),
((AC_RowStack, UD_AC_RowStack),
(self._shallHighlightMatch_AC,
self._shallHighlightMatch_ACW)),
((SS_RowStack, UD_SS_RowStack),
(self._shallHighlightMatch_SS,
self._shallHighlightMatch_SSW)),
((RK_RowStack, UD_RK_RowStack),
(self._shallHighlightMatch_RK,
self._shallHighlightMatch_RKW)),
((SC_RowStack, UD_SC_RowStack),
(self._shallHighlightMatch_SC,
self._shallHighlightMatch_SCW)),
((BO_RowStack,),
(self._shallHighlightMatch_BO,
self._shallHighlightMatch_BOW)),
):
if s['rows_type'] in c:
self.shallHighlightMatch = f
if s['rows_wrap']:
self.shallHighlightMatch = f[1]
else:
self.shallHighlightMatch = f[0]
break
# getQuickPlayScore
if s['rows_type'] in (Spider_AC_RowStack, Spider_SS_RowStack):
self.getQuickPlayScore = self._getSpiderQuickPlayScore
# canDropCards
if s['found_type'] in (Spider_SS_Foundation,
Spider_AC_Foundation,):
for stack in self.s.rows:
stack.canDropCards = stack.spiderCanDropCards
if s['found_base_card'] == ANY_RANK:
for stack in self.s.foundations:
stack.acceptsCards = stack.varyAcceptsCards
stack.getBaseCard = stack.getVaryBaseCard
def startGame(self):
frames = 0
@ -115,7 +175,7 @@ class CustomGame(Game):
self.startDealSample()
# deal to rows
flip = self.SETTINGS['deal_faceup'] == 'All cards'
flip = (self.SETTINGS['deal_faceup'] == 'All cards')
max_rows = self.SETTINGS['deal_to_rows']
if self.SETTINGS['deal_type'] == 'Triangle':
# triangle
@ -140,12 +200,16 @@ class CustomGame(Game):
if frames == 0:
self.startDealSample()
self.s.talon.dealRowAvail()
if isinstance(self.s.talon, InitialDealTalonStack):
while self.s.talon.cards:
self.s.talon.dealRowAvail()
# deal to waste
if self.s.waste:
self.s.talon.dealCards()
def registerCustomGame(gameclass):
s = gameclass.SETTINGS

View file

@ -2038,6 +2038,27 @@ for %d moves.
return ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank)
def _shallHighlightMatch_BO(self, stack1, card1, stack2, card2):
# by any suit but own
return card1.suit != card2.suit and abs(card1.rank-card2.rank) == 1
def _shallHighlightMatch_BOW(self, stack1, card1, stack2, card2):
# by any suit but own with wrapping (only for french games)
return (card1.suit != card2.suit
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
def _shallHighlightMatch_SC(self, stack1, card1, stack2, card2):
# by same color
return card1.color == card2.color and abs(card1.rank-card2.rank) == 1
def _shallHighlightMatch_SCW(self, stack1, card1, stack2, card2):
# by same color with wrapping (only for french games)
return (card1.color == card2.color
and ((card1.rank + 1) % 13 == card2.rank
or (card2.rank + 1) % 13 == card1.rank))
#
# quick-play
#

View file

@ -81,36 +81,8 @@ class Spider_Hint(SpiderType_Hint):
# //
# ************************************************************************/
class Spider_SS_Foundation(AbstractFoundationStack):
def __init__(self, x, y, game, suit=ANY_SUIT, **cap):
kwdefault(cap, dir=-1, base_rank=KING,
min_accept=13, max_accept=13, max_move=0)
AbstractFoundationStack.__init__(self, x, y, game, suit, **cap)
def acceptsCards(self, from_stack, cards):
if not AbstractFoundationStack.acceptsCards(self, from_stack, cards):
return 0
# now check the cards
return isSameSuitSequence(cards, self.cap.mod, self.cap.dir)
class Spider_AC_Foundation(Spider_SS_Foundation):
def acceptsCards(self, from_stack, cards):
if not AbstractFoundationStack.acceptsCards(self, from_stack, cards):
return 0
# now check the cards
return isAlternateColorSequence(cards, self.cap.mod, self.cap.dir)
class Spider_RowStack(Spider_SS_RowStack):
def canDropCards(self, stacks):
if len(self.cards) < 13:
return (None, 0)
cards = self.cards[-13:]
for s in stacks:
if s is not self and s.acceptsCards(self, cards):
return (s, 13)
return (None, 0)
canDropCards = BasicRowStack.spiderCanDropCards
class SuperMoveSpider_RowStack(SuperMoveStack_StackMethods, Spider_RowStack):

View file

@ -58,6 +58,8 @@ __all__ = ['cardsFaceUp',
'RK_FoundationStack',
'AC_FoundationStack',
'SC_FoundationStack',
'Spider_SS_Foundation',
'Spider_AC_Foundation',
#'SequenceStack_StackMethods',
'BasicRowStack',
'SequenceRowStack',
@ -1492,11 +1494,14 @@ class Stack:
def getBaseCard(self):
return ''
def _getBaseCard(self):
def _getBaseCard(self, rank=None):
# FIXME: no-french games
if self.cap.max_accept == 0:
return ''
br = self.cap.base_rank
if rank is None:
br = self.cap.base_rank
else:
br = rank
s = _('Base card - %s.')
if br == NO_RANK: s = _('Empty row cannot be filled.')
elif br == -1: s = s % _('any card')
@ -2068,6 +2073,28 @@ class AbstractFoundationStack(OpenStack):
def getHelp(self):
return _('Foundation.')
def varyAcceptsCards(self, from_stack, cards):
# if base rank of foundations is vary
subclass = self.__class__ # derived class (SS_FoundationStack, etc)
assert subclass is not AbstractFoundationStack
if self.cards:
return subclass.acceptsCards(self, from_stack, cards)
if not subclass.acceptsCards(self, from_stack, cards):
return False
# this stack don't have cards: check base rank of other stacks
for s in self.game.s.foundations:
if s.cards:
base_card = s.cards[0]
return base_card.rank == cards[0].rank
return True # all foundations is empty
def getVaryBaseCard(self):
rank = None
for s in self.game.s.foundations:
if s.cards:
rank = s.cards[0].rank
return self._getBaseCard(rank=rank)
# A SameSuit_FoundationStack is the typical Foundation stack.
# It builds up in rank and suit.
@ -2146,6 +2173,29 @@ class SC_FoundationStack(SS_FoundationStack):
else: return _('Foundation. Build by same rank.')
# Spider-type foundations
class Spider_SS_Foundation(AbstractFoundationStack):
def __init__(self, x, y, game, suit=ANY_SUIT, **cap):
kwdefault(cap, dir=-1, base_rank=KING,
min_accept=13, max_accept=13, max_move=0)
AbstractFoundationStack.__init__(self, x, y, game, suit, **cap)
def acceptsCards(self, from_stack, cards):
if not AbstractFoundationStack.acceptsCards(self, from_stack, cards):
return 0
# now check the cards
return isSameSuitSequence(cards, self.cap.mod, self.cap.dir)
class Spider_AC_Foundation(Spider_SS_Foundation):
def acceptsCards(self, from_stack, cards):
if not AbstractFoundationStack.acceptsCards(self, from_stack, cards):
return 0
# now check the cards
return isAlternateColorSequence(cards, self.cap.mod, self.cap.dir)
# /***********************************************************************
# // Abstract classes for row stacks.
# ************************************************************************/
@ -2192,6 +2242,16 @@ class BasicRowStack(OpenStack):
#def getBaseCard(self):
# return self._getBaseCard()
def spiderCanDropCards(self, stacks):
# drop whole sequence
if len(self.cards) < 13:
return (None, 0)
cards = self.cards[-13:]
for s in stacks:
if s is not self and s.acceptsCards(self, cards):
return (s, 13)
return (None, 0)
# Abstract class.
class SequenceRowStack(SequenceStack_StackMethods, BasicRowStack):

View file

@ -55,7 +55,8 @@ class WizardDialog(MfxDialog):
for w in WizardWidgets:
if isinstance(w, basestring):
frame = Frame(notebook)
notebook.add(frame, text=w)
notebook.add(frame, text=w, sticky='nsew', padding=5)
frame.columnconfigure(1, weight=1)
row = 0
continue
@ -64,12 +65,11 @@ class WizardDialog(MfxDialog):
if w.widget == 'entry':
w.variable = var = StringVar()
en = Entry(frame, textvariable=var)
en.grid(row=row, column=1, sticky='ew')
en.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
elif w.widget == 'menu':
w.variable = var = StringVar()
##OptionMenu(frame, var, *w.values).grid(row=row, column=1)
cb = Combobox(frame, values=tuple(w.values), textvariable=var,
state='readonly', width=20)
state='readonly', width=32)
cb.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
elif w.widget == 'spin':
w.variable = var = IntVar()
@ -78,7 +78,11 @@ class WizardDialog(MfxDialog):
s = PysolScale(frame, from_=from_, to=to, resolution=1,
orient='horizontal',
variable=var)
s.grid(row=row, column=1, sticky='ew')
s.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
elif w.widget == 'check':
w.variable = var = BooleanVar()
ch = Checkbutton(frame, variable=var, takefocus=False)
ch.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
if w.current_value is None:
var.set(w.default)

View file

@ -61,6 +61,7 @@ from selecttile import SelectTileDialogWithPreview
from findcarddialog import connect_game_find_card_dialog, destroy_find_card_dialog
from solverdialog import connect_game_solver_dialog
from tkwrap import MfxRadioMenuItem, MfxCheckMenuItem, StringVar
from wizarddialog import WizardDialog
#from toolbar import TOOLBAR_BUTTONS
from tkconst import TOOLBAR_BUTTONS
@ -401,6 +402,10 @@ class PysolMenubar(PysolMenubarActions):
menu.add_command(label=n_("Restart"), command=self.mRestart, accelerator=m+"G")
menu.add_separator()
menu.add_command(label=n_("Solitaire &Wizard"), command=self.mWizard)
menu.add_command(label=n_("Edit current game"), command=self.mWizardEdit)
menu = MfxMenu(self.__menubar, label=n_("&Game"))
menu.add_command(label=n_("&Deal cards"), command=self.mDeal, accelerator="D")
menu.add_command(label=n_("&Auto drop"), command=self.mDrop, accelerator="A")
@ -1340,3 +1345,46 @@ class PysolMenubar(PysolMenubarActions):
else:
if self._cancelDrag(break_pause=True): return
self.game.showStackDesc()
def wizardDialog(self, edit=False):
from pysollib.wizardutil import write_game, reset_wizard
if edit:
reset_wizard(self.game)
d = WizardDialog(self.top, _('Solitaire Wizard'), self.app)
if d.status == 0 and d.button == 0:
try:
if edit:
gameid = write_game(self.app, game=self.game)
else:
gameid = write_game(self.app)
except Exception, err:
if DEBUG:
traceback.print_exc()
d = MfxMessageDialog(self.top, title=_('Save game error'),
text=_('''
Error while saving game.
%s
''') % str(err),
bitmap='error')
return
if SELECT_GAME_MENU and not edit:
gi = self.app.getGameInfo(gameid)
label = gettext(gi.name)
menu = self.__menupath[".menubar.select.frenchgames.cusomgames"][2]
menu.add_radiobutton(command=self.mSelectGame,
variable=self.tkopt.gameid,
value=gameid, label=label, name=None)
self.tkopt.gameid.set(gameid)
self._mSelectGame(gameid, force=True)
def mWizard(self, *event):
if self._cancelDrag(break_pause=False): return
self.wizardDialog()
def mWizardEdit(self, *event):
if self._cancelDrag(break_pause=False): return
self.wizardDialog(edit=True)

124
pysollib/tk/tabpage.py Normal file
View file

@ -0,0 +1,124 @@
#
# This file is part of IDLE project - http://www.python.org/idle/
#
"""
a couple of classes for implementing partial tabbed-page like behaviour
"""
from Tkinter import *
MYRIDGE, MYRAISED = RAISED, RIDGE
#MYRIDGE, MYRAISED = RIDGE, RAISED
class InvalidTabPage(Exception): pass
class AlreadyExists(Exception): pass
class PageTab(Frame):
"""
a 'page tab' like framed button
"""
def __init__(self,parent):
Frame.__init__(self, parent, borderwidth=2, relief=MYRIDGE)
self.button=Radiobutton(self, padx=5, pady=5, takefocus=FALSE,
indicatoron=FALSE, highlightthickness=0,
borderwidth=0, selectcolor=self.cget('bg'))
self.button.pack()
class TabPageSet(Frame):
"""
a set of 'pages' with TabButtons for controlling their display
"""
def __init__(self,parent,pageNames=[],**kw):
"""
pageNames - a list of strings, each string will be the dictionary key
to a page's data, and the name displayed on the page's tab. Should be
specified in desired page order. The first page will be the default
and first active page.
"""
Frame.__init__(self, parent, kw)
self.grid_location(0,0)
self.columnconfigure(0,weight=1)
self.rowconfigure(1,weight=1)
self.tabBar=Frame(self)
self.tabBar.grid(row=0,column=0,sticky=EW)
self.activePage=StringVar(self)
self.defaultPage=''
self.pages={}
for name in pageNames:
self.AddPage(name)
def ChangePage(self,pageName=None):
if pageName:
if pageName in self.pages.keys():
self.activePage.set(pageName)
else:
raise InvalidTabPage, 'Invalid TabPage Name'
## pop up the active 'tab' only
for page in self.pages.keys():
self.pages[page]['tab'].config(relief=MYRIDGE)
self.pages[self.GetActivePage()]['tab'].config(relief=MYRAISED)
## switch page
self.pages[self.GetActivePage()]['page'].lift()
def GetActivePage(self):
return self.activePage.get()
def AddPage(self,pageName):
if pageName in self.pages.keys():
raise AlreadyExists, 'TabPage Name Already Exists'
self.pages[pageName]={
'tab': PageTab(self.tabBar),
'page': Frame(self,borderwidth=2,relief=RAISED)
}
self.pages[pageName]['tab'].button.config(
text=pageName,
command=self.ChangePage,
variable=self.activePage,
value=pageName
)
self.pages[pageName]['tab'].pack(side=LEFT)
self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
if len(self.pages)==1: # adding first page
self.defaultPage=pageName
self.activePage.set(self.defaultPage)
self.ChangePage()
def RemovePage(self,pageName):
if not pageName in self.pages.keys():
raise InvalidTabPage, 'Invalid TabPage Name'
self.pages[pageName]['tab'].pack_forget()
self.pages[pageName]['page'].grid_forget()
self.pages[pageName]['tab'].destroy()
self.pages[pageName]['page'].destroy()
del(self.pages[pageName])
# handle removing last remaining, or default, or active page
if not self.pages: # removed last remaining page
self.defaultPage=''
return
if pageName==self.defaultPage: # set a new default page
self.defaultPage=\
self.tabBar.winfo_children()[0].button.cget('text')
if pageName==self.GetActivePage(): # set a new active page
self.activePage.set(self.defaultPage)
self.ChangePage()
if __name__ == '__main__':
#test dialog
root=Tk()
tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
tabPage.pack(expand=TRUE,fill=BOTH)
Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
Label(tabPage.pages['Baz']['page'],text='Baz').pack()
entryPgName=Entry(root)
buttonAdd=Button(root,text='Add Page',
command=lambda:tabPage.AddPage(entryPgName.get()))
buttonRemove=Button(root,text='Remove Page',
command=lambda:tabPage.RemovePage(entryPgName.get()))
labelPgName=Label(root,text='name of page to add/remove:')
buttonAdd.pack(padx=5,pady=5)
buttonRemove.pack(padx=5,pady=5)
labelPgName.pack(padx=5)
entryPgName.pack(padx=5)
tabPage.ChangePage()
root.mainloop()

108
pysollib/tk/wizarddialog.py Normal file
View file

@ -0,0 +1,108 @@
##---------------------------------------------------------------------------##
##
## 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__ = ['WizardDialog']
# imports
from Tkinter import *
from tabpage import TabPageSet
# PySol imports
from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
from pysollib.wizardutil import WizardWidgets
# Toolkit imports
from tkwidget import MfxDialog
# /***********************************************************************
# //
# ************************************************************************/
class WizardDialog(MfxDialog):
def __init__(self, parent, title, app, **kw):
kw = self.initKw(kw)
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
top_frame, bottom_frame = self.createFrames(kw)
self.createBitmaps(top_frame, kw)
frame = Frame(top_frame)
frame.pack(expand=True, fill='both', padx=10, pady=10)
frame.columnconfigure(0, weight=1)
notebook = TabPageSet(frame)
notebook.pack(expand=True, fill='both')
for w in WizardWidgets:
if isinstance(w, basestring):
p = notebook.AddPage(w)
frame = Frame(notebook.pages[w]['page'])
frame.pack(expand=True, fill='both', padx=2, pady=4)
frame.columnconfigure(1, weight=1)
row = 0
continue
Label(frame, text=w.label).grid(row=row, column=0, padx=2)
if w.widget == 'entry':
w.variable = var = StringVar()
en = Entry(frame, textvariable=var)
en.grid(row=row, column=1, sticky='ew', padx=2)
elif w.widget == 'menu':
w.variable = var = StringVar()
om = OptionMenu(frame, var, *w.values)
om.grid(row=row, column=1, sticky='ew', padx=2)
elif w.widget == 'spin':
w.variable = var = IntVar()
from_, to = w.values
s = Scale(frame, from_=from_, to=to, resolution=1,
orient='horizontal',
variable=var)
s.grid(row=row, column=1, sticky='ew', padx=2)
elif w.widget == 'check':
w.variable = var = BooleanVar()
ch = Checkbutton(frame, variable=var,
takefocus=False, anchor='w')
ch.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
if w.current_value is None:
var.set(w.default)
else:
var.set(w.current_value)
row += 1
notebook.ChangePage()
focus = self.createButtons(bottom_frame, kw)
self.mainloop(focus, kw.timeout)
def initKw(self, kw):
kw = KwStruct(kw,
strings=(_('&OK'), _('&Cancel')),
default=0,
)
return MfxDialog.initKw(self, kw)

View file

@ -117,17 +117,22 @@ Redeals = WizSetting(
var_name = 'redeals',
)
FoundType = WizSetting(
values_map = ((n_('Same suit'), SS_FoundationStack),
(n_('Alternate color'), AC_FoundationStack),
(n_('Same color'), SC_FoundationStack),
(n_('Rank'), RK_FoundationStack),
values_map = ((n_('Same suit'), SS_FoundationStack),
(n_('Alternate color'), AC_FoundationStack),
(n_('Same color'), SC_FoundationStack),
(n_('Rank'), RK_FoundationStack),
(n_('Spider same suit'), Spider_SS_Foundation),
(n_('Spider alternate color'), Spider_AC_Foundation),
),
default = n_('Same suit'),
label = _('Type:'),
var_name = 'found_type',
)
FoundBaseCard = WizSetting(
values_map = ((n_('Ace'), ACE), (n_('King'), KING)),
values_map = ((n_('Ace'), ACE),
(n_('King'), KING),
(n_('Any'), ANY_RANK),
),
default = n_('Ace'),
label = _('Base card:'),
var_name = 'found_base_card',
@ -139,10 +144,11 @@ FoundDir = WizSetting(
var_name = 'found_dir',
)
FoundWrap = WizSetting(
values_map = ((n_('Yes'), True), (n_('No'), False)),
default = n_('No'),
values_map = (True, False),
default = False,
label = _('Wrapping:'),
var_name = 'found_wrap',
widget = 'check',
)
FoundMaxMove = WizSetting(
values_map = ((n_('No move'), 0,), (n_('One card'), 1)),
@ -158,11 +164,17 @@ RowsNum = WizSetting(
var_name = 'rows_num',
)
RowsType = WizSetting(
values_map = ((n_('Same suit'), SS_RowStack),
(n_('Alternate color'), AC_RowStack),
(n_('Same color'), SC_RowStack),
(n_('Rank'), RK_RowStack),
(n_('Any suit but the same'), BO_RowStack),
values_map = ((n_('Same suit'), SS_RowStack),
(n_('Alternate color'), AC_RowStack),
(n_('Same color'), SC_RowStack),
(n_('Rank'), RK_RowStack),
(n_('Any suit but the same'), BO_RowStack),
(n_('Up or down by same suit'), UD_SS_RowStack),
(n_('Up or down by alternate color'), UD_AC_RowStack),
(n_('Up or down by rank'), UD_RK_RowStack),
(n_('Up or down by same color'), UD_SC_RowStack),
(n_('Spider same suit'), Spider_SS_RowStack),
(n_('Spider alternate color'), Spider_AC_RowStack),
),
default = n_('Alternate color'),
label = _('Type:'),
@ -185,10 +197,11 @@ RowsDir = WizSetting(
var_name = 'rows_dir',
)
RowsWrap = WizSetting(
values_map = ((n_('Yes'), True), (n_('No'), False)),
default = n_('No'),
values_map = (True, False),
default = False,
label = _('Wrapping:'),
var_name = 'rows_wrap',
widget = 'check',
)
RowsMaxMove = WizSetting(
values_map = ((n_('One card'), 1), (n_('Unlimited'), UNLIMITED_MOVES)),
@ -203,13 +216,12 @@ ReservesNum = WizSetting(
label = _('Number of reserves:'),
var_name = 'reserves_num',
)
ReservesType = WizSetting(
values_map = ((n_('FreeCell'), ReserveStack),
(n_('Reserve'), OpenStack),
),
default = n_('FreeCell'),
label = n_('Type of reserves:'),
var_name = 'reserves_type',
ReservesMaxAccept = WizSetting(
values_map = (0, 20),
default = 1,
widget = 'spin',
label = _('Max accept:'),
var_name = 'reserves_max_accept',
)
DealType = WizSetting(
values_map = ((n_('Triangle'), 'triangle'),
@ -264,7 +276,7 @@ WizardWidgets = (
RowsMaxMove,
_('Reserves'),
ReservesNum,
ReservesType,
ReservesMaxAccept,
_('Initial dealing'),
DealType,
DealFaceUp,
@ -320,6 +332,8 @@ class MyCustomGame(CustomGame):
if isinstance(v, int):
fd.write(" '%s': %i,\n" % (w.var_name, v))
else:
if w.var_name == 'name' and not v:
v = 'Invalid Game Name'
fd.write(" '%s': '%s',\n" % (w.var_name, v))
fd.write(" 'gameid': %i,\n" % gameid)
fd.write(" 'file': '%s',\n" % os.path.split(fn)[1])