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

* improved statistics

* improved tile support
* misc. bugs fixes and improvements


git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@81 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2006-10-20 21:18:06 +00:00
parent e401d6a28e
commit a4a25adbd9
15 changed files with 371 additions and 459 deletions

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PySol 0.0.1\n"
"POT-Creation-Date: Sat Oct 7 20:02:33 2006\n"
"PO-Revision-Date: 2006-10-07 20:10+0400\n"
"PO-Revision-Date: 2006-10-08 18:43+0400\n"
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
@ -1430,7 +1430,7 @@ msgid "Intelligence +"
msgstr "Смекалка +"
msgid "Interchange"
msgstr "Чередование"
msgstr "Перестановка"
msgid "Interment"
msgstr "Погребение"

View file

@ -46,18 +46,16 @@ from settings import TOP_TITLE
from gamedb import GI
# stats imports
from stats import PysolStatsFormatter
from stats import FileStatsFormatter
from pysoltk import SingleGame_StatsDialog, AllGames_StatsDialog
from pysoltk import FullLog_StatsDialog, SessionLog_StatsDialog
from pysoltk import Status_StatsDialog, Top_StatsDialog
from pysoltk import GameInfoDialog
# toolkit imports
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
from pysoltk import MfxMessageDialog, MfxSimpleEntry
from pysoltk import MfxExceptionDialog
from pysoltk import PlayerOptionsDialog
#from pysoltk import HintOptionsDialog
from pysoltk import TimeoutsDialog
from pysoltk import ColorsDialog
from pysoltk import FontsDialog
@ -533,7 +531,7 @@ class PysolMenubarActions:
# Game menu - statistics
#
def _mStatsSave(self, player, header, filename, write_method):
def _mStatsSave(self, player, filename, write_method):
file = None
if player is None:
text = _("Demo statistics")
@ -544,10 +542,8 @@ class PysolMenubarActions:
filename = os.path.normpath(filename)
try:
file = open(filename, "a")
a = PysolStatsFormatter(self.app)
writer = a.FileWriter(file)
apply(write_method, (a, writer, player, header))
destruct(a)
a = FileStatsFormatter(self.app, file)
write_method(a, player)
except EnvError, ex:
if file: file.close()
d = MfxExceptionDialog(self.top, ex,
@ -597,19 +593,16 @@ class PysolMenubarActions:
d = GameInfoDialog(self.top, header, self.app)
elif mode == 202:
# print stats to file
header = _("Statistics for ") + p0
write_method = PysolStatsFormatter.writeStats
self._mStatsSave(player, header, "stats", write_method)
write_method = FileStatsFormatter.writeStats
self._mStatsSave(player, "stats", write_method)
elif mode == 203:
# print full log to file
header = _("Full log for ") + p0
write_method = PysolStatsFormatter.writeFullLog
self._mStatsSave(player, header, "log", write_method)
write_method = FileStatsFormatter.writeFullLog
self._mStatsSave(player, "log", write_method)
elif mode == 204:
# print session log to file
header = _("Session log for ") + p0
write_method = PysolStatsFormatter.writeSessionLog
self._mStatsSave(player, header, "log", write_method)
write_method = FileStatsFormatter.writeSessionLog
self._mStatsSave(player, "log", write_method)
elif mode == 301:
# reset all player stats
if self.game.areYouSure(_("Reset all statistics"),

View file

@ -143,10 +143,10 @@ class Options:
'startdrag' : True,
'turnwaste' : True,
'undo' : True,
'gamefinished' : True,
'gamelost' : True,
'gameperfect' : True,
'gamewon' : True,
'gamefinished' : False,
'gamelost' : False,
'gameperfect' : False,
'gamewon' : False,
}
# fonts
self.fonts = {"default" : None,

View file

@ -778,8 +778,6 @@ class Game:
def _defaultHandler(self):
self.interruptSleep()
self.deleteStackDesc()
if self.demo:
self.stopDemo()
def clickHandler(self, event):
self._defaultHandler()
@ -789,6 +787,9 @@ class Game:
def undoHandler(self, event):
if not self.app: return EVENT_PROPAGATE # FIXME (GTK)
self._defaultHandler()
if self.demo:
self.stopDemo()
return
if self.app.opt.mouse_undo and not self.event_handled:
self.app.menubar.mUndo()
self.event_handled = False
@ -797,6 +798,9 @@ class Game:
def redoHandler(self, event):
if not self.app: return EVENT_PROPAGATE # FIXME (GTK)
self._defaultHandler()
if self.demo:
self.stopDemo()
return
if self.app.opt.mouse_undo and not self.event_handled:
self.app.menubar.mRedo()
self.event_handled = False

View file

@ -132,7 +132,7 @@ class Strata(Game):
for i in range(8):
s.rows.append(AC_RowStack(x, y, self, max_move=1, max_accept=1))
x = x + l.XS
s.talon = RedealTalonStack(l.XM, l.YM, self, max_rounds=2)
s.talon = RedealTalonStack(l.XM, l.YM, self, max_rounds=3)
# define stack-groups
l.defaultStackGroups()
@ -157,6 +157,6 @@ registerGame(GameInfo(293, Nationale, "Nationale",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL,
altnames=('Zigzag Course',) ))
registerGame(GameInfo(606, Strata, "Strata",
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 2, 1, GI.SL_MOSTLY_SKILL,
GI.GT_BAKERS_DOZEN | GI.GT_OPEN, 2, 2, GI.SL_MOSTLY_SKILL,
ranks=(0, 6, 7, 8, 9, 10, 11, 12) ))

View file

@ -693,18 +693,20 @@ class Octagon(Game):
i = 0
for x, y in ((l.XM+w1, l.YM),
(l.XM+w1+l.XS, l.YM),
(l.XM+w1-2*l.XS-l.XM, l.YM+l.YS),
(l.XM+w1-l.XS-l.XM, l.YM+l.YS),
(l.XM+w1+2*l.XS+l.XM, l.YM+l.YS),
(l.XM+w1+3*l.XS+l.XM, l.YM+l.YS),
(l.XM+w1-2*l.XS-l.XS/2-l.XM, l.YM+l.YS),
(l.XM+w1-l.XS-l.XS/2-l.XM, l.YM+l.YS),
(l.XM+w1+2*l.XS+l.XS/2+l.XM, l.YM+l.YS),
(l.XM+w1+3*l.XS+l.XS/2+l.XM, l.YM+l.YS),
(l.XM+w1, l.YM+2*l.YS),
(l.XM+w1+l.XS, l.YM+2*l.YS),):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4))
i += 1
x, y = l.XM+w1, l.YM+l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=4)
l.createText(s.talon, 'nw')
x += l.XS
s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'ne')
l.defaultStackGroups()

View file

@ -596,6 +596,10 @@ class Toad(Game):
# // Shifting
# ************************************************************************/
class Shifting_Hint(Numerica_Hint):
shallMovePile = DefaultHint._cautiousShallMovePile
class Shifting_RowStack(Numerica_RowStack):
def acceptsCards(self, from_stack, cards):
if not BasicRowStack.acceptsCards(self, from_stack, cards):
@ -611,6 +615,7 @@ class Shifting_RowStack(Numerica_RowStack):
class Shifting(Numerica):
Hint_Class = Shifting_Hint
RowStack_Class = StackWrapper(Shifting_RowStack, max_accept=1)

View file

@ -415,10 +415,8 @@ class Carpet(Game):
# // British Constitution
# ************************************************************************/
class BritishConstitution_RowStack(AC_RowStack):
class BritishConstitution_RowStackMethods:
def acceptsCards(self, from_stack, cards):
if not AC_RowStack.acceptsCards(self, from_stack, cards):
return False
if self in self.game.s.rows[:8] and from_stack in self.game.s.rows[8:16]:
return True
if self in self.game.s.rows[8:16] and from_stack in self.game.s.rows[16:24]:
@ -429,6 +427,18 @@ class BritishConstitution_RowStack(AC_RowStack):
return True
return False
class BritishConstitution_RowStack(BritishConstitution_RowStackMethods, AC_RowStack):
def acceptsCards(self, from_stack, cards):
if not AC_RowStack.acceptsCards(self, from_stack, cards):
return False
return BritishConstitution_RowStackMethods.acceptsCards(self, from_stack, cards)
class NewBritishConstitution_RowStack(BritishConstitution_RowStackMethods, RK_RowStack):
def acceptsCards(self, from_stack, cards):
if not RK_RowStack.acceptsCards(self, from_stack, cards):
return False
return BritishConstitution_RowStackMethods.acceptsCards(self, from_stack, cards)
class BritishConstitution_Foundation(SS_FoundationStack):
def acceptsCards(self, from_stack, cards):
@ -500,8 +510,7 @@ class BritishConstitution(Game):
class NewBritishConstitution(BritishConstitution):
RowStack_Class = StackWrapper(BritishConstitution_RowStack, base_rank=JACK)
RowStack_Class = StackWrapper(NewBritishConstitution_RowStack, base_rank=JACK)
# /***********************************************************************

View file

