## vim:ts=4:et:nowrap ## ##---------------------------------------------------------------------------## ## ## PySol -- a Python Solitaire game ## ## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; see the file COPYING. ## If not, write to the Free Software Foundation, Inc., ## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## ## Markus F.X.J. Oberhumer ## ## http://wildsau.idv.uni-linz.ac.at/mfx/pysol.html ## ##---------------------------------------------------------------------------## # imports import os, sys, time import gtk, gobject, pango import gtk.glade # PySol imports from pysollib.mfxutil import format_time from pysollib.settings import TOP_TITLE from pysollib.stats import PysolStatsFormatter # Toolkit imports from tkwidget import MfxDialog, MfxMessageDialog glade_file = os.path.join(sys.path[0], 'data', 'pysolfc.glade') open(glade_file) # /*********************************************************************** # // # ************************************************************************/ class StatsWriter(PysolStatsFormatter.StringWriter): def __init__(self, store): 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 iter = self.store.append(None) self.store.set(iter, 0, args[0], 1, args[1], 2, args[2], 3, args[3], 4, args[4], 5, args[5], 6, args[6], 7, gameid) class FullLogWriter(PysolStatsFormatter.StringWriter): def __init__(self, store): self.store = store def p(self, s): pass def pheader(self, s): pass def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1): if gameid < 0: # header return iter = self.store.append(None) self.store.set(iter, 0, gamename, 1, gamenumber, 2, date, 3, status, 4, gameid) class Game_StatsDialog: def __init__(self, parent, header, app, player, gameid): # self.app = app formatter = PysolStatsFormatter(self.app) # self.widgets_tree = gtk.glade.XML(glade_file) #game_name_combo = self.widgets_tree.get_widget('game_name_combo') #model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT) #game_name_combo.set_model(model) #game_name_combo.set_text_column(0) stats_dialog = self.widgets_tree.get_widget('stats_dialog') stats_dialog.set_title('Game Statistics') stats_dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT) # total won, lost = app.stats.getStats(player, gameid) self._createText('total', won, lost) drawing = self.widgets_tree.get_widget('total_drawingarea') drawing.connect('expose_event', self._createChart, won, lost) # current session won, lost = app.stats.getSessionStats(player, gameid) self._createText('current', won, lost) drawing = self.widgets_tree.get_widget('session_drawingarea') drawing.connect('expose_event', self._createChart, won, lost) # store = self._createStatsList() writer = StatsWriter(store) formatter.writeStats(writer, player, header, sort_by='name') # store = self._createLogList('full_log_treeview') writer = FullLogWriter(store) formatter.writeFullLog(writer, player, header) # store = self._createLogList('session_log_treeview') writer = FullLogWriter(store) formatter.writeSessionLog(writer, player, header) # stats_dialog.set_transient_for(parent) stats_dialog.resize(400, 300) stats_dialog.run() self.status = -1 stats_dialog.destroy() def _createText(self, name, won, lost): pwon, plost = self._getPwon(won, lost) label = self.widgets_tree.get_widget(name+'_num_won_label') label.set_text(str(won)) label = self.widgets_tree.get_widget(name+'_num_lost_label') label.set_text(str(lost)) label = self.widgets_tree.get_widget(name+'_percent_won_label') label.set_text(str(int(round(pwon*100)))+'%') label = self.widgets_tree.get_widget(name+'_percent_lost_label') label.set_text(str(int(round(plost*100)))+'%') label = self.widgets_tree.get_widget(name+'_num_total_label') label.set_text(str(won+lost)) def _createChart(self, drawing, e, won, lost): pwon, plost = self._getPwon(won, lost) s, ewon, elost = 0, int(360.0*pwon), int(360.0*plost) win = drawing.window colormap = drawing.get_colormap() gc = win.new_gc() gc.set_colormap(colormap) alloc = drawing.allocation width, height = alloc.width, alloc.height w, h = 90, 50 ##x, y = 10, 10 x, y = (width-w)/2, (height-h)/2 dy = 9 y = y-dy/2 if won+lost > 0: gc.set_rgb_fg_color(colormap.alloc_color('#007f00')) win.draw_arc(gc, True, x, y+dy, w, h, s*64, ewon*64) gc.set_rgb_fg_color(colormap.alloc_color('#7f0000')) win.draw_arc(gc, True, x, y+dy, w, h, (s+ewon)*64, elost*64) gc.set_rgb_fg_color(colormap.alloc_color('#00ff00')) win.draw_arc(gc, True, x, y, w, h, s*64, ewon*64) gc.set_rgb_fg_color(colormap.alloc_color('#ff0000')) win.draw_arc(gc, True, x, y, w, h, (s+ewon)*64, elost*64) else: gc.set_rgb_fg_color(colormap.alloc_color('#7f7f7f')) win.draw_arc(gc, True, x, y+dy, w, h, 0, 360*64) gc.set_rgb_fg_color(colormap.alloc_color('#f0f0f0')) win.draw_arc(gc, True, x, y, w, h, 0, 360*64) gc.set_rgb_fg_color(colormap.alloc_color('#bfbfbf')) pangolayout = drawing.create_pango_layout('No games') ext = pangolayout.get_extents() tw, th = ext[1][2]/pango.SCALE, ext[1][3]/pango.SCALE win.draw_layout( gc, x+w/2-tw/2, y+h/2-th/2, pangolayout) def _createStatsList(self): treeview = self.widgets_tree.get_widget('all_games_treeview') n = 0 for label in ( '', _('Played'), _('Won'), _('Lost'), _('Playing time'), _('Moves'), _('% won'), ): column = gtk.TreeViewColumn(label, gtk.CellRendererText(), text=n) column.set_resizable(True) column.set_sort_column_id(n) treeview.append_column(column) n += 1 # store = gtk.ListStore(gobject.TYPE_STRING, # name gobject.TYPE_INT, # played gobject.TYPE_INT, # won gobject.TYPE_INT, # lost gobject.TYPE_STRING, # playing time gobject.TYPE_STRING, # moves gobject.TYPE_STRING, # % won gobject.TYPE_INT, # gameid ) sortable = gtk.TreeModelSort(store) treeview.set_model(sortable) sortable.set_sort_func(4, self._cmpPlayingTime) sortable.set_sort_func(5, self._cmpMoves) sortable.set_sort_func(6, self._cmpPercent) return store def _createLogList(self, name): # treeview = self.widgets_tree.get_widget(name) n = 0 for label in ( _('Game'), _('Game number'), _('Started at'), _('Status'), ): column = gtk.TreeViewColumn(label, gtk.CellRendererText(), text=n) column.set_resizable(True) column.set_sort_column_id(n) treeview.append_column(column) n += 1 # store = gtk.ListStore(gobject.TYPE_STRING, # game name gobject.TYPE_STRING, # game number gobject.TYPE_STRING, # started at gobject.TYPE_STRING, # status gobject.TYPE_INT, # gameid ) treeview.set_model(store) return store def _getPwon(self, won, lost): pwon, plost = 0.0, 0.0 if won + lost > 0: pwon = float(won) / (won + lost) pwon = min(max(pwon, 0.00001), 0.99999) plost = 1.0 - pwon return pwon, plost def _cmpPlayingTime(self, store, iter1, iter2): val1 = store.get_value(iter1, 4) val2 = store.get_value(iter2, 4) t1 = map(int, val1.split(':')) t2 = map(int, val2.split(':')) return cmp(len(t1), len(t2)) or cmp(t1, t2) def _cmpMoves(self, store, iter1, iter2): val1 = store.get_value(iter1, 5) val2 = store.get_value(iter2, 5) return cmp(float(val1), float(val2)) def _cmpPercent(self, store, iter1, iter2): val1 = store.get_value(iter1, 6) val2 = store.get_value(iter2, 6) return cmp(float(val1), float(val2)) # /*********************************************************************** # // # ************************************************************************/ SingleGame_StatsDialog = Game_StatsDialog class AllGames_StatsDialog(MfxDialog): pass class FullLog_StatsDialog(AllGames_StatsDialog): pass class SessionLog_StatsDialog(FullLog_StatsDialog): pass # /*********************************************************************** # // # ************************************************************************/ class Status_StatsDialog(MfxMessageDialog): #MfxDialog def __init__(self, parent, game): stats, gstats = game.stats, game.gstats w1 = w2 = '' n = 0 for s in game.s.foundations: n = n + len(s.cards) w1 = (_('Highlight piles: ') + str(stats.highlight_piles) + '\n' + _('Highlight cards: ') + str(stats.highlight_cards) + '\n' + _('Highlight same rank: ') + str(stats.highlight_samerank) + '\n') if game.s.talon: if game.gameinfo.redeals != 0: w2 = w2 + _('\nRedeals: ') + str(game.s.talon.round - 1) w2 = w2 + _('\nCards in Talon: ') + str(len(game.s.talon.cards)) if game.s.waste and game.s.waste not in game.s.foundations: w2 = w2 + _('\nCards in Waste: ') + str(len(game.s.waste.cards)) if game.s.foundations: w2 = w2 + _('\nCards in Foundations: ') + str(n) # date = time.strftime('%Y-%m-%d %H:%M', time.localtime(game.gstats.start_time)) MfxMessageDialog.__init__(self, parent, title=_('Game status'), text=game.getTitleName() + '\n' + game.getGameNumber(format=1) + '\n' + _('Playing time: ') + game.getTime() + '\n' + _('Started at: ') + date + '\n\n'+ _('Moves: ') + str(game.moves.index) + '\n' + _('Undo moves: ') + str(stats.undo_moves) + '\n' + _('Bookmark moves: ') + str(gstats.goto_bookmark_moves) + '\n' + _('Demo moves: ') + str(stats.demo_moves) + '\n' + _('Total player moves: ') + str(stats.player_moves) + '\n' + _('Total moves in this game: ') + str(stats.total_moves) + '\n' + _('Hints: ') + str(stats.hints) + '\n' + '\n' + w1 + w2, strings=(_('&OK'), (_('&Statistics...'), 101), (TOP_TITLE+'...', 105), ), image=game.app.gimages.logos[3], image_side='left', image_padx=20, padx=20, ) class Top_StatsDialog(MfxDialog): pass