From aa4f9ee5da101b7c396c476193db8a701d84e922 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Sat, 3 Jun 2017 03:01:33 +0300 Subject: [PATCH] Crude code to get some func running in py3. Right now klondike and freecell sort of work, but this is very hacky and there are many leftover debug traces. --- Canvas.py | 190 ++++++++++++++++++++++++++++ pysollib/app.py | 35 ++--- pysollib/configobj/configobj.py | 41 ++++-- pysollib/game.py | 2 +- pysollib/games/freecell.py | 3 +- pysollib/games/klondike.py | 4 +- pysollib/games/mahjongg/mahjongg.py | 8 +- pysollib/hint.py | 30 +++-- pysollib/layout.py | 172 ++++++++++++------------- pysollib/mfxutil.py | 4 +- pysollib/options.py | 5 +- pysollib/pysolrandom.py | 26 ++-- pysollib/settings.py | 2 +- pysollib/ui/tktile/tkhtml.py | 5 +- 14 files changed, 369 insertions(+), 158 deletions(-) create mode 100644 Canvas.py diff --git a/Canvas.py b/Canvas.py new file mode 100644 index 00000000..7edce44a --- /dev/null +++ b/Canvas.py @@ -0,0 +1,190 @@ +# This module exports classes for the various canvas item types + +# NOTE: This module was an experiment and is now obsolete. +# It's best to use the Tkinter.Canvas class directly. + +from six.moves.tkinter import Canvas, _cnfmerge, _flatten + + +class CanvasItem: + def __init__(self, canvas, itemType, *args, **kw): + self.canvas = canvas + self.id = canvas._create(itemType, args, kw) + if not hasattr(canvas, 'items'): + canvas.items = {} + canvas.items[self.id] = self + def __str__(self): + return str(self.id) + def __repr__(self): + return '<%s, id=%d>' % (self.__class__.__name__, self.id) + def delete(self): + del self.canvas.items[self.id] + self.canvas.delete(self.id) + def __getitem__(self, key): + v = self.canvas.tk.split(self.canvas.tk.call( + self.canvas._w, 'itemconfigure', + self.id, '-' + key)) + return v[4] + cget = __getitem__ + def __setitem__(self, key, value): + self.canvas.itemconfig(self.id, {key: value}) + def keys(self): + if not hasattr(self, '_keys'): + self._keys = map(lambda x, tk=self.canvas.tk: + tk.splitlist(x)[0][1:], + self.canvas.tk.splitlist( + self.canvas._do( + 'itemconfigure', + (self.id,)))) + return self._keys + def has_key(self, key): + return key in self.keys() + def __contains__(self, key): + return key in self.keys() + def addtag(self, tag, option='withtag'): + self.canvas.addtag(tag, option, self.id) + def bbox(self): + x1, y1, x2, y2 = self.canvas.bbox(self.id) + return (x1, y1), (x2, y2) + def bind(self, sequence=None, command=None, add=None): + return self.canvas.tag_bind(self.id, sequence, command, add) + def unbind(self, sequence, funcid=None): + self.canvas.tag_unbind(self.id, sequence, funcid) + def config(self, cnf={}, **kw): + return self.canvas.itemconfig(self.id, _cnfmerge((cnf, kw))) + def coords(self, pts = ()): + flat = () + for x, y in pts: flat = flat + (x, y) + return self.canvas.coords(self.id, *flat) + def dchars(self, first, last=None): + self.canvas.dchars(self.id, first, last) + def dtag(self, ttd): + self.canvas.dtag(self.id, ttd) + def focus(self): + self.canvas.focus(self.id) + def gettags(self): + return self.canvas.gettags(self.id) + def icursor(self, index): + self.canvas.icursor(self.id, index) + def index(self, index): + return self.canvas.index(self.id, index) + def insert(self, beforethis, string): + self.canvas.insert(self.id, beforethis, string) + def lower(self, belowthis=None): + self.canvas.tag_lower(self.id, belowthis) + def move(self, xamount, yamount): + self.canvas.move(self.id, xamount, yamount) + def tkraise(self, abovethis=None): + self.canvas.tag_raise(self.id, abovethis) + raise_ = tkraise # BW compat + def scale(self, xorigin, yorigin, xscale, yscale): + self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale) + def type(self): + return self.canvas.type(self.id) + +class Arc(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'arc', *args, **kw) + +class Bitmap(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'bitmap', *args, **kw) + +class ImageItem(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'image', *args, **kw) + +class Line(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'line', *args, **kw) + +class Oval(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'oval', *args, **kw) + +class Polygon(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'polygon', *args, **kw) + +class Rectangle(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'rectangle', *args, **kw) + +# XXX "Text" is taken by the Text widget... +class CanvasText(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'text', *args, **kw) + +class Window(CanvasItem): + def __init__(self, canvas, *args, **kw): + CanvasItem.__init__(self, canvas, 'window', *args, **kw) + +class Group: + def __init__(self, canvas, tag=None): + if not tag: + tag = 'Group%d' % id(self) + self.tag = self.id = tag + self.canvas = canvas + self.canvas.dtag(self.tag) + def str(self): + return self.tag + __str__ = str + def _do(self, cmd, *args): + return self.canvas._do(cmd, (self.tag,) + _flatten(args)) + def addtag_above(self, tagOrId): + self._do('addtag', 'above', tagOrId) + def addtag_all(self): + self._do('addtag', 'all') + def addtag_below(self, tagOrId): + self._do('addtag', 'below', tagOrId) + def addtag_closest(self, x, y, halo=None, start=None): + self._do('addtag', 'closest', x, y, halo, start) + def addtag_enclosed(self, x1, y1, x2, y2): + self._do('addtag', 'enclosed', x1, y1, x2, y2) + def addtag_overlapping(self, x1, y1, x2, y2): + self._do('addtag', 'overlapping', x1, y1, x2, y2) + def addtag_withtag(self, tagOrId): + self._do('addtag', 'withtag', tagOrId) + def bbox(self): + return self.canvas._getints(self._do('bbox')) + def bind(self, sequence=None, command=None, add=None): + return self.canvas.tag_bind(self.id, sequence, command, add) + def unbind(self, sequence, funcid=None): + self.canvas.tag_unbind(self.id, sequence, funcid) + def coords(self, *pts): + return self._do('coords', pts) + def dchars(self, first, last=None): + self._do('dchars', first, last) + def delete(self): + self._do('delete') + def dtag(self, tagToDelete=None): + self._do('dtag', tagToDelete) + def focus(self): + self._do('focus') + def gettags(self): + return self.canvas.tk.splitlist(self._do('gettags', self.tag)) + def icursor(self, index): + return self._do('icursor', index) + def index(self, index): + return self.canvas.tk.getint(self._do('index', index)) + def insert(self, beforeThis, string): + self._do('insert', beforeThis, string) + def config(self, cnf={}, **kw): + return self.canvas.itemconfigure(self.tag, _cnfmerge((cnf,kw))) + def lower(self, belowThis=None): + self._do('lower', belowThis) + def move(self, xAmount, yAmount): + self._do('move', xAmount, yAmount) + def tkraise(self, aboveThis=None): + self._do('raise', aboveThis) + lift = tkraise + def scale(self, xOrigin, yOrigin, xScale, yScale): + self._do('scale', xOrigin, yOrigin, xScale, yScale) + def select_adjust(self, index): + self.canvas._do('select', ('adjust', self.tag, index)) + def select_from(self, index): + self.canvas._do('select', ('from', self.tag, index)) + def select_to(self, index): + self.canvas._do('select', ('to', self.tag, index)) + def type(self): + return self._do('type') diff --git a/pysollib/app.py b/pysollib/app.py index 184afa11..ccd0ae32 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -521,13 +521,14 @@ class Application: # this is the mainloop while 1: assert self.cardset is not None - id, random = self.nextgame.id, self.nextgame.random + id_, random = self.nextgame.id, self.nextgame.random self.nextgame.id, self.nextgame.random = 0, None try: - self.runGame(id, random) + print("fopako id_", id_) + self.runGame(id_, random) except Exception: # try Klondike if current game fails - if id == 2: + if id_ == 2: raise # internal error? if DEBUG: raise @@ -569,7 +570,7 @@ class Application: destroy_find_card_dialog() destroy_solver_dialog() # update options - self.opt.last_gameid = id + self.opt.last_gameid = id_ # save options try: self.saveOptions() @@ -595,22 +596,22 @@ class Application: traceback.print_exc() pass - def runGame(self, id, random=None): + def runGame(self, id_, random=None): self.top.connectApp(self) # create game instance - g = self.getGameClass(id) + g = self.getGameClass(id_) if g is None: - id = 2 # start Klondike as default game + id_ = 2 # start Klondike as default game random = None - g = self.getGameClass(id) + g = self.getGameClass(id_) if g is None: # start first available game - id = self.gdb.getGamesIdSortedByName()[0] - g = self.getGameClass(id) - gi = self.getGameInfo(id) - assert gi is not None and gi.id == id - self.game = self.constructGame(id) - self.gdb.setSelected(id) + id_ = self.gdb.getGamesIdSortedByName()[0] + g = self.getGameClass(id_) + gi = self.getGameInfo(id_) + assert gi is not None and gi.id == id_ + self.game = self.constructGame(id_) + self.gdb.setSelected(id_) self.game.busy = 1 # create stacks and layout self.game.create(self) @@ -620,9 +621,9 @@ class Application: self.toolbar.connectGame(self.game) self.game.updateStatus(player=self.opt.player) # update "Recent games" menubar entry - if id in self.opt.recent_gameid: - self.opt.recent_gameid.remove(id) - self.opt.recent_gameid.insert(0, id) + if id_ in self.opt.recent_gameid: + self.opt.recent_gameid.remove(id_) + self.opt.recent_gameid.insert(0, id_) del self.opt.recent_gameid[self.opt.num_recent_games:] self.menubar.updateRecentGamesMenu(self.opt.recent_gameid) self.menubar.updateFavoriteGamesMenu() diff --git a/pysollib/configobj/configobj.py b/pysollib/configobj/configobj.py index d04857cd..dbef477d 100644 --- a/pysollib/configobj/configobj.py +++ b/pysollib/configobj/configobj.py @@ -21,7 +21,7 @@ import sys import os import re -from types import StringTypes +from six import string_types from warnings import warn INTP_VER = sys.version_info[:2] if INTP_VER < (2, 2): @@ -544,7 +544,7 @@ class Section(dict): def __getitem__(self, key): """Fetch the item and do string interpolation.""" val = dict.__getitem__(self, key) - if self.main.interpolation and isinstance(val, StringTypes): + if self.main.interpolation and isinstance(val, string_types): return self._interpolate(key, val) return val @@ -562,7 +562,7 @@ class Section(dict): `unrepr`` must be set when setting a value to a dictionary, without creating a new sub-section. """ - if not isinstance(key, StringTypes): + if not isinstance(key, string_types): raise ValueError('The key "%s" is not a string.' % key) # add the comment if key not in self.comments: @@ -595,11 +595,11 @@ class Section(dict): if key not in self: self.scalars.append(key) if not self.main.stringify: - if isinstance(value, StringTypes): + if isinstance(value, string_types): pass elif isinstance(value, (list, tuple)): for entry in value: - if not isinstance(entry, StringTypes): + if not isinstance(entry, string_types): raise TypeError( 'Value is not a string "%s".' % entry) else: @@ -641,7 +641,7 @@ class Section(dict): del self.comments[key] del self.inline_comments[key] self.sections.remove(key) - if self.main.interpolation and isinstance(val, StringTypes): + if self.main.interpolation and isinstance(val, string_types): return self._interpolate(key, val) return val @@ -990,7 +990,7 @@ class Section(dict): return False else: try: - if not isinstance(val, StringTypes): + if not isinstance(val, string_types): raise KeyError else: return self.main._bools[val.lower()] @@ -1149,6 +1149,7 @@ class ConfigObj(Section): ``ConfigObj(infile=None, options=None, **kwargs)`` """ + print('pink infile = ',infile) if infile is None: infile = [] if options is None: @@ -1191,10 +1192,13 @@ class ConfigObj(Section): # self._terminated = False # - if isinstance(infile, StringTypes): + if isinstance(infile, string_types): self.filename = infile if os.path.isfile(infile): - infile = open(infile).read() or [] + if sys.version_info > (3,): + infile = unicode(open(infile).read()) or [] + else: + infile = open(infile).read() or [] elif self.file_error: # raise an error if the file doesn't exist raise IOError('Config file not found: "%s".' % self.filename) @@ -1233,6 +1237,7 @@ class ConfigObj(Section): ' file like object, or list of lines.') # if infile: + print('infile flyt = ',infile) # don't do it for the empty ConfigObj infile = self._handle_bom(infile) # infile is now *always* a list @@ -1256,6 +1261,7 @@ class ConfigObj(Section): if self._errors: info = "at line %s." % self._errors[0].line_number if len(self._errors) > 1: + raise self._errors[0] msg = ("Parsing failed with several errors.\nFirst error %s" % info) error = ConfigObjError(msg) @@ -1302,6 +1308,10 @@ class ConfigObj(Section): ``infile`` must always be returned as a list of lines, but may be passed in as a single string. """ + if sys.version_info > (3,): + if isinstance(infile, list): + return infile + return infile.splitlines(True) if ((self.encoding is not None) and (self.encoding.lower() not in BOM_LIST)): # No need to check for a BOM @@ -1367,7 +1377,7 @@ class ConfigObj(Section): else: infile = newline # UTF8 - don't decode - if isinstance(infile, StringTypes): + if isinstance(infile, string_types): return infile.splitlines(True) else: return infile @@ -1375,7 +1385,7 @@ class ConfigObj(Section): return self._decode(infile, encoding) # # No BOM discovered and no encoding specified, just return - if isinstance(infile, StringTypes): + if isinstance(infile, string_types): # infile read from a file will be a single string return infile.splitlines(True) else: @@ -1383,6 +1393,8 @@ class ConfigObj(Section): def _a_to_u(self, aString): """Decode ASCII strings to unicode if a self.encoding is specified.""" + if sys.version_info > (3,): + return str(aString) if self.encoding: return aString.decode('ascii') else: @@ -1394,7 +1406,7 @@ class ConfigObj(Section): if is a string, it also needs converting to a list. """ - if isinstance(infile, StringTypes): + if isinstance(infile, string_types): # can't be unicode # NOTE: Could raise a ``UnicodeDecodeError`` return infile.decode(encoding).splitlines(True) @@ -1420,13 +1432,14 @@ class ConfigObj(Section): Used by ``stringify`` within validate, to turn non-string values into strings. """ - if not isinstance(value, StringTypes): + if not isinstance(value, string_types): return str(value) else: return value def _parse(self, infile): """Actually parse the config file.""" + print('aolk', infile) temp_list_values = self.list_values if self.unrepr: self.list_values = False @@ -1671,7 +1684,7 @@ class ConfigObj(Section): return self._quote(value[0], multiline=False) + ',' return ', '.join([self._quote(val, multiline=False) for val in value]) - if not isinstance(value, StringTypes): + if not isinstance(value, string_types): if self.stringify: value = str(value) else: diff --git a/pysollib/game.py b/pysollib/game.py index 9ce3118b..fdd82cd1 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -80,7 +80,7 @@ PLAY_TIME_TIMEOUT = 200 # ************************************************************************ -class Game: +class Game(object): # for self.gstats.updated U_PLAY = 0 U_WON = -2 diff --git a/pysollib/games/freecell.py b/pysollib/games/freecell.py index a6543a34..3ca2b007 100644 --- a/pysollib/games/freecell.py +++ b/pysollib/games/freecell.py @@ -77,7 +77,8 @@ class FreeCell(Game): # create layout l, s = Layout(self), self.s kwdefault(layout, rows=8, reserves=4, texts=0) - self.Layout_Method(l, **layout) + # self.Layout_Method(l, **layout) + self.__class__.__dict__['Layout_Method'](l, **layout) self.setSize(l.size[0], l.size[1]) # create stacks s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) diff --git a/pysollib/games/klondike.py b/pysollib/games/klondike.py index 5077bfa4..3e707407 100644 --- a/pysollib/games/klondike.py +++ b/pysollib/games/klondike.py @@ -79,7 +79,9 @@ class Klondike(Game): # create layout l, s = Layout(self), self.s kwdefault(layout, rows=7, waste=1, texts=1, playcards=16) - self.Layout_Method(l, **layout) + print(l, layout) + self.__class__.__dict__['Layout_Method'](l, **layout) + # self.Layout_Method.__get__(l, l.__class__)(**layout) self.setSize(l.size[0], l.size[1]) # create stacks s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, diff --git a/pysollib/games/mahjongg/mahjongg.py b/pysollib/games/mahjongg/mahjongg.py index 9c5b4f36..740c5800 100644 --- a/pysollib/games/mahjongg/mahjongg.py +++ b/pysollib/games/mahjongg/mahjongg.py @@ -47,8 +47,6 @@ from pysollib.stack import \ InitialDealTalonStack, \ OpenStack -from new import classobj - if sys.version_info > (3,): xrange = range @@ -987,11 +985,11 @@ def comp_cardset(ncards): assert ncards % 4 == 0 assert 0 < ncards <= 288 # ??? decks = 1 - cards = ncards/4 + cards = ncards//4 if ncards > 144: assert ncards % 8 == 0 decks = 2 - cards = cards/2 + cards = cards//2 ranks, trumps = divmod(cards, 3) if ranks > 10: trumps += (ranks-10)*3 @@ -1012,7 +1010,7 @@ def r(id, short_name, name=None, ncards=144, layout=None): name = "Mahjongg " + short_name classname = re.sub('\W', '', name) # create class - gameclass = classobj(classname, (AbstractMahjonggGame,), {}) + gameclass = type(classname, (AbstractMahjonggGame,), {}) gameclass.L = layout gameclass.NCARDS = ncards decks, ranks, trumps = comp_cardset(ncards) diff --git a/pysollib/hint.py b/pysollib/hint.py index 2e776ef3..4724dfb9 100644 --- a/pysollib/hint.py +++ b/pysollib/hint.py @@ -884,7 +884,7 @@ class FreeCellSolver_Hint(Base_Solver_Hint): kw['close_fds'] = True p = subprocess.Popen(command, **kw) pin, pout, perr = p.stdin, p.stdout, p.stderr - pin.write(board) + pin.write(bytes(board, 'utf-8')) pin.close() # stack_types = { @@ -896,39 +896,41 @@ class FreeCellSolver_Hint(Base_Solver_Hint): start_time = time.time() if progress: # iteration output - iter = 0 + iter_ = 0 depth = 0 states = 0 - for s in pout: + for sbytes in pout: + s = str(sbytes, encoding='utf-8') if DEBUG >= 5: print(s) if self.colonPrefixMatch('Iteration', s): - iter = self._v + iter_ = self._v elif self.colonPrefixMatch('Depth', s): depth = self._v elif self.colonPrefixMatch('Stored-States', s): states = self._v - if iter % 100 == 0: - self.dialog.setText(iter=iter, depth=depth, + if iter_ % 100 == 0: + self.dialog.setText(iter=iter_, depth=depth, states=states) elif re.search('^(?:-=-=)', s): break elif self._determineIfSolverState(s): break - self.dialog.setText(iter=iter, depth=depth, states=states) + self.dialog.setText(iter=iter_, depth=depth, states=states) hints = [] - for s in pout: + for sbytes in pout: + s = str(sbytes, encoding='utf-8') if DEBUG: print(s) if self._determineIfSolverState(s): next m = re.match('Total number of states checked is (\d+)\.', s) if m: - iter = int(m.group(1)) - self.dialog.setText(iter=iter) + iter_ = int(m.group(1)) + self.dialog.setText(iter=iter_) m = re.match('This scan generated (\d+) states\.', s) @@ -1061,7 +1063,7 @@ class BlackHoleSolver_Hint(Base_Solver_Hint): result = '' # iteration output - iter = 0 + iter_ = 0 depth = 0 states = 0 @@ -1073,7 +1075,7 @@ class BlackHoleSolver_Hint(Base_Solver_Hint): if m: result = m.group(1) break - self.dialog.setText(iter=iter, depth=depth, states=states) + self.dialog.setText(iter=iter_, depth=depth, states=states) if (result == 'Intractable!'): self.solver_state = 'intractable' @@ -1090,8 +1092,8 @@ class BlackHoleSolver_Hint(Base_Solver_Hint): print(s) m = re.match('Total number of states checked is (\d+)\.', s) if m: - iter = int(m.group(1)) - self.dialog.setText(iter=iter) + iter_ = int(m.group(1)) + self.dialog.setText(iter=iter_) continue m = re.match('This scan generated (\d+) states\.', s) diff --git a/pysollib/layout.py b/pysollib/layout.py index f1cc2e40..f32fdeb8 100644 --- a/pysollib/layout.py +++ b/pysollib/layout.py @@ -115,9 +115,9 @@ class Layout: self.__dict__.update(kw) if self.game.preview > 1: if "XOFFSET" in kw: - self.XOFFSET /= self.game.preview + self.XOFFSET //= self.game.preview if "YOFFSET" in kw: - self.YOFFSET /= self.game.preview + self.YOFFSET //= self.game.preview self.TEXT_HEIGHT = 10 def __createStack(self, x, y, suit=None): @@ -158,7 +158,7 @@ class Layout: s.waste = waste_class(self.s.waste.x, self.s.waste.y, game) if foundation_class: if isinstance(foundation_class, (list, tuple)): - n = len(self.s.foundations)/len(foundation_class) + n = len(self.s.foundations)//len(foundation_class) i = 0 for j in range(n): for cls in foundation_class: @@ -197,16 +197,16 @@ class Layout: delta_x, delta_y = 4, 4 delta_yy = 10 d = { - "n": (x+self.CW/2, y-delta_y, "s", "%d"), - "nn": (x+self.CW/2, y-delta_yy, "s", "%d"), - "s": (x+self.CW/2, y+self.CH+delta_y, "n", "%d"), - "ss": (x+self.CW/2, y+self.CH+delta_yy, "n", "%d"), + "n": (x+self.CW//2, y-delta_y, "s", "%d"), + "nn": (x+self.CW//2, y-delta_yy, "s", "%d"), + "s": (x+self.CW//2, y+self.CH+delta_y, "n", "%d"), + "ss": (x+self.CW//2, y+self.CH+delta_yy, "n", "%d"), "nw": (x-delta_x, y, "ne", "%d"), "sw": (x-delta_x, y+self.CH, "se", "%d"), "ne": (x+self.CW+delta_x, y, "nw", "%d"), "se": (x+self.CW+delta_x, y+self.CH, "sw", "%d"), - "w": (x-delta_x, y+self.CH/2, "e", "%d"), - "e": (x+self.CW+delta_x, y+self.CH/2, "w", "%d"), + "w": (x-delta_x, y+self.CH//2, "e", "%d"), + "e": (x+self.CW+delta_x, y+self.CH//2, "w", "%d"), } return d[anchor] @@ -305,11 +305,11 @@ class Layout: decks = self.game.gameinfo.decks suits = len(self.game.gameinfo.suits) + bool(self.game.gameinfo.trumps) - halfrows = (rows + 1) / 2 + halfrows = (rows + 1) // 2 # set size so that at least 9 cards are fully playable h = YS + min(2*YS, (playcards-1)*self.YOFFSET) - h = max(h, 5*YS/2, 3*YS/2+CH) + h = max(h, 5*YS//2, 3*YS//2+CH) h = min(h, 3*YS) # create rows @@ -321,7 +321,7 @@ class Layout: # create foundations x, y = XM + halfrows * XS, YM - self.setRegion(self.s.rows, (-999, -999, x - CW / 2, 999999)) + self.setRegion(self.s.rows, (-999, -999, x - CW // 2, 999999)) for suit in range(suits): for i in range(decks): self.s.foundations.append(S(x+i*XS, y, suit=suit)) @@ -343,7 +343,7 @@ class Layout: # - left bottom: talon, waste # - def freeCellLayout(self, rows, reserves, waste=0, + def freeCellLayout(self, rows=0, reserves=0, waste=0, texts=0, reserve_texts=False, playcards=18): S = self.__createStack CH = self.CH @@ -359,14 +359,14 @@ class Layout: w = XM + maxrows*XS - # set size so that at least 2/3 of a card is visible with 18 cards - h = CH*2/3 + (playcards-1)*self.YOFFSET + # 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 + x, y = (w - (toprows*XS - XM))//2, YM if reserves: for i in range(reserves): s = S(x, y) @@ -381,13 +381,13 @@ class Layout: x += XS # create rows - x, y = (w - (rows*XS - XM))/2, YM + YS + 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 - self.setRegion(self.s.rows, (-999, y - CH / 2, 999999, 999999)) + self.setRegion(self.s.rows, (-999, y - CH // 2, 999999, 999999)) # create talon x, y = XM, h - YS @@ -431,8 +431,8 @@ class Layout: if reserves: h = YS+(playcards-1)*self.YOFFSET+YS else: - # set size so that at least 2/3 of a card is visible with 25 cards - h = CH*2/3 + (playcards-1)*self.YOFFSET + # 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 @@ -443,10 +443,10 @@ class Layout: self.s.rows.append(S(x, y)) x += XS if reserves: - yy = h - YS - CH/2 + yy = h - YS - CH//2 else: yy = 999999 - self.setRegion(self.s.rows, (-999, -999, x - CW / 2, yy)) + self.setRegion(self.s.rows, (-999, -999, x - CW // 2, yy)) # create foundations x = w - decks*XS @@ -458,7 +458,7 @@ class Layout: # create talon and waste x, y = x + (decks-1)*XS, h - YS if texts: - x -= XS/2 + x -= XS//2 self.s.talon = s = S(x, y) anchor = 's' if round_text: @@ -519,7 +519,7 @@ class Layout: if reserves: if reserve_texts: y += self.TEXT_HEIGHT - x = (w - (reserves*XS - XM))/2 + x = (w - (reserves*XS - XM))//2 for i in range(reserves): s = S(x, y) self.s.reserves.append(s) @@ -527,7 +527,7 @@ class Layout: if reserve_texts: self._setText(s, anchor="n") y += YS - x = (w - (rows*XS - XM))/2 + x = (w - (rows*XS - XM))//2 for i in range(rows): self.s.rows.append(S(x, y)) x += XS @@ -539,12 +539,12 @@ class Layout: self.s.foundations.append(S(x, y, suit=suit)) x += XS if reserves: - yy = YM + YS - CH/2 + 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)) + self.setRegion(self.s.rows, (-999, yy, 999999, y - YS // 2)) if waste: x = w - 2*XS self.s.waste = s = S(x, y) @@ -567,7 +567,7 @@ class Layout: # - bottom: reserves # - def klondikeLayout(self, rows, waste, reserves=0, + def klondikeLayout(self, rows=0, waste=0, reserves=0, texts=1, reserve_texts=False, round_text=False, playcards=16, center=1, text_height=0): S = self.__createStack @@ -578,15 +578,15 @@ class Layout: decks = self.game.gameinfo.decks suits = len(self.game.gameinfo.suits) + bool(self.game.gameinfo.trumps) foundrows = 1 + (suits > 5) - frows = decks * suits / foundrows + frows = decks * suits // foundrows toprows = 1 + waste + frows if round_text: toprows += 1 maxrows = max(rows, toprows, reserves) w = XM + maxrows * XS - # set size so that at least 2/3 of a card is visible with 16 cards - h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET + # set size so that at least 2//3 of a card is visible with 16 cards + h = CH * 2 // 3 + (playcards - 1) * self.YOFFSET h = max(h, 2 * YS) h += YM + YS * foundrows if reserves and reserve_texts: @@ -616,32 +616,32 @@ class Layout: x = w - frows * XS if center and frows + 2 * (1 + waste + 1) <= maxrows: # center the foundations - x = XM + (maxrows - frows) * XS / 2 - for suit in range(suits / foundrows): + x = XM + (maxrows - frows) * XS // 2 + for suit in range(suits // foundrows): for i in range(decks): self.s.foundations.append( - S(x, y, suit=suit + (row * (suits / 2)))) + S(x, y, suit=suit + (row * (suits // 2)))) x += XS y += YS # below x = XM if rows < maxrows: - x += (maxrows-rows) * XS/2 + x += (maxrows-rows) * XS//2 # y += YM * (3 - foundrows) y += text_height for i in range(rows): self.s.rows.append(S(x, y)) x += XS if reserves: - yy = h - CH/2 + yy = h - CH//2 else: yy = 999999 - self.setRegion(self.s.rows, (-999, y-CH/2, 999999, yy)) + self.setRegion(self.s.rows, (-999, y-CH//2, 999999, yy)) # bottom if reserves: - x = (maxrows-reserves)*XS/2 + x = (maxrows-reserves)*XS//2 y = h h += YS for i in range(reserves): @@ -670,8 +670,8 @@ class Layout: decks = self.game.gameinfo.decks suits = len(self.game.gameinfo.suits) + bool(self.game.gameinfo.trumps) - # set size so that at least 2/3 of a card is visible with 20 cards - h = CH*2/3 + (playcards-1)*self.YOFFSET + # set size so that at least 2//3 of a card is visible with 20 cards + h = CH*2//3 + (playcards-1)*self.YOFFSET h = YM + max(h, suits*YS) # create rows @@ -679,7 +679,7 @@ class Layout: for i in range(rows): self.s.rows.append(S(x, y)) x += XS - self.setRegion(self.s.rows, (-999, -999, x - CW / 2, 999999)) + self.setRegion(self.s.rows, (-999, -999, x - CW // 2, 999999)) # create foundations for suit in range(suits): @@ -711,13 +711,13 @@ class Layout: decks = self.game.gameinfo.decks ranks = len(self.game.gameinfo.ranks) - frows = 4 * decks / (1 + (decks >= 3)) + frows = 4 * decks // (1 + (decks >= 3)) toprows = 1 + waste + frows maxrows = max(rows, toprows) yextra = 0 - # set size so that at least 2/3 of a card is visible with 10 cards - h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET + # set size so that at least 2//3 of a card is visible with 10 cards + h = CH * 2 // 3 + (playcards - 1) * self.YOFFSET h = max(h, 2 * YS) # top @@ -740,7 +740,7 @@ class Layout: x = XM + (maxrows - frows) * XS if center and frows + 2 * (1 + waste + 1) <= maxrows: # center the foundations - x = XM + (maxrows - frows) * XS / 2 + x = XM + (maxrows - frows) * XS // 2 x0, y0 = x, y for i in range(decks): @@ -753,7 +753,7 @@ class Layout: # bottom x, y = XM, y + YS + yextra * (decks <= 2) - self.setRegion(self.s.rows, (-999, y - YM / 2, 999999, 999999)) + self.setRegion(self.s.rows, (-999, y - YM // 2, 999999, 999999)) for i in range(rows): self.s.rows.append(S(x, y)) x += XS @@ -778,12 +778,12 @@ class Layout: toprows = 2 * decks + rows yextra = 0 - # set size so that at least 2/3 of a card is visible with 20 cards - h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET + # set size so that at least 2//3 of a card is visible with 20 cards + h = CH * 2 // 3 + (playcards - 1) * self.YOFFSET h = max(h, 2 * YS) # bottom center - x = (XM + (toprows * XS) / 2) - XS + x = (XM + (toprows * XS) // 2) - XS y = h self.s.talon = s = S(x, y) if texts: @@ -815,7 +815,7 @@ class Layout: # top center x, y = XM + XS * decks, YM - self.setRegion(self.s.rows, (x - XM / 2, 0, x + XS * rows, 999999)) + self.setRegion(self.s.rows, (x - XM // 2, 0, x + XS * rows, 999999)) for i in range(rows): self.s.rows.append(S(x, y)) x += XS @@ -842,8 +842,8 @@ class Layout: maxrows = max(rows, toprows) w = XM + maxrows * XS - # set size so that at least 2/3 of a card is visible with 12 cards - h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET + # set size so that at least 2//3 of a card is visible with 12 cards + h = CH * 2 // 3 + (playcards - 1) * self.YOFFSET h = max(h, 2 * YS) # create foundations @@ -855,21 +855,21 @@ class Layout: x, y = XM, y + YS # create rows - x, y = XM + XS * ((toprows - rows) / 2), YM + YS * decks + x, y = XM + XS * ((toprows - rows) // 2), YM + YS * decks for i in range(rows): self.s.rows.append(S(x, y)) x += XS self.setRegion( self.s.rows, - (XS + XM / 2, YS * decks + YM / 2, XS * 11 - XM / 2, 999999)) + (XS + XM // 2, YS * decks + YM // 2, XS * 11 - XM // 2, 999999)) # create reserves x, y = XM, YM + YS * decks - for i in range(reserves / 2): + for i in range(reserves // 2): self.s.reserves.append(S(x, y)) y += YS x, y = w - XS, YM + YS * decks - for i in range(reserves / 2): + for i in range(reserves // 2): self.s.reserves.append(S(x, y)) y += YS @@ -900,12 +900,12 @@ class Layout: ranks = len(self.game.gameinfo.ranks) assert rows % 2 == 0 assert reserves % decks == 0 - toprows = decks + rows / 2 + toprows = decks + rows // 2 w = XM * 2 + toprows * XS - # set size so that at least 2/3 of a card is visible with 12 cards - h1 = CH * 2 / 3 + (playcards - 1) * self.YOFFSET - h2 = (3 + reserves / decks) * YS + # set size so that at least 2//3 of a card is visible with 12 cards + h1 = CH * 2 // 3 + (playcards - 1) * self.YOFFSET + h2 = (3 + reserves // decks) * YS h = max(h1, h2) # create foundations @@ -918,19 +918,19 @@ class Layout: # create rows x, y = XM, YM - for i in range(rows / 2): + for i in range(rows // 2): self.s.rows.append(S(x, y)) x += XS - x, y = XM, (YS + h) / 2 - for i in range(rows / 2): + x, y = XM, (YS + h) // 2 + for i in range(rows // 2): self.s.rows.append(S(x, y)) x += XS - self.setRegion(self.s.rows, (0, 0, XS * rows / 2 + XM / 2, 999999)) + self.setRegion(self.s.rows, (0, 0, XS * rows // 2 + XM // 2, 999999)) # create reserves x, y = w - XS * decks, YM + YS * 4 for i in range(decks): - for i in range(reserves / decks): + for i in range(reserves // decks): self.s.reserves.append(S(x, y)) y += YS x, y = x + XS, YM + YS * 4 @@ -960,11 +960,11 @@ class Layout: decks = self.game.gameinfo.decks assert rows % 2 == 0 - toprows = decks + rows / 2 + toprows = decks + rows // 2 w = XM * 2 + toprows * (XS + XM) - # set size so that at least 2/3 of a card is visible with 12 cards - h = CH * 2 / 3 + (playcards - 1) * self.YOFFSET + # set size so that at least 2//3 of a card is visible with 12 cards + h = CH * 2 // 3 + (playcards - 1) * self.YOFFSET h = max(h, 2 * YS) # create talon @@ -976,11 +976,11 @@ class Layout: # create rows x, y = XS + XM * 3, YM - for i in range(rows / 2): + for i in range(rows // 2): self.s.rows.append(S(x, y)) x += XS + XM - x, y = XS + XM * 3, (YS + h) / 2 - for i in range(rows / 2): + x, y = XS + XM * 3, (YS + h) // 2 + for i in range(rows // 2): self.s.rows.append(S(x, y)) x += XS + XM self.setRegion(self.s.rows, (XS + XM, -999, 999999, 999999)) @@ -988,7 +988,7 @@ class Layout: # create reserves x, y = XM, YM + YS + self.TEXT_HEIGHT for i in range(decks): - for i in range(reserves / decks): + for i in range(reserves // decks): self.s.reserves.append(S(x, y)) y += YS x, y = x + XS, YM + YS * 4 @@ -1013,28 +1013,28 @@ class Layout: assert reserves % 2 == 0 # set size - w, h = XM * 3 + XS * ((rows / 2) + 2), YM + YS * ((suits / 2) + 2) + w, h = XM * 3 + XS * ((rows // 2) + 2), YM + YS * ((suits // 2) + 2) # create foundations x, y = XM, YM for i in range(suits): self.s.foundations.append(S(x, y, suit=i)) y += YS - if i == suits / 2 - 1: + if i == suits // 2 - 1: x, y = w - XS, YM # create rows x = XM * 2 + XS - for i in range(rows / 2): + for i in range(rows // 2): self.s.rows.append(S(x + i * XS, YM)) - for i in range(rows / 2): - self.s.rows.append(S(x + i * XS, h / 2)) + for i in range(rows // 2): + self.s.rows.append(S(x + i * XS, h // 2)) self.setRegion(self.s.rows, (XM + XS, -999, w - XM - XS, 999999)) # create reserves - for i in range(reserves / 2): + for i in range(reserves // 2): self.s.reserves.append(S(XM, h - YS * (i + 1))) - for i in range(reserves / 2): + for i in range(reserves // 2): self.s.reserves.append(S(w - XS, h - YS * (i + 1))) # create talon @@ -1058,8 +1058,8 @@ class Layout: decks = self.game.gameinfo.decks suits = len(self.game.gameinfo.suits) + bool(self.game.gameinfo.trumps) - frows = suits * decks / 2 - fspace = XS * (rows - 1) / 2 + frows = suits * decks // 2 + fspace = XS * (rows - 1) // 2 # Set window size w, h = XM + XS * rows, YM * 2 + YS * height @@ -1073,16 +1073,16 @@ class Layout: self._setText(s, 'se') # Create foundations - x = w - fspace - XS * frows / 2 - for suit in range(suits / 2): + x = w - fspace - XS * frows // 2 + for suit in range(suits // 2): for i in range(decks): self.s.foundations.append(S(x, y, suit=suit)) x += XS - x = w - fspace - XS * frows / 2 + x = w - fspace - XS * frows // 2 y += YS - for suit in range(suits / 2): + for suit in range(suits // 2): for i in range(decks): - self.s.foundations.append(S(x, y, suit=(suit + suits / 20))) + self.s.foundations.append(S(x, y, suit=(suit + suits // 20))) x += XS # bottom diff --git a/pysollib/mfxutil.py b/pysollib/mfxutil.py index 35ab1229..d57bad5c 100644 --- a/pysollib/mfxutil.py +++ b/pysollib/mfxutil.py @@ -37,7 +37,6 @@ __all__ = [ import sys import os import time -import types import locale import webbrowser from six import print_ @@ -87,6 +86,8 @@ class SubclassResponsibility(Exception): def latin1_to_ascii(n): + if sys.version_info > (3,): + return n # return n n = n.encode('iso8859-1', 'replace') # FIXME: rewrite this for better speed @@ -183,7 +184,6 @@ def win32_getprefdir(package): def destruct(obj): # assist in breaking circular references if obj is not None: - assert isinstance(obj, types.InstanceType) for k in obj.__dict__.keys(): obj.__dict__[k] = None # del obj.__dict__[k] diff --git a/pysollib/options.py b/pysollib/options.py index 30fe01e9..2b78b950 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -487,7 +487,8 @@ class Options: for key, t in self.GENERAL_OPTIONS: val = getattr(self, key) if isinstance(val, str): - val = unicode(val, 'utf-8') + if sys.version_info < (3,): + val = unicode(val, 'utf-8') config['general'][key] = val config['general']['recent_gameid'] = self.recent_gameid @@ -563,10 +564,12 @@ class Options: # create ConfigObj instance try: + print(filename) config = configobj.ConfigObj(filename, configspec=configspec, encoding=self._config_encoding) except configobj.ParseError: + raise BaseException('foo') traceback.print_exc() config = configobj.ConfigObj(configspec=configspec, encoding=self._config_encoding) diff --git a/pysollib/pysolrandom.py b/pysollib/pysolrandom.py index 75303c7b..16b14cf3 100644 --- a/pysollib/pysolrandom.py +++ b/pysollib/pysolrandom.py @@ -116,19 +116,19 @@ class MTRandom(BasicRandom, random.Random): # * uses the standard python module `random' # ************************************************************************ -class WHRandom(BasicRandom, random.WichmannHill): - - def __init__(self, seed=None): - if seed is None: - seed = self._getRandomSeed() - BasicRandom.__init__(self) - random.WichmannHill.__init__(self, seed) - self.initial_seed = seed - self.initial_state = self.getstate() - self.origin = self.ORIGIN_UNKNOWN - - def reset(self): - self.setstate(self.initial_state) +# class WHRandom(BasicRandom, random.WichmannHill): +# +# def __init__(self, seed=None): +# if seed is None: +# seed = self._getRandomSeed() +# BasicRandom.__init__(self) +# random.WichmannHill.__init__(self, seed) +# self.initial_seed = seed +# self.initial_state = self.getstate() +# self.origin = self.ORIGIN_UNKNOWN +# +# def reset(self): +# self.setstate(self.initial_state) # ************************************************************************ # * Abstract class for LC Random number generators. diff --git a/pysollib/settings.py b/pysollib/settings.py index 43ee9bdd..31749e0c 100644 --- a/pysollib/settings.py +++ b/pysollib/settings.py @@ -79,5 +79,5 @@ SELECT_GAME_MENU = True TRANSLATE_GAME_NAMES = True # debug -DEBUG = 0 # must be integer +DEBUG = 121 # must be integer CHECK_GAMES = False # check duplicated names and classes diff --git a/pysollib/ui/tktile/tkhtml.py b/pysollib/ui/tktile/tkhtml.py index b1bcb7c1..9a0e5188 100644 --- a/pysollib/ui/tktile/tkhtml.py +++ b/pysollib/ui/tktile/tkhtml.py @@ -22,7 +22,7 @@ # --------------------------------------------------------------------------- import os -import htmllib +# import htmllib import formatter from six.moves import tkinter @@ -182,7 +182,8 @@ class tkHTMLWriter(formatter.NullWriter): # * # ************************************************************************ -class tkHTMLParser(htmllib.HTMLParser): +# class tkHTMLParser(htmllib.HTMLParser): +class tkHTMLParser: def anchor_bgn(self, href, name, type): self.formatter.flush_softspace() htmllib.HTMLParser.anchor_bgn(self, href, name, type)