import tkinter from pysollib.mygettext import _ from pysollib.settings import TITLE from pysollib.ui.tktile.tkconst import EVENT_HANDLED class BaseSolverDialog: def _ToggleShowProgressButton(self, *args): self.app.opt.solver_show_progress = self.progress_var.get() def _getMaxIters(self): try: i = self.max_iters_var.get() except Exception: i = 100000 return i def _OnAssignToMaxIters(self, *args): self.app.opt.solver_max_iterations = self._getMaxIters() def _OnAssignToPreset(self, *args): self.app.opt.solver_preset = self.preset_var.get() def __init__(self, parent, app, **kw): self.parent = parent self.app = app title = _('%(app)s - FreeCell Solver') % {'app': TITLE} 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) self.preset_var.set(self.app.opt.solver_preset) # row += 1 self.max_iters_var = tkinter.IntVar() self.max_iters_var.set(self.app.opt.solver_max_iterations) 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) self.max_iters_var.trace('w', self._OnAssignToMaxIters) 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 pysollib.mygettext 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._getMaxIters() progress = self.app.opt.solver_show_progress iters_step = self.app.opt.solver_iterations_output_step solver.config(preset=preset, max_iters=max_iters, progress=progress, iters_step=iters_step) try: solver.computeHints() except RuntimeError: self.result_label['text'] = _('Solver not found in the PATH') return hints_len = len(solver.hints)-1 if hints_len > 0: if solver.solver_state == 'intractable': t = ungettext('This game can be hinted in %d move.', 'This game can be hinted in %d moves.', hints_len) else: t = ungettext('This game is solvable in %d move.', 'This game is solvable in %d moves.', hints_len) t = t % 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 Exception: pass def destroy_solver_dialog(): global solver_dialog try: solver_dialog.destroy() except Exception: # traceback.print_exc() pass solver_dialog = None def reset_solver_dialog(): if solver_dialog: try: solver_dialog.reset() except Exception: # traceback.print_exc() pass