Move leader cards to separate page. add current streaks

This commit is contained in:
Maximilian Keßler 2023-12-04 22:02:08 +01:00
parent ee40c27bc7
commit 0b67cea089
Signed by: max
GPG Key ID: BCC5A619923C0BA5
5 changed files with 63 additions and 48 deletions

View File

@ -11,6 +11,11 @@
font-weight: bold;
color: #17a2b8; /* Bootstrap's teal color */
}
.current-streak {
font-size: 1.5rem;
font-weight: bold;
color: #676767; /* Bootstrap's teal color */
}
.table td, .table th {
vertical-align: middle;
}

View File

@ -20,6 +20,11 @@ class PlayerEntry:
score: int
@dataclass
class PlayerStreakEntry(PlayerEntry):
current_streak: int
@dataclass
class Leader:
title: str
@ -59,6 +64,7 @@ class VariantStats:
return 0
return round(float(self.total_moves) / self.games_played, 3)
@dataclass
class VariantRow:
variant_id: int
@ -117,7 +123,7 @@ def get_leaders(rating_lists: Dict, streak_lists: Dict) -> Dict[int, Dict[str, L
return leaders
def get_stat_lists(stat_type: str, order_type: str = 'DESC', precision: int = 0, default: float | int = 0, percents: bool = False):
def get_streak_list():
cur = conn_manager.get_connection().cursor(cursor_factory=psycopg2.extras.DictCursor)
rating_types = [utils.get_rating_type(x) for x in [False, True]]
leaderboard = {
@ -128,27 +134,23 @@ def get_stat_lists(stat_type: str, order_type: str = 'DESC', precision: int = 0,
cur.execute(
"SELECT * FROM ("
" SELECT "
" player_name,"
" string_agg(user_accounts.username, %s ORDER BY user_accounts.username) AS user_accounts,"
f" COALESCE({stat_type}, %s) AS value"
" FROM users "
" LEFT OUTER JOIN user_statistics"
" ON users.id = user_statistics.user_id AND variant_type = %s"
" LEFT OUTER JOIN user_accounts "
" ON users.id = user_accounts.user_id "
f" GROUP BY (user_accounts.user_id, player_name, {stat_type}) "
" player_name,"
" STRING_AGG(user_accounts.username, %s ORDER BY user_accounts.username) AS user_accounts,"
" COALESCE(maximum_streak, 0) AS maximum_streak,"
" COALESCE(current_streak, 0) AS current_streak"
" FROM users "
" LEFT OUTER JOIN user_statistics"
" ON users.id = user_statistics.user_id AND variant_type = %s"
" LEFT OUTER JOIN user_accounts "
" ON users.id = user_accounts.user_id "
" GROUP BY (user_accounts.user_id, player_name, maximum_streak, current_streak) "
" ) AS streaks "
# As a tiebreak, just sort by player name for now for determinancy
f"ORDER BY value {order_type}, player_name",
(", ", default, rating_type)
"ORDER BY maximum_streak, player_name",
(", ", rating_type)
)
for (player_name, user_accounts, value) in cur.fetchall():
if percents:
value = round(100 * value, precision)
value = str(value) + ' %'
else:
value = round(value, precision)
leaderboard[rating_type].append(PlayerEntry(player_name, user_accounts, value))
for (player_name, user_accounts, max_streak, current_streak) in cur.fetchall():
leaderboard[rating_type].append(PlayerStreakEntry(player_name, user_accounts, max_streak, current_streak))
return leaderboard
@ -228,7 +230,7 @@ def build_variant_stats_per_variant(variant_rows: List[VariantRow]):
def render_leaderboard():
rating_lists = get_rating_lists()
streak_lists = get_stat_lists("maximum_streak")
streak_lists = get_streak_list()
leaders = get_leaders(rating_lists, streak_lists)
variant_rows: List[VariantRow] = get_variant_rows()
@ -237,9 +239,6 @@ def render_leaderboard():
leaderboards = {
'Player Rating': rating_lists,
'Maximum Streak': streak_lists,
'Current Streak': get_stat_lists("current_streak", order_type="DESC"),
'Average Bottom Deck Risk': get_stat_lists("average_bdr", 'ASC', precision=2, default=float("inf")),
'Winrate': get_stat_lists('winrate', order_type='DESC', precision=1, percents=True)
}
env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'))

View File

@ -1,22 +1,27 @@
{% extends "layout.html" %}
{% block content %}
<div class="tab-content" id="myTabContent">
{% for rating_type, leaders in leaders.items() %}
<div class="tab-pane fade{{' active show' if rating_type == 0 else ''}}" id="leaderboards-{{rating_type}}">
<div class="container my-5">
<!-- Leader Cards -->
<div class="card-deck mb-5">
{% for category, data in leaders.items() %}
<div class="card text-center">
<div class="card-body">
<h5 class="card-title mb-4">{{ data.title }}</h5>
<p class="mb-0 player-name">{{ data.entry.player_name }}</p>
<p class="mt-1 alt-name">{{ data.entry.user_accounts }}</p>
<p class="score-large">{{ data.entry.score }}</p>
</div>
<div class="tab-pane fade active show" id="summary">
<!-- Leader Cards -->
<div class="card-deck mb-5">
{% for rating_type, leaders in leaders.items() %}
{% for category, data in leaders.items() %}
<div class="card text-center">
<div class="card-body">
<h5 class="card-title mb-4">{{ data.title }}</h5>
<p class="mb-0 player-name">{{ data.entry.player_name }}</p>
<p class="mt-1 alt-name">{{ data.entry.user_accounts }}</p>
<p class="score-large">{{ data.entry.score }}</p>
</div>
{% endfor %}
</div>
{% endfor %}
{% endfor %}
</div>
</div>
{% for rating_type, leaders in leaders.items() %}
<div class="tab-pane fade" id="leaderboards-{{rating_type}}">
<div class="container my-5">
<!-- Leaderboards -->
<div id="leaderboards-{{rating_type}}-data" class="accordion">
@ -37,6 +42,9 @@
<div class="alt-name">{{ entry.user_accounts }}</div>
</td>
<td class="score">{{ entry.score }}</td>
{% if entry.current_streak is defined %}
<td class="current-streak">({{ entry.current_streak }})</td>
{% endif %}
</tr>
{% endfor %}
</table>

View File

@ -17,7 +17,10 @@
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" id="leaderboards-0-tab" data-toggle="tab" href="#leaderboards-0">No Variant</a>
<a class="nav-link active" id="summary-tab" data-toggle="tab" href="#summary">Summary</a>
</li>
<li class="nav-item">
<a class="nav-link" id="leaderboards-0-tab" data-toggle="tab" href="#leaderboards-0">No Variant</a>
</li>
<li class="nav-item">
<a class="nav-link" id="leaderboards-1-tab" data-toggle="tab" href="#leaderboards-1">Clue Starved</a>

View File

@ -11,7 +11,7 @@
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="#">The Hanabi Pro Hunting League<small class="text-muted"> - Variant Statistics for {{variant_name}}</small></a>
<a class="navbar-brand" href="/">The Hanabi Pro Hunting League</a><a class="navbar-brand" href="#"><small class="text-muted">- Variant Statistics for {{variant_name}}</small></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@ -36,7 +36,7 @@
<div class="tab-pane fade" id="stats-{{num_players}}p">
<div class="container my-5">
<h3>
League statistics for {{variant_name}} ({{num_players}} players)
League Statistics for {{variant_name}} - {{num_players}} Players
</h3>
<div class="history-bullets">
<ul>
@ -45,25 +45,25 @@
{{stats.rating}}
</li>
<li>
<span class="stat-description">Total perfect scores:</span>
<span class="stat-description">Total Perfect Scores:</span>
{{stats.games_won}}
</li>
<li>
<span class="stat-description">Total bottom deck risk:</span>
<span class="stat-description">Total Bottom Deck Risk:</span>
{{stats.total_bdr}}
</li>
<li>
<span class="stat-description">Total crits lost:</span>
<span class="stat-description">Total Crits Lost:</span>
{{stats.total_crits_lost}}
</li>
<li>
<span class="stat-description">Total turns taken:</span>
<span class="stat-description">Total Turns Taken:</span>
{{stats.total_moves}}
</li>
</ul>
<ul>
<li>
<span class="stat-description">Total games played:</span>
<span class="stat-description">Total Games Played:</span>
{{stats.games_played}}
</li>
<li>
@ -71,15 +71,15 @@
{{stats.winrate}}%
</li>
<li>
<span class="stat-description">Average bottom deck risk:</span>
<span class="stat-description">Average Bottom Deck Risk:</span>
{{stats.average_bdr}}
</li>
<li>
<span class="stat-description">Average crits lost:</span>
<span class="stat-description">Average Crits Lost:</span>
{{stats.average_crits_lost}}
</li>
<li>
<span class="stat-description">Average turns taken:</span>
<span class="stat-description">Average Turns Taken:</span>
{{stats.average_moves}}
</li>
</ul>