@ -40,61 +40,71 @@ gettext = _
# //
# ************************************************************************/
class StatsWriter(PysolStatsFormatter.StringWriter):
class StatsFormatter(PysolStatsFormatter):
def __init__(self, store):
def __init__(self, app, store):
self.app = app
self.store = store
def p(self, s):
pass
def pheader(self, s):
pass
def pstats(self, *args, **kwargs):
gameid=kwargs.get('gameid', None)
if gameid is None:
# header
return
def writeStats(self, player, sort_by='name'):
for result in self.getStatResults(player, sort_by):
iter = self.store.append(None)
self.store.set(iter,
0, gettext(result[0]),
1, result[1],
2, result[2],
3, result[3],
4, result[4],
5, result[5],
6, result[6],
7, result[7])
total, played, won, lost, time, moves, perc = self.getStatSummary()
text = _("Total (%d out of %d games)") % (played, total)
iter = self.store.append(None)
self.store.set(iter,
0, gettext(args[0]),
1, args[1],
2, args[2],
3, args[3],
4, args[4],
5, args[5],
6, args[6],
7, gameid)
0, text,
1, won+lost,
2, won,
3, lost,
4, time,
5, moves,
6, perc,
7, -1)
return 1
class LogWriter(PysolStatsFormatter.StringWriter):
class LogFormatter(PysolStatsFormatter):
MAX_ROWS = 10000
def __init__(self, store):
def __init__(self, app, store):
self.app = app
self.store = store
self._num_rows = 0
def p(self, s):
pass
def writeLog(self, player, prev_games):
if not player or not prev_games:
return 0
num_rows = 0
for result in self.getLogResults(player, prev_games):
iter = self.store.append(None)
self.store.set(iter,
0, gettext(result[0]),
1, result[1],
2, result[2],
3, result[3],
4, result[4])
num_rows += 1
if num_rows > self.MAX_ROWS:
break
return 1
def pheader(self, s):
pass
def writeFullLog(self, player):
prev_games = self.app.stats.prev_games.get(player)
return self.writeLog(player, prev_games)
def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
if gameid < 0:
# header
return
if self._num_rows > self.MAX_ROWS:
return
iter = self.store.append(None)
self.store.set(iter,
0, gettext(gamename),
1, gamenumber,
2, date,
3, status,
4, gameid)
self._num_rows += 1
def writeSessionLog(self, player):
prev_games = self.app.stats.session_games.get(player)
return self.writeLog(player, prev_games)
class Game_StatsDialog:
@ -107,7 +117,6 @@ class Game_StatsDialog:
self.games = {}
self.games_id = [] # sorted by name
#
formatter = PysolStatsFormatter(self.app)
glade_file = app.dataloader.findFile('pysolfc.glade')
#
games = app.gdb.getGamesIdSortedByName()
@ -142,16 +151,16 @@ class Game_StatsDialog:
self._updateTop(gameid)
# all games stat
store = self._createStatsList()
writer = StatsWriter(store)
formatter.writeStats(writer, player, header, sort_by='name')
formatter = StatsFormatter(app, store)
formatter.writeStats(player)
# full log
store = self._createLogList('full_log_treeview')
writer = LogWriter(store)
formatter.writeFullLog(writer, player, header)
formatter = LogFormatter(app, store)
formatter.writeFullLog(player)
# session log
store = self._createLogList('session_log_treeview')
writer = LogWriter(store)
formatter.writeSessionLog(writer, player, header)
formatter = LogFormatter(app, store)
formatter.writeSessionLog(player)
#
self._translateLabels()
dialog = self.widgets_tree.get_widget('stats_dialog')

View file

@ -38,69 +38,28 @@
import os, sys, time, types
# PySol imports
from mfxutil import SubclassResponsibility, Struct, destruct
from mfxutil import format_time
from settings import PACKAGE, VERSION
from gamedb import GI
# // FIXME - this a quick hack and needs a rewrite
# /***********************************************************************
# //
# ************************************************************************/
class PysolStatsFormatter:
def __init__(self, app):
self.app = app
#
#
#
class StringWriter:
def __init__(self):
self.text = ""
def p(self, s):
self.text = self.text + s
def nl(self, count=1):
self.p("\n" * count)
def pheader(self, s):
self.p(s)
def pstats(self, *args, **kwargs):
s = "%-30s %7s %7s %7s %7s %7s %7s\n" % args
self.p(s)
def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
self.p("%-25s %-20s %17s %s\n" % (gamename, gamenumber, date, status))
class FileWriter(StringWriter):
def __init__(self, file):
self.file = file
def getStatHeader(self):
return (_("Game"),
_("Played"),
_("Won"),
_("Lost"),
_('Playing time'),
_('Moves'),
_("% won"))
def p(self, s):
self.file.write(s.encode('utf-8'))
#
#
#
def writeHeader(self, writer, header, pagewidth=72):
date = time.ctime(time.time())
date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()))
blanks = max(pagewidth - len(header) - len(date), 1)
writer.pheader(header + " "*blanks + date + "\n")
writer.pheader("-" * pagewidth + "\n")
writer.pheader("\n")
def writeStats(self, writer, player, header, sort_by='name'):
def getStatResults(self, player, sort_by='name'):
app = self.app
#
sort_functions = {
@ -113,18 +72,8 @@ class PysolStatsFormatter:
'percent': app.getGamesIdSortedByPercent,
}
sort_func = sort_functions[sort_by]
self.writeHeader(writer, header, 62)
writer.pstats(player or _("Demo games"),
_("Played"),
_("Won"),
_("Lost"),
_('Playing time'),
_('Moves'),
_("% won"))
writer.nl()
twon, tlost, tgames, ttime, tmoves = 0, 0, 0, 0, 0
g = sort_func()
twon, tlost, tgames, ttime, tmoves = 0, 0, 0, 0, 0
for id in g:
name = app.getGameTitleName(id)
#won, lost = app.stats.getStats(player, id)
@ -134,33 +83,43 @@ class PysolStatsFormatter:
if won + lost > 0: perc = "%.1f" % (100.0 * won / (won + lost))
else: perc = "0.0"
if won > 0 or lost > 0 or id == app.game.id:
#writer.pstats(name, won+lost, won, lost, perc, gameid=id)
t = format_time(time)
m = str(round(moves, 1))
writer.pstats(name, won+lost, won, lost, t, m, perc, gameid=id)
yield [name, won+lost, won, lost, t, m, perc, id]
tgames = tgames + 1
writer.nl()
won, lost = twon, tlost
if won + lost > 0:
if won > 0:
time = format_time(ttime/won)
moves = round(tmoves/won, 1)
time = format_time(ttime/tgames)
moves = round(tmoves/tgames, 1)
else:
time = format_time(0)
moves = 0
perc = "%.1f" % (100.0*won/(won+lost))
else: perc = "0.0"
writer.pstats(_("Total (%d out of %d games)") % (tgames, len(g)),
won+lost, won, lost, time, moves, perc)
writer.nl(2)
return tgames
self.total_games = len(g)
self.played_games = tgames
self.won_games = won
self.lost_games = lost
self.avrg_time = time
self.avrg_moves = moves
self.percent = perc
#yield (_("Total (%d out of %d games)") % (tgames, len(g)),
# won+lost, won, lost, time, moves, perc, '')
def _writeLog(self, writer, player, header, prev_games):
if not player or not prev_games:
return 0
self.writeHeader(writer, header, 71)
writer.plog(_("Game"), _("Game number"), _("Started at"), _("Status"))
writer.nl()
def getStatSummary(self):
return self.total_games, \
self.played_games, \
self.won_games, \
self.lost_games, \
self.avrg_time, \
self.avrg_moves, \
self.percent
def getLogHeader(self):
return _("Game"), _("Game number"), _("Started at"), _("Status")
def getLogResults(self, player, prev_games):
twon, tlost = 0, 0
for pg in prev_games:
if type(pg) is not types.TupleType:
@ -198,14 +157,88 @@ class PysolStatsFormatter:
status = "*error*"
if -2 <= pg[2] <= 2:
status = (_("Loaded"), _("Not won"), _("Lost"), _("Won"), _("Perfect")) [pg[2]+2]
writer.plog(name, gamenumber, date, status, gameid=gameid, won=pg[2])
writer.nl(2)
#writer.plog(name, gamenumber, date, status, gameid=gameid, won=pg[2])
yield [name, gamenumber, date, status, pg[2], gameid]
#
#
#
def writeStats(self, player, sort_by='name'):
pass
def writeFullLog(self, player):
pass
def writeSessionLog(self, player):
pass
class FileStatsFormatter(PysolStatsFormatter):
def __init__(self, app, file):
self.app = app
self.file = file
def p(self, s):
self.file.write(s.encode('utf-8'))
def nl(self, count=1):
self.p("\n" * count)
def pheader(self, s):
self.p(s)
def pstats(self, *args, **kwargs):
s = "%-30s %7s %7s %7s %7s %7s %7s\n" % args
self.p(s)
def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
self.p("%-25s %-20s %17s %s\n" % (gamename, gamenumber, date, status))
def writeHeader(self, header, pagewidth=72):
date = time.ctime(time.time())
date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()))
blanks = max(pagewidth - len(header) - len(date), 1)
self.pheader(header + " "*blanks + date + "\n")
self.pheader("-" * pagewidth + "\n")
self.pheader("\n")
def writeStats(self, player, sort_by='name'):
header = _("Statistics for ") + player
self.writeHeader(header, 62)
header = self.getStatHeader()
self.pstats(*header)
self.nl()
for result in self.getStatResults(player, sort_by):
gameid = result.pop()
self.pstats(gameid=gameid, *result)
self.nl()
total, played, won, lost, time, moves, perc = self.getStatSummary()
self.pstats(_("Total (%d out of %d games)") % (played, total),
won+lost, won, lost, time, moves, perc)
self.nl(2)
return played
def writeLog(self, player, header, prev_games):
if not player or not prev_games:
return 0
self.writeHeader(header, 71)
header = self.getLogHeader()
self.plog(*header)
self.nl()
for result in self.getLogResults(player, prev_games):
gameid = result.pop()
won = result.pop()
self.plog(gameid=gameid, won=won, *result)
self.nl(2)
return 1
def writeFullLog(self, writer, player, header):
def writeFullLog(self, player):
header = _("Full log for ") + player
prev_games = self.app.stats.prev_games.get(player)
return self._writeLog(writer, player, header, prev_games)
return self.writeLog(player, header, prev_games)
def writeSessionLog(self, writer, player, header):
def writeSessionLog(self, player):
header = _("Session log for ") + player
prev_games = self.app.stats.session_games.get(player)
return self._writeLog(writer, player, header, prev_games)
return self.writeLog(player, header, prev_games)

View file

@ -112,7 +112,8 @@ class PysolProgressBar:
return
self.percent = min(100, max(0, self.percent))
self.progress.config(value=self.percent)
self.top.update_idletasks()
##self.top.update_idletasks()
self.top.update()
# /***********************************************************************

View file

@ -54,7 +54,8 @@ __all__ = ['tkversion',
# imports
import sys, os
import Tile as Tkinter
import traceback
import Tkinter
# Toolkit imports
@ -73,6 +74,7 @@ try:
tkversion = tuple(m[:4])
del m
except:
traceback.print_exc()
pass
# experimental

View file

@ -80,12 +80,7 @@ class SingleGame_StatsDialog(MfxDialog):
self.top.wm_minsize(200, 200)
self.button = kw.default
#
##createChart = self.create3DBarChart
createChart = self.createPieChart
##createChart = self.createSimpleChart
## if parent.winfo_screenwidth() < 800 or parent.winfo_screenheight() < 600:
## createChart = self.createPieChart
## createChart = self.createSimpleChart
#
self.font = self.app.getFont("default")
self.tk_font = tkFont.Font(self.top, self.font)
@ -177,79 +172,6 @@ class SingleGame_StatsDialog(MfxDialog):
c.create_text(x, ty[1]-dy, text="%d%%" % (100-pw), anchor="ne", font=tfont, fill=fg)
## def _createChart3DBar(self, canvas, perc, x, y, p, col):
## if perc < 0.005:
## return
## # translate and scale
## p = list(p[:])
## for i in (0, 1, 2, 3):
## p[i] = (x + p[i][0], y + p[i][1])
## j = i + 4
## dx = int(round(p[j][0] * perc))
## dy = int(round(p[j][1] * perc))
## p[j] = (p[i][0] + dx, p[i][1] + dy)
## # draw rects
## def draw_rect(a, b, c, d, col, canvas=canvas, p=p):
## points = (p[a][0], p[a][1], p[b][0], p[b][1],
## p[c][0], p[c][1], p[d][0], p[d][1])
## canvas.create_polygon(points, fill=col)
## draw_rect(0, 1, 5, 4, col[0])
## draw_rect(1, 2, 6, 5, col[1])
## draw_rect(4, 5, 6, 7, col[2])
## # draw lines
## def draw_line(a, b, canvas=canvas, p=p):
## ##print a, b, p[a], p[b]
## canvas.create_line(p[a][0], p[a][1], p[b][0], p[b][1])
## draw_line(0, 1)
## draw_line(1, 2)
## draw_line(0, 4)
## draw_line(1, 5)
## draw_line(2, 6)
## ###draw_line(3, 7) ## test
## draw_line(4, 5)
## draw_line(5, 6)
## draw_line(6, 7)
## draw_line(7, 4)
#
# charts
#
## def createSimpleChart(self, app, won, lost, text):
## #c, tfont, fg = self._createChartInit(frame, 300, 100, text)
## self._createChartInit(300, 100, text)
## c, tfont, fg = self.canvas, self.font, self.fg
## #
## tx = (90, 180, 210)
## ty = (21, 41, 75)
## self._createChartTexts(tx, ty, won, lost)
## def create3DBarChart(self, app, won, lost, text):
## image = app.gimages.stats[0]
## iw, ih = image.width(), image.height()
## #c, tfont, fg = self._createChartInit(frame, iw+160, ih, text)
## self._createChartInit(iw+160, ih, text)
## c, tfont, fg = self.canvas, self.font, self.fg
## pwon, plost = self._getPwon(won, lost)
## #
## tx = (iw+20, iw+110, iw+140)
## yy = ih/2 ## + 7
## ty = (yy+21-46, yy+41-46, yy+75-46)
## #
## c.create_image(0, 7, image=image, anchor="nw")
## #
## p = ((0, 0), (44, 6), (62, -9), (20, -14),
## (-3, -118), (-1, -120), (-1, -114), (-4, -112))
## col = ("#00ff00", "#008200", "#00c300")
## self._createChart3DBar(c, pwon, 102, 145+7, p, col)
## p = ((0, 0), (49, 6), (61, -10), (15, -15),
## (1, -123), (3, -126), (4, -120), (1, -118))
## col = ("#ff0000", "#860400", "#c70400")
## self._createChart3DBar(c, plost, 216, 159+7, p, col)
## #
## self._createChartTexts(tx, ty, won, lost)
## c.create_text(tx[0], ty[0]-48, text=self.player, anchor="nw", font=tfont, fill=fg)
def createPieChart(self, app, won, lost, text):
#c, tfont, fg = self._createChartInit(frame, 300, 100, text)
@ -300,8 +222,11 @@ class SingleGame_StatsDialog(MfxDialog):
# //
# ************************************************************************/
class TreeWriter(PysolStatsFormatter.StringWriter):
def __init__(self, tree, parent_window, font, w, h):
class TreeFormatter(PysolStatsFormatter):
MAX_ROWS = 10000
def __init__(self, app, tree, parent_window, font, w, h):
self.app = app
self.tree = tree
self.parent_window = parent_window
self.font = font
@ -311,12 +236,6 @@ class TreeWriter(PysolStatsFormatter.StringWriter):
self.w = w
self.h = h
def p(self, s):
pass
def pheader(self, s):
pass
def _calc_tabs(self, arg):
if self.parent_window.tree_tabs:
self._tabs = self.parent_window.tree_tabs
@ -331,57 +250,73 @@ class TreeWriter(PysolStatsFormatter.StringWriter):
self._tabs.append(10)
self.parent_window.tree_tabs = self._tabs
def pstats(self, *args, **kwargs):
header = False
def writeStats(self, player, sort_by='name'):
header = self.getStatHeader()
if self._tabs is None:
# header
self._calc_tabs(args)
header = True
self._calc_tabs(header)
t1, t2, t3, t4, t5, t6, t7 = header
for column, text, anchor, tab in (
('#0', t1, 'nw', self._tabs[0]),
('played', t2, 'ne', self._tabs[1]),
('won', t3, 'ne', self._tabs[2]),
('lost', t4, 'ne', self._tabs[3]),
('time', t5, 'ne', self._tabs[4]),
('moves', t6, 'ne', self._tabs[5]),
('percent', t7, 'ne', self._tabs[6]), ):
self.tree.heading(column, text=text,
command=lambda par=self.parent_window, col=column: par.headerClick(col))
self.tree.column(column, width=tab)
t1, t2, t3, t4, t5, t6, t7 = args
if not header: t1=gettext(t1) # game name
if header:
for column, text, anchor, tab in (
('#0', t1, 'nw', self._tabs[0]),
('played', t2, 'ne', self._tabs[1]),
('won', t3, 'ne', self._tabs[2]),
('lost', t4, 'ne', self._tabs[3]),
('time', t5, 'ne', self._tabs[4]),
('moves', t6, 'ne', self._tabs[5]),
('percent', t7, 'ne', self._tabs[6]), ):
self.tree.heading(column, text=text,
command=lambda par=self.parent_window, col=column: par.headerClick(col))
self.tree.column(column, width=tab)
else:
for result in self.getStatResults(player, sort_by):
t1, t2, t3, t4, t5, t6, t7, t8 = result
t1=gettext(t1) # game name
id = self.tree.insert(None, "end", text=t1,
values=(t2, t3, t4, t5, t6, t7))
self.parent_window.tree_items.append(id)
def plog(self, *args, **kwargs):
header = False
total, played, won, lost, time, moves, perc = self.getStatSummary()
text = _("Total (%d out of %d games)") % (played, total)
id = self.tree.insert(None, "end", text=text,
values=(won+lost, won, lost, time, moves, perc))
self.parent_window.tree_items.append(id)
return 1
def writeLog(self, player, prev_games):
if self._tabs is None:
# header
self._calc_tabs(('', '99999999999999999999', '9999-99-99 99:99', 'XXXXXXXXXXXX'))
header = True
t1, t2, t3, t4 = args[:4]
if not header: t1=gettext(t1) # game name
if header:
for column, text, anchor, tab in (
('#0', t1, 'nw', self._tabs[0]),
('gamenumber', t2, 'ne', self._tabs[1]),
('date', t3, 'ne', self._tabs[2]),
('status', t4, 'ne', self._tabs[3]), ):
self.tree.heading(column, text=text,
command=lambda par=self.parent_window, col=column: par.headerClick(col))
self.tree.column(column, width=tab)
##if column in ('gamenumber', 'date', 'status'):
## self.tree.column(column, anchor='center')
else:
header = self.getLogHeader()
t1, t2, t3, t4 = header
for column, text, anchor, tab in (
('#0', t1, 'nw', self._tabs[0]),
('gamenumber', t2, 'ne', self._tabs[1]),
('date', t3, 'ne', self._tabs[2]),
('status', t4, 'ne', self._tabs[3]), ):
self.tree.heading(column, text=text,
command=lambda par=self.parent_window, col=column: par.headerClick(col))
self.tree.column(column, width=tab)
##if column in ('gamenumber', 'date', 'status'):
## self.tree.column(column, anchor='center')
if not player or not prev_games:
return 0
num_rows = 0
for result in self.getLogResults(player, prev_games):
t1, t2, t3, t4, t5, t6 = result
t1=gettext(t1) # game name
id = self.tree.insert(None, "end", text=t1, values=(t2, t3, t4))
self.parent_window.tree_items.append(id)
num_rows += 1
if num_rows > self.MAX_ROWS:
break
return 1
def writeFullLog(self, player):
prev_games = self.app.stats.prev_games.get(player)
return self.writeLog(player, prev_games)
def writeSessionLog(self, player):
prev_games = self.app.stats.session_games.get(player)
return self.writeLog(player, prev_games)
# /***********************************************************************
@ -467,14 +402,9 @@ class AllGames_StatsDialog(MfxDialog):
if self.tree_items:
self.tree.delete(tuple(self.tree_items))
self.tree_items = []
a = PysolStatsFormatter(self.app)
writer = TreeWriter(self.tree, self,
formatter = TreeFormatter(self.app, self.tree, self,
self.font, self.CHAR_W, self.CHAR_H)
if not a.writeStats(writer, player, header, sort_by=self.sort_by):
# FIXME
pass
destruct(writer)
destruct(a)
formatter.writeStats(player, sort_by=self.sort_by)
# /***********************************************************************
@ -487,13 +417,9 @@ class FullLog_StatsDialog(AllGames_StatsDialog):
COLUMNS = ('gamenumber', 'date', 'status')
def fillCanvas(self, player, header):
a = PysolStatsFormatter(self.app)
writer = TreeWriter(self.tree, self, self.font,
self.CHAR_W, self.CHAR_H)
if not a.writeFullLog(writer, player, header):
# FIXME
pass
destruct(a)
formatter = TreeFormatter(self.app, self.tree, self, self.font,
self.CHAR_W, self.CHAR_H)
formatter.writeFullLog(player)
def initKw(self, kw):
kw = KwStruct(kw,
@ -509,13 +435,9 @@ class FullLog_StatsDialog(AllGames_StatsDialog):
class SessionLog_StatsDialog(FullLog_StatsDialog):
def fillCanvas(self, player, header):
a = PysolStatsFormatter(self.app)
writer = TreeWriter(self.tree, self, self.font,
self.CHAR_W, self.CHAR_H)
if not a.writeSessionLog(writer, player, header):
# FIXME
pass
destruct(a)
formatter = TreeFormatter(self.app, self.tree, self, self.font,
self.CHAR_W, self.CHAR_H)
formatter.writeSessionLog(player)
def initKw(self, kw):
kw = KwStruct(kw,
@ -582,8 +504,7 @@ class _TopDialog(MfxDialog):
self.createBitmaps(top_frame, kw)
cnf = {'master': top_frame,
'highlightthickness': 1,
'highlightbackground': 'black',
'padding': (4, 1),
}
frame = apply(Tkinter.Frame, (), cnf)
frame.pack(expand=Tkinter.YES, fill=Tkinter.BOTH, padx=10, pady=10)
@ -654,9 +575,9 @@ class Top_StatsDialog(MfxDialog):
app.stats.games_stats[player].has_key(gameid) and
app.stats.games_stats[player][gameid].time_result.top):
Tkinter.Label(frame, text=_('Minimum')).grid(row=0, column=1)
Tkinter.Label(frame, text=_('Maximum')).grid(row=0, column=2)
Tkinter.Label(frame, text=_('Average')).grid(row=0, column=3)
Tkinter.Label(frame, text=_('Minimum')).grid(row=0, column=1, padx=4)
Tkinter.Label(frame, text=_('Maximum')).grid(row=0, column=2, padx=4)
Tkinter.Label(frame, text=_('Average')).grid(row=0, column=3, padx=4)
##Tkinter.Label(frame, text=_('Total')).grid(row=0, column=4)
s = app.stats.games_stats[player][gameid]

View file

@ -297,7 +297,9 @@ class MfxTreeInCanvas(MfxScrolledCanvas):
# set scroll region
bbox = self.canvas.bbox("all")
##self.canvas.config(scrollregion=bbox)
self.canvas.config(scrollregion=(0,0,bbox[2],bbox[3]))
##self.canvas.config(scrollregion=(0,0,bbox[2],bbox[3]))
dx, dy = 8, 0 # margins
self.canvas.config(scrollregion=(-dx,-dy,bbox[2]+dx,bbox[3]+dy))
self.canvas.config(yscrollincrement=self.style.disty)
def clear(self):

View file

@ -299,8 +299,9 @@ class SingleGame_StatsDialog(MfxDialog):
# //
# ************************************************************************/
class CanvasWriter(PysolStatsFormatter.StringWriter):
def __init__(self, canvas, parent_window, font, w, h):
class CanvasFormatter(PysolStatsFormatter):
def __init__(self, app, canvas, parent_window, font, w, h):
self.app = app
self.canvas = canvas
self.parent_window = parent_window
##self.fg = canvas.cget("insertbackground")
@ -308,7 +309,7 @@ class CanvasWriter(PysolStatsFormatter.StringWriter):
self.font = font
self.w = w
self.h = h
self.x = self.y = 0
#self.x = self.y = 0
self.gameid = None
self.gamenumber = None
self.canvas.config(yscrollincrement=h)
@ -317,26 +318,6 @@ class CanvasWriter(PysolStatsFormatter.StringWriter):
def _addItem(self, id):
self.canvas.dialog.nodes[id] = (self.gameid, self.gamenumber)
def p(self, s):
if self.y > 16000:
return
h1, h2 = 0, 0
while s and s[0] == "\n":
s = s[1:]
h1 = h1 + self.h
while s and s[-1] == "\n":
s = s[:-1]
h2 = h2 + self.h
self.y = self.y + h1
if s:
id = self.canvas.create_text(self.x, self.y, text=s, anchor="nw",
font=self.font, fill=self.fg)
self._addItem(id)
self.y = self.y + h2
def pheader(self, s):
pass
def _calc_tabs(self, arg):
tw = 15*self.w
##tw = 160
@ -347,59 +328,12 @@ class CanvasWriter(PysolStatsFormatter.StringWriter):
self._tabs.append(tw)
self._tabs.append(10)
def pstats(self, *args, **kwargs):
gameid=kwargs.get('gameid', None)
header = False
if self._tabs is None:
# header
header = True
self._calc_tabs(args)
self.gameid = 'header'
self.gamenumber = None
## if False:
## sort_by = ( 'name', 'played', 'won', 'lost',
## 'time', 'moves', 'percent', )
## frame = Tkinter.Frame(self.canvas)
## i = 0
## for t in args:
## w = self._tabs[i]
## if i == 0:
## w += 10
## b = Tkinter.Button(frame, text=t)
## b.grid(row=0, column=i, sticky='ew')
## b.bind('<1>', lambda e, f=self.parent_window.rearrange, s=sort_by[i]: f(s))
## frame.columnconfigure(i, minsize=w)
## i += 1
## self.canvas.create_window(0, 0, window=frame, anchor='nw')
## self.y += 20
## return
## if False:
## i = 0
## x = 0
## for t in args:
## w = self._tabs[i]
## h = 18
## anchor = 'ne'
## y = 0
## self.canvas.create_rectangle(x+2, y, x+w, y+h, width=1,
## fill="#00ff00", outline="#000000")
## x += w
## self.canvas.create_text(x-3, y+3, text=t, anchor=anchor)
## i += 1
## self.y += 20
## return
else:
self.gameid = gameid
self.gamenumber = None
if self.y > 16000:
return
x, y = 1, self.y
p = self._pstats_text
def pstats(self, y, args, gameid=None):
x = 1
t1, t2, t3, t4, t5, t6, t7 = args
h = 0
if not header: t1=gettext(t1) # game name
self.gamenumber = None
if gameid is None: # header
self.gameid = 'header'
for var, text, anchor, tab in (
('name', t1, 'nw', self._tabs[0]+self._tabs[1]),
('played', t2, 'ne', self._tabs[2]),
@ -408,46 +342,13 @@ class CanvasWriter(PysolStatsFormatter.StringWriter):
('time', t5, 'ne', self._tabs[5]),
('moves', t6, 'ne', self._tabs[6]),
('percent', t7, 'ne', self._tabs[7]), ):
if header: self.gamenumber=var
h = max(h, p(x, y, anchor=anchor, text=text))
if gameid is None: # header
self.gamenumber=var
id = self.canvas.create_text(x, y, text=text, anchor=anchor,
font=self.font, fill=self.fg)
self._addItem(id)
x += tab
self.pstats_perc(x, y, t7)
self.y += h
self.gameid = None
return
## h = max(h, p(x, y, anchor="nw", text=t1))
## if header: self.gamenumber='played'
## x += self._tabs[0]+self._tabs[1]
## h = max(h, p(x, y, anchor="ne", text=t2))
## if header: self.gamenumber='won'
## x += self._tabs[2]
## h = max(h, p(x, y, anchor="ne", text=t3))
## if header: self.gamenumber='lost'
## x += self._tabs[3]
## h = max(h, p(x, y, anchor="ne", text=t4))
## if header: self.gamenumber='time'
## x += self._tabs[4]
## h = max(h, p(x, y, anchor="ne", text=t5))
## if header: self.gamenumber='moves'
## x += self._tabs[5]
## h = max(h, p(x, y, anchor="ne", text=t6))
## if header: self.gamenumber='percent'
## x += self._tabs[6]
## h = max(h, p(x, y, anchor="ne", text=t7))
## x += self._tabs[7]
## self.pstats_perc(x, y, t7)
## self.y += h
## self.gameid = None
def _pstats_text(self, x, y, **kw):
kwdefault(kw, font=self.font, fill=self.fg)
id = apply(self.canvas.create_text, (x, y), kw)
self._addItem(id)
return self.h
##bbox = self.canvas.bbox(id)
##return bbox[3] - bbox[1]
def pstats_perc(self, x, y, t):
if not (t and "0" <= t[0] <= "9"):
@ -498,13 +399,51 @@ class CanvasWriter(PysolStatsFormatter.StringWriter):
ix = ix + 8
p = max(0.0, p - 0.1)
def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
if gameid > 0 and "0" <= gamenumber[0:1] <= "9":
self.gameid = gameid
self.gamenumber = gamenumber
self.p("%-25s %-20s %17s %s\n" % (gamename, gamenumber, date, status))
self.gameid = None
self.gamenumber = None
def writeStats(self, player, sort_by='name'):
header = self.getStatHeader()
y = 0
if self._tabs is None:
self._calc_tabs(header)
self.pstats(y, header)
#
y += 2*self.h
for result in self.getStatResults(player, sort_by):
gameid = result.pop()
result[0]=gettext(result[0]) # game name
self.pstats(y, result, gameid)
y += self.h
#
y += self.h
total, played, won, lost, time, moves, perc = self.getStatSummary()
s = _("Total (%d out of %d games)") % (played, total)
self.pstats(y, (s, won+lost, won, lost, time, moves, perc))
def writeLog(self, player, prev_games):
y = 0
header = self.getLogHeader()
t1, t2, t3, t4 = header
s = "%-25s %-20s %-17s %s" % header
id = self.canvas.create_text(1, y, text=s, anchor="nw",
font=self.font, fill=self.fg)
self._addItem(id)
y += 2*self.h
if not player or not prev_games:
return 0
for result in self.getLogResults(player, prev_games):
result[0]=gettext(result[0]) # game name
s = "%-25s %-20s %-17s %s" % tuple(result[:4])
id = self.canvas.create_text(1, y, text=s, anchor="nw",
font=self.font, fill=self.fg)
y += self.h
return 1
def writeFullLog(self, player):
prev_games = self.app.stats.prev_games.get(player)
return self.writeLog(player, prev_games)
def writeSessionLog(self, player):
prev_games = self.app.stats.session_games.get(player)
return self.writeLog(player, prev_games)
# /***********************************************************************
@ -617,14 +556,9 @@ class AllGames_StatsDialog(MfxDialog):
def fillCanvas(self, player, header):
self.canvas.delete('all')
self.nodes = {}
a = PysolStatsFormatter(self.app)
#print 'CHAR_W:', self.CHAR_W
writer = CanvasWriter(self.canvas, self,
writer = CanvasFormatter(self.app, self.canvas, self,
self.font, self.CHAR_W, self.CHAR_H)
if not a.writeStats(writer, player, header, sort_by=self.sort_by):
writer.p(_("No entries for player ") + player + "\n")
destruct(writer)
destruct(a)
writer.writeStats(player, self.sort_by)
# /***********************************************************************
@ -636,11 +570,9 @@ class FullLog_StatsDialog(AllGames_StatsDialog):
FONT_TYPE = "fixed"
def fillCanvas(self, player, header):
a = PysolStatsFormatter(self.app)
writer = CanvasWriter(self.canvas, self, self.font, self.CHAR_W, self.CHAR_H)
if not a.writeFullLog(writer, player, header):
writer.p(_("No log entries for %s\n") % player)
destruct(a)
writer = CanvasFormatter(self.app, self.canvas, self,
self.font, self.CHAR_W, self.CHAR_H)
writer.writeFullLog(player)
def initKw(self, kw):
kw = KwStruct(kw,
@ -652,11 +584,10 @@ class FullLog_StatsDialog(AllGames_StatsDialog):
class SessionLog_StatsDialog(FullLog_StatsDialog):
def fillCanvas(self, player, header):
a = PysolStatsFormatter(self.app)
writer = CanvasWriter(self.canvas, self, self.font, self.CHAR_W, self.CHAR_H)
if not a.writeSessionLog(writer, player, header):
writer.p(_("No current session log entries for %s\n") % player)
destruct(a)
a = PysolStatsFormatter()
writer = CanvasFormatter(self.app, self.canvas, self,
self.font, self.CHAR_W, self.CHAR_H)
writer.writeSessionLog(player)
def initKw(self, kw):
kw = KwStruct(kw,