mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
* improved solitaire wizard
git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@162 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
4117e41bb0
commit
e7714af87e
8 changed files with 361 additions and 81 deletions
|
@ -30,26 +30,32 @@ from hint import AbstractHint, DefaultHint, CautiousDefaultHint, Yukon_Hint
|
|||
from wizardutil import WizardWidgets
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
def get_settings(ss):
|
||||
s = {}
|
||||
for w in WizardWidgets:
|
||||
if isinstance(w, basestring):
|
||||
continue
|
||||
if w.var_name in ss:
|
||||
v = ss[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget == 'menu':
|
||||
v = dict(w.values_map)[v]
|
||||
s[w.var_name] = v
|
||||
return s
|
||||
|
||||
|
||||
class CustomGame(Game):
|
||||
|
||||
def createGame(self):
|
||||
|
||||
ss = self.SETTINGS
|
||||
s = {}
|
||||
for w in WizardWidgets:
|
||||
if isinstance(w, basestring):
|
||||
continue
|
||||
if w.var_name in ss:
|
||||
v = ss[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget == 'menu':
|
||||
v = dict(w.values_map)[v]
|
||||
s[w.var_name] = v
|
||||
s = get_settings(self.SETTINGS)
|
||||
##from pprint import pprint; pprint(s)
|
||||
|
||||
# foundations
|
||||
|
@ -119,17 +125,25 @@ class CustomGame(Game):
|
|||
}
|
||||
if s['talon'] is InitialDealTalonStack:
|
||||
layout_kw['texts'] = False
|
||||
layout_kw['playcards'] = max(16, 12+s['deal_face_down']+s['deal_face_up'])
|
||||
layout_kw['playcards'] = max(
|
||||
16, 12+s['deal_face_down']+s['deal_face_up'])
|
||||
if s['talon'] in (DealRowRedealTalonStack,
|
||||
SpiderTalonStack,
|
||||
GroundForADivorceTalonStack):
|
||||
layout_kw['playcards'] += 2 * s['decks']
|
||||
|
||||
# reserves
|
||||
if s['reserves_num']:
|
||||
kw = {
|
||||
'max_accept': s['reserves_max_accept'],
|
||||
'max_cards': s['reserves_max_accept'],
|
||||
}
|
||||
if s['reserves_max_accept']:
|
||||
layout_kw['reserve_class'] = StackWrapper(ReserveStack, **kw)
|
||||
else:
|
||||
layout_kw['reserve_class'] = StackWrapper(OpenStack, **kw)
|
||||
if s['talon'] is DealReserveRedealTalonStack or \
|
||||
s['reserves_max_accept'] > 1:
|
||||
layout_kw['reserve_texts'] = True
|
||||
|
||||
# waste
|
||||
if s['talon'] is WasteTalonStack:
|
||||
|
@ -153,19 +167,22 @@ class CustomGame(Game):
|
|||
((Spider_AC_RowStack, Spider_SS_RowStack),
|
||||
(self._shallHighlightMatch_RK,
|
||||
self._shallHighlightMatch_RKW)),
|
||||
((AC_RowStack, UD_AC_RowStack, Yukon_AC_RowStack),
|
||||
((AC_RowStack, UD_AC_RowStack,
|
||||
Yukon_AC_RowStack, SuperMoveAC_RowStack),
|
||||
(self._shallHighlightMatch_AC,
|
||||
self._shallHighlightMatch_ACW)),
|
||||
((SS_RowStack, UD_SS_RowStack, Yukon_SS_RowStack),
|
||||
((SS_RowStack, UD_SS_RowStack,
|
||||
Yukon_SS_RowStack, SuperMoveSS_RowStack),
|
||||
(self._shallHighlightMatch_SS,
|
||||
self._shallHighlightMatch_SSW)),
|
||||
((RK_RowStack, UD_RK_RowStack, Yukon_RK_RowStack),
|
||||
((RK_RowStack, UD_RK_RowStack,
|
||||
Yukon_RK_RowStack, SuperMoveRK_RowStack),
|
||||
(self._shallHighlightMatch_RK,
|
||||
self._shallHighlightMatch_RKW)),
|
||||
((SC_RowStack, UD_SC_RowStack),
|
||||
((SC_RowStack, UD_SC_RowStack, SuperMoveSC_RowStack),
|
||||
(self._shallHighlightMatch_SC,
|
||||
self._shallHighlightMatch_SCW)),
|
||||
((BO_RowStack,),
|
||||
((BO_RowStack, SuperMoveBO_RowStack),
|
||||
(self._shallHighlightMatch_BO,
|
||||
self._shallHighlightMatch_BOW)),
|
||||
):
|
||||
|
@ -214,7 +231,7 @@ class CustomGame(Game):
|
|||
frames=frames)
|
||||
|
||||
frames = 0
|
||||
s = self.SETTINGS
|
||||
s = get_settings(self.SETTINGS)
|
||||
max_cards = s['deal_max_cards'] - len(self.s.rows)
|
||||
if self.s.waste:
|
||||
max_cards -= 1
|
||||
|
@ -232,7 +249,7 @@ class CustomGame(Game):
|
|||
# deal to rows
|
||||
face_down = s['deal_face_down']
|
||||
max_rows = s['deal_face_down'] + s['deal_face_up']
|
||||
if s['deal_type'] == 'Triangle':
|
||||
if s['deal_type'] == 'triangle':
|
||||
# triangle
|
||||
for i in range(1, len(self.s.rows)):
|
||||
flip = (face_down <= 0)
|
||||
|
@ -269,25 +286,12 @@ class CustomGame(Game):
|
|||
self.s.talon.dealCards()
|
||||
|
||||
|
||||
|
||||
def registerCustomGame(gameclass):
|
||||
|
||||
s = gameclass.SETTINGS
|
||||
for w in WizardWidgets:
|
||||
if isinstance(w, basestring):
|
||||
continue
|
||||
if w.var_name == 'decks':
|
||||
v = s['decks']
|
||||
decks = dict(w.values_map)[v]
|
||||
elif w.var_name == 'redeals':
|
||||
v = s['redeals']
|
||||
redeals = dict(w.values_map)[v]
|
||||
elif w.var_name == 'skill_level':
|
||||
v = s['skill_level']
|
||||
skill_level = dict(w.values_map)[v]
|
||||
gameid = s['gameid']
|
||||
s = get_settings(gameclass.SETTINGS)
|
||||
gameid = gameclass.SETTINGS['gameid']
|
||||
|
||||
registerGame(GameInfo(gameid, gameclass, s['name'],
|
||||
GI.GT_CUSTOM | GI.GT_ORIGINAL,
|
||||
decks, redeals, skill_level))
|
||||
s['decks'], s['redeals'], s['skill_level']))
|
||||
|
||||
|
|
|
@ -2064,15 +2064,22 @@ for %d moves.
|
|||
#
|
||||
|
||||
def getQuickPlayScore(self, ncards, from_stack, to_stack):
|
||||
if to_stack in self.s.reserves:
|
||||
# if to_stack in reserves prefer empty stack
|
||||
return 1000-len(to_stack.cards)
|
||||
# prefer non-empty piles in to_stack
|
||||
return (len(to_stack.cards) != 0)
|
||||
return 1001 + int(len(to_stack.cards) != 0)
|
||||
|
||||
def _getSpiderQuickPlayScore(self, ncards, from_stack, to_stack):
|
||||
if to_stack in self.s.reserves:
|
||||
# if to_stack in reserves prefer empty stack
|
||||
return 1000-len(to_stack.cards)
|
||||
# for spider-type stacks
|
||||
if to_stack.cards:
|
||||
# check suit
|
||||
return int(from_stack.cards[-ncards].suit == to_stack.cards[-1].suit)+1
|
||||
return 0
|
||||
same_suit = from_stack.cards[-ncards].suit == to_stack.cards[-1].suit
|
||||
return int(same_suit)+1002
|
||||
return 1001
|
||||
|
||||
#
|
||||
# Score (I really don't like scores in Patience games...)
|
||||
|
|
|
@ -192,6 +192,14 @@ class Layout:
|
|||
s.reserves.append(reserve_class(r.x, r.y, game))
|
||||
# default
|
||||
self.defaultAll()
|
||||
# reserves texts
|
||||
if self.s.reserves and ('reserve_texts' in kw) and kw['reserve_texts']:
|
||||
game = self.game
|
||||
for i in range(len(game.s.reserves)):
|
||||
s1 = game.s.reserves[i]
|
||||
s2 = self.s.reserves[i]
|
||||
s1.texts.ncards = self.defaultText(s2)
|
||||
|
||||
|
||||
#
|
||||
# public util for use by class Game
|
||||
|
@ -333,7 +341,8 @@ class Layout:
|
|||
# - left bottom: talon, waste
|
||||
#
|
||||
|
||||
def freeCellLayout(self, rows, reserves, waste=0, texts=0, playcards=18):
|
||||
def freeCellLayout(self, rows, reserves, waste=0,
|
||||
texts=0, reserve_texts=False, playcards=18):
|
||||
S = self.__createStack
|
||||
CW, CH = self.CW, self.CH
|
||||
XM, YM = self.XM, self.YM
|
||||
|
@ -351,12 +360,17 @@ class Layout:
|
|||
# set size so that at least 2/3 of a card is visible with 18 cards
|
||||
h = CH*2/3 + (playcards-1)*self.YOFFSET
|
||||
h = YM + YS + max(h, 3*YS)
|
||||
if reserves and reserve_texts:
|
||||
h += self.TEXT_HEIGHT
|
||||
|
||||
# create reserves & foundations
|
||||
x, y = (w - (toprows*XS - XM))/2, YM
|
||||
if reserves:
|
||||
for i in range(reserves):
|
||||
self.s.reserves.append(S(x, y))
|
||||
s = S(x, y)
|
||||
self.s.reserves.append(s)
|
||||
if reserve_texts:
|
||||
self._setText(s, anchor="s")
|
||||
x += XS
|
||||
x += XS
|
||||
for suit in range(suits):
|
||||
|
@ -366,6 +380,8 @@ class Layout:
|
|||
|
||||
# create rows
|
||||
x, y = (w - (rows*XS - XM))/2, YM + YS
|
||||
if reserves and reserve_texts:
|
||||
y += self.TEXT_HEIGHT
|
||||
for i in range(rows):
|
||||
self.s.rows.append(S(x, y))
|
||||
x += XS
|
||||
|
@ -399,7 +415,8 @@ class Layout:
|
|||
# - bottom: reserves
|
||||
#
|
||||
|
||||
def gypsyLayout(self, rows, waste=0, reserves=0, texts=1, playcards=25):
|
||||
def gypsyLayout(self, rows, waste=0, reserves=0,
|
||||
texts=1, reserve_texts=False, playcards=25):
|
||||
S = self.__createStack
|
||||
CW, CH = self.CW, self.CH
|
||||
XM, YM = self.XM, self.YM
|
||||
|
@ -415,6 +432,8 @@ class Layout:
|
|||
# set size so that at least 2/3 of a card is visible with 25 cards
|
||||
h = CH*2/3 + (playcards-1)*self.YOFFSET
|
||||
h = YM + max(h, (suits+1)*YS)
|
||||
if reserves and reserve_texts:
|
||||
h += self.TEXT_HEIGHT
|
||||
|
||||
# create rows
|
||||
x, y = XM, YM
|
||||
|
@ -451,7 +470,10 @@ class Layout:
|
|||
# create reserves
|
||||
x, y = XM, h-YS
|
||||
for i in range(reserves):
|
||||
self.s.reserves.append(S(x, y))
|
||||
s = S(x, y)
|
||||
self.s.reserves.append(s)
|
||||
if reserve_texts:
|
||||
self._setText(s, anchor="n")
|
||||
x += XS
|
||||
|
||||
# set window
|
||||
|
@ -464,7 +486,8 @@ class Layout:
|
|||
# - bottom: foundations, waste, talon
|
||||
#
|
||||
|
||||
def harpLayout(self, rows, waste, reserves=0, texts=1, playcards=19):
|
||||
def harpLayout(self, rows, waste, reserves=0,
|
||||
texts=1, reserve_texts=False, playcards=19):
|
||||
S = self.__createStack
|
||||
CW, CH = self.CW, self.CH
|
||||
XM, YM = self.XM, self.YM
|
||||
|
@ -483,14 +506,21 @@ class Layout:
|
|||
if texts: h += self.TEXT_HEIGHT
|
||||
if reserves:
|
||||
h += YS
|
||||
if reserves and reserve_texts:
|
||||
h += self.TEXT_HEIGHT
|
||||
|
||||
# top
|
||||
y = YM
|
||||
if reserves:
|
||||
if reserve_texts:
|
||||
y += self.TEXT_HEIGHT
|
||||
x = (w - (reserves*XS - XM))/2
|
||||
for i in range(reserves):
|
||||
self.s.reserves.append(S(x, y))
|
||||
s = S(x, y)
|
||||
self.s.reserves.append(s)
|
||||
x += XS
|
||||
if reserve_texts:
|
||||
self._setText(s, anchor="n")
|
||||
y += YS
|
||||
x = (w - (rows*XS - XM))/2
|
||||
for i in range(rows):
|
||||
|
@ -505,6 +535,8 @@ class Layout:
|
|||
x += XS
|
||||
if reserves:
|
||||
yy = YM + YS - CH/2
|
||||
if reserve_texts:
|
||||
yy += self.TEXT_HEIGHT
|
||||
else:
|
||||
yy = -999
|
||||
self.setRegion(self.s.rows, (-999, yy, 999999, y - YS / 2))
|
||||
|
@ -532,7 +564,8 @@ class Layout:
|
|||
#
|
||||
|
||||
def klondikeLayout(self, rows, waste, reserves=0,
|
||||
texts=1, playcards=16, center=1, text_height=0):
|
||||
texts=1, reserve_texts=False,
|
||||
playcards=16, center=1, text_height=0):
|
||||
S = self.__createStack
|
||||
CW, CH = self.CW, self.CH
|
||||
XM, YM = self.XM, self.YM
|
||||
|
@ -549,6 +582,8 @@ class Layout:
|
|||
h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET
|
||||
h = max(h, 2 * YS)
|
||||
h += YM + YS * foundrows
|
||||
if reserves and reserve_texts:
|
||||
h += self.TEXT_HEIGHT
|
||||
|
||||
# top
|
||||
##text_height = 0
|
||||
|
@ -601,8 +636,11 @@ class Layout:
|
|||
y = h
|
||||
h += YS
|
||||
for i in range(reserves):
|
||||
self.s.reserves.append(S(x, y))
|
||||
s = S(x, y)
|
||||
self.s.reserves.append(s)
|
||||
x += XS
|
||||
if reserve_texts:
|
||||
self._setText(s, anchor="n")
|
||||
|
||||
# set window
|
||||
self.size = (XM + maxrows * XS, h)
|
||||
|
|
|
@ -52,6 +52,8 @@ __all__ = ['cardsFaceUp',
|
|||
'RedealTalonStack',
|
||||
'DealRowRedealTalonStack',
|
||||
'DealReserveRedealTalonStack',
|
||||
'SpiderTalonStack',
|
||||
'GroundForADivorceTalonStack',
|
||||
'OpenStack',
|
||||
'AbstractFoundationStack',
|
||||
'SS_FoundationStack',
|
||||
|
@ -1875,6 +1877,29 @@ class DealReserveRedealTalonStack(DealRowRedealTalonStack):
|
|||
return DealRowRedealTalonStack.dealCards(self, sound=sound,
|
||||
rows=self.game.s.reserves)
|
||||
|
||||
# Spider Talons
|
||||
class SpiderTalonStack(DealRowRedealTalonStack):
|
||||
def canDealCards(self):
|
||||
if not DealRowRedealTalonStack.canDealCards(self):
|
||||
return False
|
||||
# no row may be empty
|
||||
for r in self.game.s.rows:
|
||||
if not r.cards:
|
||||
return False
|
||||
return True
|
||||
|
||||
class GroundForADivorceTalonStack(DealRowRedealTalonStack):
|
||||
# A single click deals a new cards to each non-empty row.
|
||||
def dealCards(self, sound=1):
|
||||
if self.cards:
|
||||
rows = filter(lambda r: r.cards, self.game.s.rows)
|
||||
## if not rows:
|
||||
## # deal one card to first row if all rows are emtpy
|
||||
## rows = self.game.s.rows[:1]
|
||||
return DealRowRedealTalonStack.dealRowAvail(self, rows=rows,
|
||||
sound=sound)
|
||||
return 0
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // An OpenStack is a stack where cards can be placed and dragged
|
||||
|
|
|
@ -28,12 +28,15 @@ from Tile import *
|
|||
# PySol imports
|
||||
from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
|
||||
from pysollib.wizardutil import WizardWidgets
|
||||
from pysollib.wizardpresets import presets
|
||||
|
||||
# Toolkit imports
|
||||
from tkwidget import MfxDialog
|
||||
from tkwidget import PysolScale
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
@ -62,7 +65,21 @@ class WizardDialog(MfxDialog):
|
|||
|
||||
Label(frame, text=w.label).grid(row=row, column=0)
|
||||
|
||||
if w.widget == 'entry':
|
||||
if w.widget == 'preset':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
default = gettext(w.default)
|
||||
values.remove(default)
|
||||
values.sort()
|
||||
values.insert(0, default)
|
||||
cb = Combobox(frame, values=tuple(values),
|
||||
textvariable=w.variable,
|
||||
state='readonly', width=32)
|
||||
cb.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
|
||||
callback = lambda e, w=w: self.presetSelected(e, w)
|
||||
cb.bind('<<ComboboxSelected>>', callback)
|
||||
elif w.widget == 'entry':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
en = Entry(frame, textvariable=w.variable)
|
||||
|
@ -70,7 +87,8 @@ class WizardDialog(MfxDialog):
|
|||
elif w.widget == 'menu':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
cb = Combobox(frame, values=tuple(w.values),
|
||||
values = [gettext(v) for v in w.values]
|
||||
cb = Combobox(frame, values=tuple(values),
|
||||
textvariable=w.variable,
|
||||
state='readonly', width=32)
|
||||
cb.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
|
||||
|
@ -94,17 +112,32 @@ class WizardDialog(MfxDialog):
|
|||
ch.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
|
||||
|
||||
if w.current_value is None:
|
||||
w.variable.set(w.default)
|
||||
w.variable.set(gettext(w.default))
|
||||
else:
|
||||
w.variable.set(w.current_value)
|
||||
w.variable.set(gettext(w.current_value))
|
||||
|
||||
row += 1
|
||||
|
||||
|
||||
focus = self.createButtons(bottom_frame, kw)
|
||||
self.mainloop(focus, kw.timeout)
|
||||
|
||||
|
||||
def presetSelected(self, e, w):
|
||||
n = e.widget.get()
|
||||
n = w.translation_map[n]
|
||||
p = presets[n]
|
||||
for w in WizardWidgets:
|
||||
if isinstance(w, basestring):
|
||||
continue
|
||||
if w.var_name in p:
|
||||
v = p[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
w.variable.set(v)
|
||||
|
||||
|
||||
def initKw(self, kw):
|
||||
kw = KwStruct(kw,
|
||||
strings=(_('&OK'), _('&Cancel')),
|
||||
|
|
|
@ -29,11 +29,14 @@ from tabpage import TabPageSet
|
|||
# PySol imports
|
||||
from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
|
||||
from pysollib.wizardutil import WizardWidgets
|
||||
from pysollib.wizardpresets import presets
|
||||
|
||||
# Toolkit imports
|
||||
from tkwidget import MfxDialog
|
||||
|
||||
|
||||
gettext = _
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
@ -63,7 +66,19 @@ class WizardDialog(MfxDialog):
|
|||
|
||||
Label(frame, text=w.label).grid(row=row, column=0, padx=2)
|
||||
|
||||
if w.widget == 'entry':
|
||||
if w.widget == 'preset':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
values = [gettext(v) for v in w.values]
|
||||
default = gettext(w.default)
|
||||
values.remove(default)
|
||||
values.sort()
|
||||
values.insert(0, default)
|
||||
callback = lambda v, w=w: self.presetSelected(v, w)
|
||||
om = OptionMenu(frame, w.variable,
|
||||
command=callback, *values)
|
||||
om.grid(row=row, column=1, sticky='ew', padx=2)
|
||||
elif w.widget == 'entry':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
en = Entry(frame, textvariable=w.variable)
|
||||
|
@ -71,15 +86,15 @@ class WizardDialog(MfxDialog):
|
|||
elif w.widget == 'menu':
|
||||
if w.variable is None:
|
||||
w.variable = StringVar()
|
||||
om = OptionMenu(frame, w.variable, *w.values)
|
||||
values = [gettext(v) for v in w.values]
|
||||
om = OptionMenu(frame, w.variable, *values)
|
||||
om.grid(row=row, column=1, sticky='ew', padx=2)
|
||||
elif w.widget == 'spin':
|
||||
if w.variable is None:
|
||||
w.variable = IntVar()
|
||||
from_, to = w.values
|
||||
s = Scale(frame, from_=from_, to=to, resolution=1,
|
||||
orient='horizontal',
|
||||
variable=w.variable)
|
||||
orient='horizontal', length=200, variable=w.variable)
|
||||
s.grid(row=row, column=1, sticky='ew', padx=2)
|
||||
elif w.widget == 'check':
|
||||
if w.variable is None:
|
||||
|
@ -89,9 +104,9 @@ class WizardDialog(MfxDialog):
|
|||
ch.grid(row=row, column=1, sticky='ew', padx=2, pady=2)
|
||||
|
||||
if w.current_value is None:
|
||||
w.variable.set(w.default)
|
||||
w.variable.set(gettext(w.default))
|
||||
else:
|
||||
w.variable.set(w.current_value)
|
||||
w.variable.set(gettext(w.current_value))
|
||||
|
||||
row += 1
|
||||
|
||||
|
@ -101,6 +116,21 @@ class WizardDialog(MfxDialog):
|
|||
self.mainloop(focus, kw.timeout)
|
||||
|
||||
|
||||
def presetSelected(self, v, w):
|
||||
n = w.translation_map[v]
|
||||
p = presets[n]
|
||||
for w in WizardWidgets:
|
||||
if isinstance(w, basestring):
|
||||
continue
|
||||
if w.var_name in p:
|
||||
v = p[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget in ('menu', 'preset'):
|
||||
v = gettext(v)
|
||||
w.variable.set(v)
|
||||
|
||||
|
||||
def initKw(self, kw):
|
||||
kw = KwStruct(kw,
|
||||
strings=(_('&OK'), _('&Cancel')),
|
||||
|
|
128
pysollib/wizardpresets.py
Normal file
128
pysollib/wizardpresets.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
##---------------------------------------------------------------------------##
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
##---------------------------------------------------------------------------##
|
||||
|
||||
n_ = lambda x: x
|
||||
|
||||
presets = {
|
||||
'None': {
|
||||
'preset': 'None',
|
||||
'name': n_('My Game'),
|
||||
},
|
||||
|
||||
'Klondike': {
|
||||
'preset': 'Klondike',
|
||||
'name': n_('My Klondike'),
|
||||
'layout': 'Klondike',
|
||||
'talon': 'Deal to waste',
|
||||
'redeals': 'Unlimited redeals',
|
||||
'rows_num': 7,
|
||||
'rows_base_card': 'King',
|
||||
'reserves_num': 0,
|
||||
'deal_type': 'Triangle',
|
||||
'deal_face_down': 6,
|
||||
'deal_face_up': 1,
|
||||
},
|
||||
|
||||
'FreeCell': {
|
||||
'preset': 'FreeCell',
|
||||
'name': n_('My FreeCell'),
|
||||
'skill_level': 'Mostly skill',
|
||||
'rows_max_move': 'Top card',
|
||||
'rows_super_move': 1,
|
||||
'deal_face_up': 6,
|
||||
},
|
||||
|
||||
'Spider': {
|
||||
'preset': 'Spider',
|
||||
'name': n_('My Spider'),
|
||||
'skill_level': 'Mostly skill',
|
||||
'decks': 'Two',
|
||||
'layout': 'Klondike',
|
||||
'talon': 'Spider',
|
||||
'found_type': 'Spider same suit',
|
||||
'found_max_move': 'None',
|
||||
'rows_num': 10,
|
||||
'rows_type': 'Spider same suit',
|
||||
'reserves_num': 0,
|
||||
'deal_face_down': 5,
|
||||
'deal_face_up': 1,
|
||||
'deal_max_cards': 54,
|
||||
},
|
||||
|
||||
'Gypsy': {
|
||||
'preset': 'Gypsy',
|
||||
'name': n_('My Gypsy'),
|
||||
'skill_level': 'Mostly skill',
|
||||
'decks': 'Two',
|
||||
'layout': 'Gypsy',
|
||||
'talon': 'Deal to tableau',
|
||||
'found_max_move': 'None',
|
||||
'reserves_num': 0,
|
||||
'deal_face_down': 2,
|
||||
'deal_face_up': 1,
|
||||
},
|
||||
|
||||
'Ground for a Divorce': {
|
||||
'preset': 'Ground for a Divorce',
|
||||
'name': n_('My Ground for a Divorce'),
|
||||
'skill_level': 'Mostly skill',
|
||||
'decks': 'Two',
|
||||
'layout': 'Harp',
|
||||
'talon': 'Ground for a Divorce',
|
||||
'found_type': 'Spider same suit',
|
||||
'found_base_card': 'Any',
|
||||
'found_equal': 0,
|
||||
'rows_num': 10,
|
||||
'rows_type': 'Spider same suit',
|
||||
'rows_wrap': 1,
|
||||
'reserves_num': 0,
|
||||
'deal_face_up': 5,
|
||||
},
|
||||
|
||||
'Double Klondike': {
|
||||
'preset': 'Double Klondike',
|
||||
'name': n_('My Double Klondike'),
|
||||
'decks': 'Two',
|
||||
'layout': 'Harp',
|
||||
'talon': 'Deal to waste',
|
||||
'redeals': 'Unlimited redeals',
|
||||
'rows_num': 9,
|
||||
'rows_base_card': 'King',
|
||||
'reserves_num': 0,
|
||||
'deal_type': 'Triangle',
|
||||
'deal_face_down': 8,
|
||||
'deal_face_up': 1,
|
||||
},
|
||||
|
||||
'Simple Simon': {
|
||||
'preset': 'Simple Simon',
|
||||
'name': n_('My Simple Simon'),
|
||||
'skill_level': 'Mostly skill',
|
||||
'found_type': 'Spider same suit',
|
||||
'found_max_move': 'None',
|
||||
'rows_num': 10,
|
||||
'rows_type': 'Spider same suit',
|
||||
'reserves_num': 0,
|
||||
'deal_type': 'Triangle',
|
||||
},
|
||||
|
||||
}
|
||||
|
|
@ -24,10 +24,8 @@ import sys, os
|
|||
from gamedb import GI, loadGame
|
||||
from util import *
|
||||
from stack import *
|
||||
#from game import Game
|
||||
from layout import Layout
|
||||
#from hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||
#from pysoltk import MfxCanvasText
|
||||
from wizardpresets import presets
|
||||
|
||||
gettext = _
|
||||
n_ = lambda x: x
|
||||
|
@ -40,15 +38,20 @@ class WizSetting:
|
|||
def __init__(self, values_map, default, var_name,
|
||||
label, widget='menu'):
|
||||
self.values_map = values_map
|
||||
self.default = gettext(default)
|
||||
self.default = default
|
||||
##self.values_dict = dict(self.values_map)
|
||||
self.translation_map = {}
|
||||
if widget == 'menu':
|
||||
self.values = []
|
||||
for k, v in self.values_map:
|
||||
t = gettext(k)
|
||||
self.values.append(t)
|
||||
self.translation_map[t] = k
|
||||
self.values.append(k)
|
||||
self.translation_map[gettext(k)] = k
|
||||
assert self.default in self.values
|
||||
elif widget == 'preset':
|
||||
self.values = []
|
||||
for v in self.values_map:
|
||||
self.values.append(v)
|
||||
self.translation_map[gettext(v)] = v
|
||||
assert self.default in self.values
|
||||
else:
|
||||
self.values = self.values_map
|
||||
|
@ -59,6 +62,13 @@ class WizSetting:
|
|||
self.current_value = None
|
||||
|
||||
|
||||
WizardPresets = WizSetting(
|
||||
values_map = presets.keys(),
|
||||
default = 'None',
|
||||
widget = 'preset',
|
||||
label = _('Initial setting:'),
|
||||
var_name = 'preset',
|
||||
)
|
||||
GameName = WizSetting(
|
||||
values_map = (),
|
||||
default = 'My Game',
|
||||
|
@ -97,10 +107,12 @@ LayoutType = WizSetting(
|
|||
var_name = 'layout',
|
||||
)
|
||||
TalonType = WizSetting(
|
||||
values_map = ((n_('Initial dealing'), InitialDealTalonStack),
|
||||
(n_('Deal to waste'), WasteTalonStack),
|
||||
(n_('Deal to tableau'), DealRowRedealTalonStack),
|
||||
(n_('Deal to reserves'), DealReserveRedealTalonStack),
|
||||
values_map = ((n_('Initial dealing'), InitialDealTalonStack),
|
||||
(n_('Deal to waste'), WasteTalonStack),
|
||||
(n_('Deal to tableau'), DealRowRedealTalonStack),
|
||||
(n_('Deal to reserves'), DealReserveRedealTalonStack),
|
||||
(n_('Spider'), SpiderTalonStack),
|
||||
(n_('Ground for a Divorce'), GroundForADivorceTalonStack),
|
||||
),
|
||||
default = n_('Initial dealing'),
|
||||
label = _('Type:'),
|
||||
|
@ -166,15 +178,15 @@ FoundWrap = WizSetting(
|
|||
widget = 'check',
|
||||
)
|
||||
FoundMaxMove = WizSetting(
|
||||
values_map = ((n_('None'), 0,), (n_('One card'), 1)),
|
||||
default = n_('One card'),
|
||||
label = _('Max move cards:'),
|
||||
values_map = ((n_('None'), 0,), (n_('Top card'), 1)),
|
||||
default = n_('Top card'),
|
||||
label = _('Move:'),
|
||||
var_name = 'found_max_move',
|
||||
)
|
||||
FoundEqual = WizSetting(
|
||||
values_map = (0, 1),
|
||||
default = 1,
|
||||
label = _('First card sets first rank:'),
|
||||
label = _('First card sets base rank:'),
|
||||
var_name = 'found_equal',
|
||||
widget = 'check',
|
||||
)
|
||||
|
@ -225,9 +237,9 @@ RowsDir = WizSetting(
|
|||
var_name = 'rows_dir',
|
||||
)
|
||||
RowsMaxMove = WizSetting(
|
||||
values_map = ((n_('One card'), 1), (n_('Unlimited'), UNLIMITED_MOVES)),
|
||||
default = n_('Unlimited'),
|
||||
label = _('Max # of moved cards:'),
|
||||
values_map = ((n_('Top card'), 1), (n_('Sequence'), UNLIMITED_MOVES)),
|
||||
default = n_('Sequence'),
|
||||
label = _('Move:'),
|
||||
var_name = 'rows_max_move',
|
||||
)
|
||||
RowsWrap = WizSetting(
|
||||
|
@ -284,7 +296,7 @@ DealToReseves = WizSetting(
|
|||
values_map = (0, 20),
|
||||
default = 0,
|
||||
widget = 'spin',
|
||||
label = _('# cards dealt to reserve:'),
|
||||
label = _('# of cards dealt to reserve:'),
|
||||
var_name = 'deal_to_reserves',
|
||||
)
|
||||
DealMaxCards = WizSetting(
|
||||
|
@ -297,6 +309,7 @@ DealMaxCards = WizSetting(
|
|||
|
||||
WizardWidgets = (
|
||||
_('General'),
|
||||
WizardPresets,
|
||||
GameName,
|
||||
SkillLevel,
|
||||
NumDecks,
|
||||
|
@ -374,12 +387,16 @@ class MyCustomGame(CustomGame):
|
|||
if isinstance(w, basestring):
|
||||
continue
|
||||
v = w.variable.get()
|
||||
if w.widget == 'menu':
|
||||
if w.widget in ('menu', 'presets'):
|
||||
v = w.translation_map[v]
|
||||
if v == w.default:
|
||||
# save only unique values
|
||||
continue
|
||||
if isinstance(v, int):
|
||||
fd.write(" '%s': %i,\n" % (w.var_name, v))
|
||||
else:
|
||||
if w.var_name == 'name':
|
||||
# escape
|
||||
v = v.replace('\\', '\\\\')
|
||||
v = v.replace("'", "\\'")
|
||||
if isinstance(v, unicode):
|
||||
|
@ -413,8 +430,6 @@ def reset_wizard(game):
|
|||
v = game.SETTINGS[w.var_name]
|
||||
else:
|
||||
v = w.default
|
||||
if w.widget == 'menu':
|
||||
v = gettext(v)
|
||||
w.current_value = v
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue