1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
PySolFC/pysollib/ui/tktile/solverdialog.py
Shlomi Fish 1dec576b1a Add persistence for solver show progress.
See https://github.com/shlomif/PySolFC/issues/38 :

<<<
Currently the solver dialog (Assist → Solver when playing Freecell or
other supported games) does not remember its "Preset" , "Max Iterations"
and "Show Progress" settings - either across sessions of PySol or even
after closing and invoking it again. It should remember those but note
that it should not remember the "Game" setting because one can switch to
a different game.
>>>
2017-08-25 22:28:25 +03:00

222 lines
7.2 KiB
Python

from six.moves import tkinter
from pysollib.mygettext import _
from pysollib.ui.tktile.tkconst import EVENT_HANDLED
from pysollib.settings import TITLE
class BaseSolverDialog:
def _ToggleShowProgressButton(self, *args):
self.app.opt.solver_show_progress = self.progress_var.get()
def __init__(self, parent, app, **kw):
self.parent = parent
self.app = app
title = TITLE+' - FreeCell Solver'
kw = self.initKw(kw)
self._calc_MfxDialog().__init__(
self, parent, title, kw.resizable, kw.default)
top_frame, bottom_frame = self.createFrames(kw)
self.createBitmaps(top_frame, kw)
self.games = {} # key: gamename; value: gameid
#
frame = self._calcToolkit().Frame(top_frame)
frame.pack(expand=True, fill='both', padx=4, pady=4)
frame.columnconfigure(1, weight=1)
#
row = 0
self._calcToolkit().Label(
frame, text=_('Game:'), anchor='w').grid(
row=row, column=0, sticky='ew', padx=2, pady=2)
games = app.getGamesForSolver()
gamenames = ['']
for id in games:
name = app.getGameTitleName(id)
gamenames.append(name)
self.games[name] = id
gamenames.sort()
self.gamenames = gamenames
self.games_var = self._createGamesVar(frame, row)
#
row += 1
self._calcToolkit().Label(
frame, text=_('Preset:'), anchor='w').grid(
row=row, column=0, sticky='ew', padx=2, pady=2)
presets = app.opt.solver_presets
self.presets = presets
self.preset_var = self._createPresetVar(frame, row)
#
row += 1
self.max_iters_var = tkinter.IntVar()
self.max_iters_var.set(10e4)
self._calcToolkit().Label(
frame, text=_('Max iterations:'), anchor='w').grid(
row=row, column=0, sticky='ew', padx=2, pady=2)
spin = tkinter.Spinbox(frame, bg='white', from_=1000, to=10e6,
increment=1000, textvariable=self.max_iters_var)
spin.grid(row=row, column=1, sticky='w', padx=2, pady=2)
#
row += 1
self.progress_var = tkinter.BooleanVar()
self.progress_var.set(self.app.opt.solver_show_progress)
w = self._createShowProgressButton(frame)
w.grid(row=row, column=0, columnspan=2, sticky='ew', padx=2, pady=2)
w.config(command=self._ToggleShowProgressButton)
#
label_frame = self._calcToolkit().LabelFrame(
top_frame, text=_('Progress'))
label_frame.pack(expand=True, fill='both', padx=6, pady=2)
# label_frame.columnconfigure(0, weight=1)
label_frame.columnconfigure(1, weight=1)
#
frow = 0
self._calcToolkit().Label(
label_frame, text=_('Iteration:'), anchor='w').grid(
row=frow, column=0, sticky='ew', padx=4, pady=2)
lb = self._calcToolkit().Label(label_frame, anchor='w')
lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2)
self.iter_label = lb
frow += 1
self._calcToolkit().Label(
label_frame, text=_('Depth:'), anchor='w').grid(
row=frow, column=0, sticky='ew', padx=4, pady=2)
lb = self._calcToolkit().Label(label_frame, anchor='w')
lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2)
self.depth_label = lb
frow += 1
self._calcToolkit().Label(
label_frame, text=_('Stored-States:'), anchor='w').grid(
row=frow, column=0, sticky='ew', padx=4, pady=2)
lb = self._calcToolkit().Label(label_frame, anchor='w')
lb.grid(row=frow, column=1, sticky='ew', padx=4, pady=2)
self.states_label = lb
#
lb = self._calcToolkit().Label(top_frame, anchor='w')
lb.pack(expand=True, fill='x', padx=6, pady=4)
self.result_label = lb
#
focus = self.createButtons(bottom_frame, kw)
self.start_button = self.buttons[0]
self.play_button = self.buttons[1]
self._reset()
self.connectGame(self.app.game)
self.mainloop(focus, kw.timeout, transient=False)
def mDone(self, button):
if button == 0:
self.startSolving()
elif button == 1:
self.startPlay()
elif button == 2:
self.app.menubar.mNewGame()
elif button == 3:
global solver_dialog
solver_dialog = None
self.destroy()
return EVENT_HANDLED
def mCancel(self, *event):
return self.mDone(3)
def wmDeleteWindow(self, *event):
return self.mDone(3)
def gameSelected(self, *event):
name = self.games_var.get()
if not name:
return
id = self.games[name]
self.app.menubar._mSelectGame(id)
def _reset(self):
self.play_button.config(state='disabled')
self.setText(iter='', depth='', states='')
self.result_label['text'] = ''
self.top.update_idletasks()
def reset(self):
self.play_button.config(state='disabled')
def startSolving(self):
from gettext import ungettext
self._reset()
game = self.app.game
solver = game.Solver_Class(game, self) # create solver instance
game.solver = solver
preset = self.preset_var.get()
max_iters = self.max_iters_var.get()
progress = self.app.opt.solver_show_progress
solver.config(preset=preset, max_iters=max_iters, progress=progress)
solver.computeHints()
hints_len = len(solver.hints)-1
if hints_len > 0:
t = ungettext('This game is solveable in %d move.',
'This game is solveable in %d moves.',
hints_len) % hints_len
self.result_label['text'] = t
self.play_button.config(state='normal')
else:
self.result_label['text'] = \
(_('I could not solve this game.')
if solver.solver_state == 'unsolved'
else _('Iterations count exceeded (Intractable)'))
self.play_button.config(state='disabled')
def startPlay(self):
self.play_button.config(state='disabled')
self.start_button.focus()
if self.app.game.pause:
self.app.menubar.mPause()
self.app.top.tkraise()
self.app.top.update_idletasks()
self.app.top.update()
self.app.top.after(200)
self.app.game.startDemo(level=3)
def setText(self, **kw):
if 'iter' in kw:
self.iter_label['text'] = kw['iter']
if 'depth' in kw:
self.depth_label['text'] = kw['depth']
if 'states' in kw:
self.states_label['text'] = kw['states']
self.top.update_idletasks()
solver_dialog = None
def connect_game_solver_dialog(game):
try:
solver_dialog.connectGame(game)
except:
pass
def destroy_solver_dialog():
global solver_dialog
try:
solver_dialog.destroy()
except:
# traceback.print_exc()
pass
solver_dialog = None
def reset_solver_dialog():
if solver_dialog:
try:
solver_dialog.reset()
except:
# traceback.print_exc()
pass