def __init__(self, placeholder, round): Chart.__init__(self, placeholder) self.chart.type = 'column' self.title.text = '' self.xAxis.categories = ["Trick %d" % (i + 1) for i in range(13)] # self.yAxis = [ # {'title': {'text': 'Tricks'}, 'min': 0, 'max': 13, 'tickInterval': 1}, # {'title': {'text': 'Bids'}, 'opposite': True, 'min': 0, 'max': 13}, # ] with self.yAxis as axis: axis.title.text = 'Tricks' axis.min = 0 axis.max = 13 axis.tickInterval = 1 axis.plotLines = plotLines = [] clrs = ['red', 'green'] import sys for team in round.game.teams: plotLines.append({ 'label': {'text': annotatedTeamName(round.game, team)}, 'width': 2, 'color': clrs.pop(0), 'value': sum(bidValue(round.bidsByPlayer.get(player, 0)) for player in team), }) if plotLines[0]['value'] == plotLines[1]['value']: plotLines[0]['label']['text'] = 'Both teams' plotLines.pop(1) self.tooltip.enabled = False self.plotOptions.column.stacking = 'normal' # Not sure if there's a nice use for flags # Was planning to mark when players made their bid, but it doesn't look good and the team bids are obvious from the plotlines # flagSeries = { # 'type': 'flags', # 'data': [], # 'color': '#4572a7', # 'shape': 'flag', # 'onSeries': '', # 'showInLegend': False, # 'shape': 'squarepin', # } winners = [trick.winner if trick else None for trick in round.tricks] taken = {player: [0] for player in round.game.players} for winner in winners: for player, l in taken.iteritems(): l.append(l[-1] + (1 if player == winner else 0)) for l in taken.values(): l.pop(0) self.series = [{ 'name': player, 'stack': "Team %d" % (i%2 + 1), 'color': "#%02x%02x%02x" % getPlayerColor(player), 'data': taken[player], } for i, player in enumerate(round.game.players)]
def printResults(round, team): game = round.game bid = sum(bidValue(round.bidsByPlayer[player]) for player in team) taken = sum(len(round.tricksByWinner[player]) for player in team) if taken >= bid: change = 10 * bid print "<li>%s bid %d, made it with %d (+%d)" % (annotatedTeamName(game, team), bid, taken, 10 * bid) print "<ul>" if taken > bid: change += taken - bid prevBags = sum(r.bags[team] for r in round.previousRounds) % game.bagLimit print "<li>Took %s, up to %d (+%d)</li>" % (pluralize(taken - bid, 'bag', 'bags'), prevBags + taken - bid, taken - bid) if prevBags + taken - bid >= game.bagLimit: change -= 10 * game.bagLimit print "<li>Bagged out (-%d)</li>" % (10 * game.bagLimit) else: change = -10 * bid print "<li>%s bid %d, set with %d (-%d)" % (annotatedTeamName(game, team), bid, taken, 10 * bid) print "<ul>" for player in team: bid = round.bidsByPlayer[player] if bid in ('nil', 'blind'): playerTaken = len(round.tricksByWinner[player]) desc = 'blind nil' if bid == 'blind' else 'nil' thisChange = 10 * game.bagLimit * (2 if bid == 'blind' else 1) * (1 if playerTaken == 0 else -1) if playerTaken == 0: print "<li>%s made %s (%d)</li>" % (player, desc, thisChange) else: print "<li>%s took %d, failed %s (%d)" % (player, playerTaken, desc, thisChange) change += thisChange if change == 0: print "<li>No score change, still at %d points</li>" % round.score[team] else: print "<li>%s %s, %s to %d</li>" % (('Gained' if change > 0 else 'Lost'), pluralize(abs(change), 'point', 'points'), ('up' if change > 0 else 'down'), round.score[team]) print "</ul></li>"
def player(handler, player, q = None): handler.title(player) handler.callFromHeader(Chart.include) allGames = getGames().values() games = filter(lambda game: player in game.players, allGames) if len(games) == 0: ErrorBox.die("Player not found", "No player named <b>%s</b> has played in a recorded game" % clean(player)) print "<img class=\"avatar\" src=\"/players/%s/avatar\">" % player if q is not None: print WarningBox("Ignoring query (unimplemented): <b>%s</b>" % clean(q)) counts = OrderedDict((cat, 0) for cat in ('games', 'rounds', 'tricks', 'nils', 'blind_nils', 'nil_defenses')) wins = {cat: 0 for cat in counts} cards = {card: 0 for card in ordering} leads = {card: 0 for card in ordering} for game in games: if game.finished: counts['games'] += 1 if player in (game.winner or []): wins['games'] += 1 partner = game.partners[player] for round in game.rounds: if not round.finished: continue counts['rounds'] += 1 bid = round.bidsByPlayer[player] partnerBid = round.bidsByPlayer[partner] taken, partnerTaken = 0, 0 for trick in round.tricks: if trick is not None: counts['tricks'] += 1 play = trick.playsByPlayer[player] if play is not None: cards[play] += 1 if trick.leader == player: leads[play] += 1 if trick.winner == player: taken += 1 wins['tricks'] += 1 elif trick.winner == partner: partnerTaken += 1 # "Won" if player's nil was successful or the player didn't go nil and the team made their bid if bid in ('nil', 'blind'): cat = {'nil': 'nils', 'blind': 'blind_nils'}[bid] counts[cat] += 1 if taken == 0: wins[cat] += 1 wins['rounds'] += 1 elif taken + partnerTaken >= bid + bidValue(partnerBid): wins['rounds'] += 1 if partnerBid in ('nil', 'blind'): counts['nil_defenses'] += 1 if partnerTaken == 0: wins['nil_defenses'] += 1 print "<a name=\"counts\"/>" print "<h2><a href=\"#counts\">Counts</a></h2>" print "A round counts as a win if you bid nil and make it, or bid non-nil and don't go bust. A trick counts as a win only when you take it. Never let your partner win tricks, it hurts your stats.<br><br>" print "<table class=\"counts\">" for cat, count in counts.iteritems(): print "<tr>" print "<td>" if cat == 'games': print "<img data-toggle=\"game-list\" src=\"/static/images/expand.png\"> ", print "%s" % ' '.join(word.title() for word in cat.split('_')) print "</td>" print "<td class=\"progresscell\">" print ProgressBar(wins[cat], count) if cat == 'games': print "<table id=\"game-list\">" print "<tr><th>Result</th><th>Opponent</th><th>Score</th><th>When</th><th> </th></tr>" for game in sorted(games, key = lambda game: game.end or datetime.now()): if not game.finished: continue name = os.path.splitext(game.logFilename)[0] won = (player in (game.winner or [])) partner = game.partners[player] myTeam, otherTeam = game.teams if player not in myTeam: myTeam, otherTeam = otherTeam, myTeam print "<tr><td><img src=\"/static/images/icons/%s.png\"> %s</td> <td>%s</td><td>%d to %d</td><td>%s</td><td><a class=\"fancy mini\" href=\"/games/%s/history\">game history</a> <a class=\"fancy mini\" href=\"?q=game:%s\">focus stats on this game</a></td></tr>" % ('success' if won else 'error', 'Won' if won else 'Lost', annotatedTeamName(game, otherTeam), game.score[myTeam], game.score[otherTeam], game.end.strftime('%Y-%m-%d %H:%M:%S'), name, name) print "</table>" print "</td>" print "</tr>" print "</table>" print "<a name=\"frequencies\"/>" print "<h2><a href=\"#frequencies\">Frequencies</a></h2>" print "<a name=\"bids\"/>" print "<h3><a href=\"#bids\">Bids</a></h3>" bids = {i: {'count': 0, 'made': 0} for i in range(14)} for game in games: partner = game.partners[player] for round in game.rounds: if not round.finished: continue bid = bidValue(round.bidsByPlayer[player]) partnerBid = bidValue(round.bidsByPlayer[partner]) taken = len(round.tricksByWinner[player]) partnerTaken = len(round.tricksByWinner[partner]) bids[bid]['count'] += 1 # Going to count a bid as "made" if you made nil, you alone made your bid (even if going bust as a team), or the team made its collective bid if (taken == 0) if (bid == 0) else (taken >= bid or taken + partnerTaken >= bid + partnerBid): bids[bid]['made'] += 1 BidSuccessChart('bid-success-chart', bids).emplace(handler) print "<a name=\"partners\"/>" print "<h3><a href=\"#partners\">Partners</a></h3>" partners = {} for game in games: partner = game.partners[player] if partner is None: continue if partner not in partners: partners[partner] = {'games': 0, 'wins': 0} partners[partner]['games'] += 1 if player in (game.winner or []): partners[partner]['wins'] += 1 print "<table class=\"partners\">" print "<tr><th> </th><th>Wins</th></tr>" for partner in sorted(partners): info = partners[partner] print "<tr>" print "<td><a href=\"/players/%s\"><img src=\"/players/%s/avatar\"></a></td>" % (partner, partner) print "<td class=\"progresscell\">%s</div>" % ProgressBar(info['wins'], info['games'], partner, "/players/%s" % partner) print "</tr>" print "</table>" PartnersChart('partners-chart', partners).emplace(handler) def printCardCounts(title, data): print "<a name=\"freq-%s\"/>" % title.lower() print "<h3><a href=\"freq-%s\">%s</a></h3>" % (title.lower(), title) for count in sorted(list(set(data.values())), reverse = True): print "<div class=\"freq-cards\">" print "<div class=\"count\">%d</div>" % count theseCards = [card for card, c in data.iteritems() if c == count] theseCards.sort(key = ordering.index) for card in theseCards: print "<img src=\"/card/%s\">" % card print "</div>" printCardCounts('Cards', cards) printCardCounts('Leads', leads)