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

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.
This commit is contained in:
Shlomi Fish 2017-06-03 03:01:33 +03:00
parent 0417068664
commit aa4f9ee5da
14 changed files with 369 additions and 158 deletions

190
Canvas.py Normal file
View file

@ -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')

View file

@ -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()

View file

@ -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:

View file

@ -80,7 +80,7 @@ PLAY_TIME_TIMEOUT = 200
# ************************************************************************
class Game:
class Game(object):
# for self.gstats.updated
U_PLAY = 0
U_WON = -2

View file

@ -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)

View file

@ -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,

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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]

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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)