|
From: <umg...@us...> - 2007-08-31 13:45:22
|
Revision: 500
http://pybridge.svn.sourceforge.net/pybridge/?rev=500&view=rev
Author: umgangee
Date: 2007-08-31 06:45:20 -0700 (Fri, 31 Aug 2007)
Log Message:
-----------
Refactor rubber scoring, to facilitate rubber scoresheet display.
Modified Paths:
--------------
trunk/pybridge/pybridge/games/bridge/game.py
trunk/pybridge/pybridge/games/bridge/result.py
trunk/pybridge/pybridge/games/bridge/ui/window_bridgetable.py
Added Paths:
-----------
trunk/pybridge/pybridge/games/bridge/ui/window_scoresheet.py
Modified: trunk/pybridge/pybridge/games/bridge/game.py
===================================================================
--- trunk/pybridge/pybridge/games/bridge/game.py 2007-08-03 18:42:14 UTC (rev 499)
+++ trunk/pybridge/pybridge/games/bridge/game.py 2007-08-31 13:45:20 UTC (rev 500)
@@ -97,14 +97,14 @@
if len(self.rubbers) == 0 or self.rubbers[-1].winner:
self.board['vuln'] = Vulnerable.None # First round, new rubber.
else:
- games = self.rubbers[-1].games
- if len(games[(Direction.North, Direction.South)]) > 0:
- if len(games[(Direction.East, Direction.West)]) > 0:
+ pairs = [pair for game, pair in self.rubbers[-1].games]
+ if pairs.count((Direction.North, Direction.South)) > 0:
+ if pairs.count((Direction.East, Direction.West)) > 0:
self.board['vuln'] = Vulnerable.All
else:
self.board['vuln'] = Vulnerable.NorthSouth
else:
- if len(games[(Direction.East, Direction.West)]) > 0:
+ if pairs.count((Direction.East, Direction.West)) > 0:
self.board['vuln'] = Vulnerable.EastWest
else:
self.board['vuln'] = Vulnerable.None
Modified: trunk/pybridge/pybridge/games/bridge/result.py
===================================================================
--- trunk/pybridge/pybridge/games/bridge/result.py 2007-08-03 18:42:14 UTC (rev 499)
+++ trunk/pybridge/pybridge/games/bridge/result.py 2007-08-31 13:45:20 UTC (rev 500)
@@ -233,40 +233,41 @@
def _getGames(self):
- """Returns, for each pair, a list of completed 'games' won by the pair
- in this rubber.
+ """Returns a list of completed (ie. won) 'games' in this rubber, in the
+ order of their completion.
- A game is represented as the list of consecutive results in this rubber,
- with below-the-line scores that count towards the game.
+ A game is represented as a list of consecutive results from this rubber,
+ coupled with the identifier of the scoring pair.
"""
- gamesNS, gamesEW = [], []
+ games = []
- game = []
- belowNS, belowEW = 0, 0 # Cumulative totals for results.
+ thisgame = []
+ belowNS, belowEW = 0, 0 # Cumulative totals for results in this game.
+
for result in self:
- game.append(result)
-
+ thisgame.append(result)
if result.contract.declarer in (Direction.North, Direction.South):
belowNS += result.score[1]
if belowNS >= 100:
- gamesNS.append(game)
+ games.append((thisgame, (Direction.North, Direction.South)))
else:
belowEW += result.score[1]
if belowEW >= 100:
- gamesEW.append(game)
+ games.append((thisgame, (Direction.East, Direction.West)))
- # If either accumulated total exceeds 100, proceed to next game.
- if belowNS >= 100 or belowEW >= 100:
- game = []
- belowNS, belowEW = 0, 0
+ # If either total for this game exceeds 100, proceed to next game.
+ if belowNS >= 100 or belowEW >= 100:
+ thisgame = []
+ belowNS, belowEW = 0, 0 # Reset accumulators.
- return {(Direction.North, Direction.South): gamesNS,
- (Direction.East, Direction.West): gamesEW}
+ return games
def _getWinner(self):
"""The rubber is won by the pair which have completed two games."""
- for pair, games in self.games.items():
- if len(games) >= 2:
+ pairs = [pair for game, pair in self.games]
+
+ for pair in ((Direction.North, Direction.South), (Direction.East, Direction.West)):
+ if pairs.count(pair) >= 2:
return pair
Modified: trunk/pybridge/pybridge/games/bridge/ui/window_bridgetable.py
===================================================================
--- trunk/pybridge/pybridge/games/bridge/ui/window_bridgetable.py 2007-08-03 18:42:14 UTC (rev 499)
+++ trunk/pybridge/pybridge/games/bridge/ui/window_bridgetable.py 2007-08-31 13:45:20 UTC (rev 500)
@@ -29,6 +29,7 @@
from pybridge.ui.window_gametable import WindowGameTable
from window_bidbox import WindowBidbox
+from window_scoresheet import ScoreSheet
class BiddingView(gtk.TreeView):
@@ -83,41 +84,6 @@
-class ScoreView(gtk.TreeView):
- """A display of contracts bid, their results and their scores."""
-
-
- def __init__(self):
- gtk.TreeView.__init__(self)
- self.set_rules_hint(True)
-
- self.store = gtk.ListStore(str, str, str, str)
- self.set_model(self.store)
- self.clear = self.store.clear
- renderer = gtk.CellRendererText()
-
- for index, title in enumerate([_('Contract'), _('Made'), _('N/S'), _('E/W')]):
- column = gtk.TreeViewColumn(title, renderer, markup=index)
- self.append_column(column)
-
-
- def add_score(self, game):
- declarerWon, defenceWon = game.play.wonTrickCount()
- score = game.result.score
-
- textContract = render_contract(game.contract)
- textMade = str(declarerWon)
- if game.contract.declarer in (Direction.North, Direction.South) and score > 0 \
- or game.contract.declarer in (Direction.East, Direction.West) and score < 0:
- textNS, textEW = str(abs(score)), ''
- else:
- textNS, textEW = '', str(abs(score))
-
- self.store.prepend([textContract, textMade, textNS, textEW])
-
-
-
-
class BridgeDashboard(gtk.VBox):
"""An at-a-glance display of the state of a bridge game."""
@@ -242,7 +208,7 @@
exp = gtk.Expander(_('Bidding'))
exp.set_expanded(True)
exp.add(frame)
- self.sidebar.pack_start(exp)
+ self.sidebar.pack_start(exp, expand=True)
self.trickarea = TrickArea(positions=Direction)
self.trickarea.set_size_request(-1, 180)
@@ -253,10 +219,10 @@
exp.add(frame)
self.sidebar.pack_start(exp, expand=False)
- self.scoreview = ScoreView()
+ self.scoresheet = ScoreSheet()
sw = gtk.ScrolledWindow()
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- sw.add(self.scoreview)
+ sw.add(self.scoresheet)
frame = gtk.Frame()
frame.add(sw)
exp = gtk.Expander(_('Score Sheet'))
@@ -265,11 +231,6 @@
self.sidebar.pack_start(exp, expand=False)
- def errback(self, failure):
- print "Error: %s" % failure.getErrorMessage()
- print failure.getBriefTraceback()
-
-
def setTable(self, table):
"""Changes display to match the table specified.
@@ -337,12 +298,11 @@
# Determine and display score in dialog box and score sheet.
if self.table.game.contract:
- self.scoreview.add_score(self.table.game)
+ self.scoresheet.add_result(self.table.game.result)
tricksMade = self.table.game.result.tricksMade
tricksRequired = self.table.game.contract.bid.level.index + 7
offset = tricksMade - tricksRequired
- score = self.table.game.result.score
fields = {'contract': render_contract(self.table.game.contract),
'offset': abs(offset)}
@@ -359,6 +319,10 @@
else:
resultText = _('Contract %(contract)s made exactly.') % fields
+ score = self.table.game.result.score
+ if isinstance(score, tuple): # Rubber scoring.
+ score = sum(score) # TODO: display above, below separately.
+
pair = (score >= 0 and _('declarer')) or _('defence')
scoreText = _('Score %(points)s points for %(pair)s.') % {'points': abs(score), 'pair': pair}
Added: trunk/pybridge/pybridge/games/bridge/ui/window_scoresheet.py
===================================================================
--- trunk/pybridge/pybridge/games/bridge/ui/window_scoresheet.py (rev 0)
+++ trunk/pybridge/pybridge/games/bridge/ui/window_scoresheet.py 2007-08-31 13:45:20 UTC (rev 500)
@@ -0,0 +1,140 @@
+# PyBridge -- online contract bridge made easy.
+# Copyright (C) 2004-2007 PyBridge Project.
+#
+# 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; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+import gtk
+
+from pybridge.games.bridge.result import DuplicateResult, RubberResult
+from pybridge.games.bridge.symbols import Direction
+
+from pybridge.ui.eventhandler import SimpleEventHandler
+import pybridge.ui.vocabulary as voc
+
+
+class ScoreSheet(gtk.TreeView):
+ """A score sheet widget, which presents GameResult information."""
+
+ # TODO: display total scores for N/S and E/W.
+
+
+ def __init__(self):
+ gtk.TreeView.__init__(self)
+ self.set_rules_hint(True)
+
+ self.store = gtk.ListStore(int, str, str, str, str)
+ self.set_model(self.store)
+
+ renderer = gtk.CellRendererText()
+ for index, title in enumerate([_('Board'), _('Contract'), _('Made'), _('N/S'), _('E/W')]):
+ column = gtk.TreeViewColumn(title, renderer, markup=index)
+ self.append_column(column)
+
+
+ def add_result(self, result):
+ if isinstance(result, RubberResult):
+ # Rubber results are split into 'above' and 'below' scores.
+ score = sum(result.score)
+ else:
+ score = result.score
+
+ if result.contract is None: # Bidding passed out.
+ row = (result.board['num'], _('Passed out'), '-', '-', '', '')
+
+ else:
+ if result.contract.declarer in (Direction.North, Direction.South) and score > 0 \
+ or result.contract.declarer in (Direction.East, Direction.West) and score < 0:
+ scoreNS, scoreEW = str(abs(score)), ''
+ else:
+ scoreNS, scoreEW = '', str(abs(score))
+
+ row = (result.board['num'], voc.render_contract(result.contract),
+ #voc.DIRECTION_NAMES[result.contract.declarer],
+ str(result.tricksMade), scoreNS, scoreEW)
+
+ self.store.append(row)
+
+
+
+
+class RubberScoreSheet(gtk.TreeView):
+ """A score sheet widget, which presents a Rubber object."""
+
+
+ def __init__(self):
+ gtk.TreeView.__init__(self)
+ self.set_rules_hint(True)
+ self.set_row_separator_func(self._row_separator)
+
+ # Set bool field in a row to display as separator.
+ self.store = gtk.ListStore(str, str, bool)
+ self.set_model(self.store)
+
+ renderer = gtk.CellRendererText()
+ for index, title in enumerate([_('N/S'), _('E/W')]):
+ column = gtk.TreeViewColumn(title, renderer, markup=index)
+ self.append_column(column)
+
+
+ def set_rubber(self, rubber):
+ self.store.clear()
+ self.store.append(('', '', True)) # The initial dividing line.
+
+ for game, pair in rubber.games:
+ #aboveiters, belowiters = [], []
+ for result in rubber:
+ above, below = result.score
+ if result.contract.declarer in (Direction.North, Direction.South) and below > 0 \
+ or result.contract.declarer in (Direction.East, Direction.West) and score < 0:
+ self.store.prepend((str(above), '', False))
+ self.store.append((str(below), '', False))
+ else:
+ self.store.prepend(('', str(above), False))
+ self.store.append(('', str(below), False))
+
+
+ def _row_separator(self, model, iter, data):
+ print model, iter, data
+ return True
+
+
+
+
+class WindowScoreSheet(object):
+ """"""
+
+
+ def __init__(self, parent=None):
+ self.window = gtk.Window()
+ if parent:
+ self.window.set_transient_for(parent.window)
+ self.window.set_title(_('Score Sheet'))
+ self.window.connect('delete_event', self.on_delete_event)
+ #self.window.set_resizable(False)
+
+ self.eventHandler = SimpleEventHandler(self)
+ self.table = None
+
+
+ def tearDown(self):
+ pass
+
+
+
+ def on_delete_event(self, widget, *args):
+ # TODO: call wm.close(self)
+ return True # Stops window deletion taking place.
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|