Skip to content

Commit 2ed4e52

Browse files
committed
Forgot to include views.py changes
1 parent df36704 commit 2ed4e52

File tree

1 file changed

+118
-3
lines changed

1 file changed

+118
-3
lines changed

src/chigame/games/views.py

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ def create_game_history_entry(user, match):
19991999
user=user,
20002000
match=match,
20012001
defaults={
2002-
"is_completed": match.lobby.match_status == 3, # Lobby.Finished
2002+
"is_completed": match.lobby.match_status == Lobby.Finished, # Lobby.Finished is 3
20032003
"result": outcome,
20042004
},
20052005
)
@@ -2031,7 +2031,8 @@ def get(self, request, game_id):
20312031
if start_date:
20322032
entries = entries.filter(date_played__gte=start_date)
20332033

2034-
entries = entries.select_related("match").order_by("-date_played")
2034+
# Order by date_played ascending for accurate streak calculations first
2035+
ordered_entries_for_streaks = entries.select_related("match").order_by("date_played")
20352036

20362037
# Calculate statistics
20372038
total_played = entries.count()
@@ -2042,16 +2043,35 @@ def get(self, request, game_id):
20422043

20432044
win_rate = (wins / total_played) * 100 if total_played > 0 else 0
20442045

2046+
longest_win_streak = self._calculate_longest_streak(ordered_entries_for_streaks, GameHistory.WIN)
2047+
longest_loss_streak = self._calculate_longest_streak(ordered_entries_for_streaks, GameHistory.LOSE)
2048+
current_streak_type, current_streak_count = self._calculate_current_streak(ordered_entries_for_streaks)
2049+
average_playtime_seconds = self._calculate_average_playtime(entries) # Can use original entries for this
2050+
average_playtime = (
2051+
timedelta(seconds=average_playtime_seconds) if average_playtime_seconds is not None else None
2052+
)
2053+
2054+
# For opponent-based stats, we can use the original entries collection
2055+
opponent_stats = self._calculate_opponent_stats(request.user, entries)
2056+
20452057
context = {
20462058
"game": game,
2047-
"entries": entries,
2059+
"entries": entries.select_related("match").order_by("-date_played"), # Re-order for display
20482060
"selected_period": period,
20492061
"total_played": total_played,
20502062
"wins": wins,
20512063
"losses": losses,
20522064
"draws": draws,
20532065
"incomplete": incomplete,
20542066
"win_rate": win_rate,
2067+
"longest_win_streak": longest_win_streak,
2068+
"longest_loss_streak": longest_loss_streak,
2069+
"current_streak_type": current_streak_type,
2070+
"current_streak_count": current_streak_count,
2071+
"average_playtime": average_playtime,
2072+
"most_played_with": opponent_stats["most_played_with"],
2073+
"favorite_opponent": opponent_stats["favorite_opponent"],
2074+
"nemesis_opponent": opponent_stats["nemesis_opponent"],
20552075
"period_options": [
20562076
{"value": "all", "label": "All Time"},
20572077
{"value": "7days", "label": "Last 7 Days"},
@@ -2063,6 +2083,101 @@ def get(self, request, game_id):
20632083
}
20642084
return render(request, "games/game_history.html", context)
20652085

2086+
def _calculate_longest_streak(self, entries, outcome_type):
2087+
max_streak = 0
2088+
current_streak = 0
2089+
for entry in entries:
2090+
if entry.result == outcome_type:
2091+
current_streak += 1
2092+
else:
2093+
max_streak = max(max_streak, current_streak)
2094+
current_streak = 0
2095+
max_streak = max(max_streak, current_streak) # Final check
2096+
return max_streak
2097+
2098+
def _calculate_current_streak(self, entries):
2099+
if not entries:
2100+
return "N/A", 0
2101+
2102+
# .last() requires an ordered queryset
2103+
last_entry = entries.last()
2104+
if not last_entry or last_entry.result not in [GameHistory.WIN, GameHistory.LOSE]:
2105+
return "N/A", 0 # Not a win or loss
2106+
2107+
streak_type = last_entry.result
2108+
current_streak_count = 0
2109+
2110+
# Iterate in reverse order from the original ascending sort for streaks
2111+
for entry in reversed(entries):
2112+
if entry.result == streak_type:
2113+
current_streak_count += 1
2114+
else:
2115+
break
2116+
2117+
streak_label = "Win" if streak_type == GameHistory.WIN else "Loss"
2118+
return streak_label, current_streak_count
2119+
2120+
def _calculate_average_playtime(self, entries):
2121+
total_duration_seconds = 0
2122+
completed_games_count = 0
2123+
for entry in entries:
2124+
if entry.is_completed and entry.match and entry.match.start_time and entry.match.end_time:
2125+
duration = entry.match.end_time - entry.match.start_time
2126+
total_duration_seconds += duration.total_seconds()
2127+
completed_games_count += 1
2128+
2129+
if completed_games_count > 0:
2130+
return total_duration_seconds / completed_games_count
2131+
return None
2132+
2133+
def _calculate_opponent_stats(self, current_user, entries):
2134+
opponent_play_count = {}
2135+
opponent_win_count = {}
2136+
opponent_loss_count = {}
2137+
2138+
for entry in entries:
2139+
match = entry.match
2140+
if not match:
2141+
continue
2142+
2143+
opponents_in_match = [player for player in match.players.all() if player != current_user]
2144+
2145+
for opponent in opponents_in_match:
2146+
opponent_play_count[opponent] = opponent_play_count.get(opponent, 0) + 1
2147+
2148+
if entry.result == GameHistory.WIN:
2149+
opponent_win_count[opponent] = opponent_win_count.get(opponent, 0) + 1
2150+
elif entry.result == GameHistory.LOSE:
2151+
opponent_loss_count[opponent] = opponent_loss_count.get(opponent, 0) + 1
2152+
2153+
most_played_with_opponent = None
2154+
if opponent_play_count:
2155+
most_played_with_opponent_user = max(opponent_play_count, key=opponent_play_count.get)
2156+
most_played_with_opponent = {
2157+
"user": most_played_with_opponent_user,
2158+
"count": opponent_play_count[most_played_with_opponent_user],
2159+
}
2160+
2161+
favorite_opponent_user = None
2162+
if opponent_win_count:
2163+
favorite_opponent_user_candidate = max(opponent_win_count, key=opponent_win_count.get)
2164+
max_wins_against = opponent_win_count[favorite_opponent_user_candidate]
2165+
if max_wins_against > 0:
2166+
favorite_opponent_user = {"user": favorite_opponent_user_candidate, "count": max_wins_against}
2167+
2168+
nemesis_opponent_user = None
2169+
if opponent_loss_count:
2170+
nemesis_opponent_user_candidate = max(opponent_loss_count, key=opponent_loss_count.get)
2171+
max_losses_against = opponent_loss_count[nemesis_opponent_user_candidate]
2172+
if max_losses_against > 0:
2173+
nemesis_opponent_user = {"user": nemesis_opponent_user_candidate, "count": max_losses_against}
2174+
2175+
return {
2176+
"most_played_with": most_played_with_opponent,
2177+
"favorite_opponent": favorite_opponent_user,
2178+
"nemesis_opponent": nemesis_opponent_user,
2179+
}
2180+
20662181

20672182
class MatchStatsView(DetailView):
20682183
model = Tournament

0 commit comments

Comments
 (0)