Files
yrtv/web/routes/tactics.py

141 lines
4.5 KiB
Python
Raw Permalink Normal View History

2026-01-26 02:13:06 +08:00
from flask import Blueprint, render_template, request, jsonify
from web.services.web_service import WebService
from web.services.stats_service import StatsService
from web.services.feature_service import FeatureService
import json
bp = Blueprint('tactics', __name__, url_prefix='/tactics')
@bp.route('/')
def index():
return render_template('tactics/index.html')
# API: Analyze Lineup
@bp.route('/api/analyze', methods=['POST'])
def api_analyze():
data = request.json
steam_ids = data.get('steam_ids', [])
if not steam_ids:
return jsonify({'error': 'No players selected'}), 400
# 1. Get Basic Info & Stats
players = StatsService.get_players_by_ids(steam_ids)
player_data = []
total_rating = 0
total_kd = 0
total_adr = 0
count = 0
for p in players:
p_dict = dict(p)
# Fetch L3 features
f = FeatureService.get_player_features(p_dict['steam_id_64'])
stats = dict(f) if f else {}
p_dict['stats'] = stats
player_data.append(p_dict)
if stats:
2026-01-29 12:18:05 +08:00
total_rating += stats.get('basic_avg_rating', 0) or 0
total_kd += stats.get('basic_avg_kd', 0) or 0
total_adr += stats.get('basic_avg_adr', 0) or 0
2026-01-26 02:13:06 +08:00
count += 1
# 2. Shared Matches
shared_matches = StatsService.get_shared_matches(steam_ids)
# They are already dicts now with 'result_str' and 'is_win'
2026-01-26 02:13:06 +08:00
# 3. Aggregates
avg_stats = {
'rating': total_rating / count if count else 0,
'kd': total_kd / count if count else 0,
'adr': total_adr / count if count else 0
}
2026-01-29 23:44:02 +08:00
# Calculate 8-Dimension Averages
radar_keys = {
'score_aim': 'AIM', 'score_defense': 'DEFENSE', 'score_utility': 'UTILITY',
'score_clutch': 'CLUTCH', 'score_economy': 'ECONOMY', 'score_pace': 'PACE',
'score_pistol': 'PISTOL', 'score_stability': 'STABILITY'
}
radar_stats = {v: 0.0 for v in radar_keys.values()}
if count > 0:
for p in player_data:
stats = p.get('stats', {})
for k, v in radar_keys.items():
radar_stats[v] += float(stats.get(k) or 0.0)
for k in radar_stats:
radar_stats[k] /= count
# Calculate Chemistry
# Formula: Base on shared matches and win rate
# Max Score = 100
# 50% weight on match count (Cap at 50 matches = 50 pts)
# 50% weight on win rate (100% WR = 50 pts)
avg_shared_count = 0
avg_shared_winrate = 0
if shared_matches:
avg_shared_count = len(shared_matches)
wins = sum(1 for m in shared_matches if m['is_win'])
avg_shared_winrate = wins / len(shared_matches)
chem_match_score = min(50, avg_shared_count) # 1 point per match, max 50
chem_win_score = avg_shared_winrate * 50
chemistry_score = chem_match_score + chem_win_score
2026-01-26 17:26:43 +08:00
# 4. Map Stats Calculation
map_stats = {} # {map_name: {'count': 0, 'wins': 0}}
total_shared_matches = len(shared_matches)
for m in shared_matches:
map_name = m['map_name']
if map_name not in map_stats:
map_stats[map_name] = {'count': 0, 'wins': 0}
map_stats[map_name]['count'] += 1
if m['is_win']:
map_stats[map_name]['wins'] += 1
# Convert to list for frontend
map_stats_list = []
for k, v in map_stats.items():
win_rate = (v['wins'] / v['count'] * 100) if v['count'] > 0 else 0
map_stats_list.append({
'map_name': k,
'count': v['count'],
'wins': v['wins'],
'win_rate': win_rate
})
# Sort by count desc
map_stats_list.sort(key=lambda x: x['count'], reverse=True)
2026-01-26 02:13:06 +08:00
return jsonify({
'players': player_data,
'shared_matches': [dict(m) for m in shared_matches],
2026-01-26 17:26:43 +08:00
'avg_stats': avg_stats,
2026-01-29 23:44:02 +08:00
'radar_stats': radar_stats,
'chemistry_score': chemistry_score,
2026-01-26 17:26:43 +08:00
'map_stats': map_stats_list,
2026-01-29 12:18:05 +08:00
'total_shared_matches': total_shared_matches
2026-01-26 02:13:06 +08:00
})
# API: Save Board
@bp.route('/save_board', methods=['POST'])
def save_board():
data = request.json
title = data.get('title', 'Untitled Strategy')
map_name = data.get('map_name', 'de_mirage')
markers = data.get('markers')
if not markers:
return jsonify({'success': False, 'message': 'No markers to save'})
WebService.save_strategy_board(title, map_name, json.dumps(markers), 'Anonymous')
return jsonify({'success': True, 'message': 'Board saved successfully'})