DL-Broadcast-Tool/analysis/team_identity_v2.py

168 lines
No EOL
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from utils.safe_tag import safe_pct, safe_tier, safe_avg
# Caster‑friendly display names
DISPLAY_NAMES = {
"slayer": "Slayer",
"objective_payload": "Payload Specialist",
"sharpshooter": "Sharpshooter",
"consistency": "Consistency",
"clutch": "Clutch",
"anchor": "Anchor Specialist",
"breaker": "Breaker",
}
def summarize_team_tags(team_players):
"""
Aggregates tag tiers + percentiles for a team.
Returns a dict with:
- avg_pct
- top_tier
- tier counts
"""
tags = ["slayer", "objective_payload", "sharpshooter",
"consistency", "clutch", "anchor", "breaker"]
summary = {}
for tag in tags:
pcts = []
tiers = []
for p in team_players:
tag_data = p.get(tag, {})
pcts.append(safe_pct(tag_data.get("pct")))
tiers.append(safe_tier(tag_data.get("tier"))) # guaranteed valid tier
summary[tag] = {
"avg_pct": safe_avg(pcts), # guaranteed numeric
"top_tier": max(tiers, key=lambda t: "SABCD".index(t)),
"count_S": tiers.count("S"),
"count_A": tiers.count("A"),
"count_B": tiers.count("B"),
"count_C": tiers.count("C"),
"count_D": tiers.count("D"),
}
return summary
def classify_team_style(summary):
"""
Produces a high-level team style classification based on tag strengths.
"""
slayer = summary["slayer"]["avg_pct"]
payload = summary["objective_payload"]["avg_pct"]
sharpshooter = summary["sharpshooter"]["avg_pct"]
consistency = summary["consistency"]["avg_pct"]
clutch = summary["clutch"]["avg_pct"]
anchor = summary["anchor"]["avg_pct"]
# Primary style selection
primary = max(
{
"Slayer-heavy": slayer,
"Objective-focused": payload,
"Precision/Sharpshooter": sharpshooter,
"Stable/Consistent": consistency,
"High-pressure/Clutch": clutch,
"Anchor/Support": anchor,
}.items(),
key=lambda x: x[1]
)[0]
# Weakness detection
weaknesses = []
if slayer < 40:
weaknesses.append("low elimination pressure")
if payload < 40:
weaknesses.append("weak objective presence")
if sharpshooter < 40:
weaknesses.append("below-average accuracy")
if consistency < 40:
weaknesses.append("inconsistent match-to-match output")
if clutch < 40:
weaknesses.append("poor high-pressure performance")
if anchor < 40:
weaknesses.append("weak defensive backbone / low anchor stability")
return primary, weaknesses
def generate_team_identity_block(team_players, team_name="Team"):
"""
Returns a structured identity block dict for a team.
GUI or OBS formatter will convert this into text.
"""
summary = summarize_team_tags(team_players)
primary_style, weaknesses = classify_team_style(summary)
# Strengths list
strengths = []
for tag, data in summary.items():
if data["avg_pct"] >= 60:
display = DISPLAY_NAMES.get(tag, tag.replace("_", " ").title())
strengths.append(
f"Strong {display} ({data['top_tier']} Tier)"
)
# Tag breakdown
tag_block = {}
for tag, data in summary.items():
tag_block[tag] = {
"avg_pct": data["avg_pct"],
"tier": data["top_tier"],
}
return {
"team_name": team_name,
"team_style": primary_style,
"strengths": strengths,
"weaknesses": weaknesses,
"tags": tag_block,
}
def format_team_identity(identity_data):
"""
Converts the identity block dict into a readable text block.
Used by GUI and OBS exporters.
"""
lines = []
lines.append(f"Team: {identity_data['team_name']}")
lines.append(f"Playstyle: {identity_data['team_style']}")
lines.append("")
# Strengths
lines.append("Strengths:")
if identity_data["strengths"]:
for s in identity_data["strengths"]:
lines.append(f" - {s}")
else:
lines.append(" - None identified")
lines.append("")
# Weaknesses
lines.append("Weaknesses:")
if identity_data["weaknesses"]:
for w in identity_data["weaknesses"]:
lines.append(f" - {w}")
else:
lines.append(" - None identified")
lines.append("")
lines.append("Tag Breakdown:")
for tag, data in identity_data["tags"].items():
name = DISPLAY_NAMES.get(tag, tag.replace("_", " ").title())
lines.append(
f" - {name}: {data['tier']} Tier (avg {data['avg_pct']:.1f} percentile)"
)
return "\n".join(lines)