1+ using dsstats . shared ;
2+
3+ namespace dsstats . razorlib . Stats . Synergy ;
4+
5+ internal static class GroupSynergy
6+ {
7+ public static GroupSynergyResponse GetGroupSynergy ( SynergyResponse response , List < Commander > group )
8+ {
9+ GroupSynergyResponse groupSynergy = new ( )
10+ {
11+ Group = group
12+ } ;
13+
14+ var commanders = response . Entities
15+ . Select ( e => e . Commander )
16+ . Distinct ( )
17+ . ToList ( ) ;
18+
19+ Dictionary < Commander , GroupSynergyInfo > synergyInfos = [ ] ;
20+ foreach ( var interest in group )
21+ {
22+ foreach ( var cmdr in commanders )
23+ {
24+ var synergyEnt = response . Entities
25+ . FirstOrDefault ( e => e . Commander == interest && e . Teammate == cmdr ) ;
26+ if ( synergyEnt == null )
27+ {
28+ continue ;
29+ }
30+ if ( ! synergyInfos . TryGetValue ( cmdr , out var infos ) )
31+ {
32+ infos = new GroupSynergyInfo ( ) ;
33+ synergyInfos [ cmdr ] = infos ;
34+ }
35+ infos . Counts . Add ( synergyEnt . Count ) ;
36+ infos . Wins . Add ( synergyEnt . Wins ) ;
37+ infos . AvgRatings . Add ( synergyEnt . AvgRating ) ;
38+ infos . AvgGains . Add ( synergyEnt . AvgGain ) ;
39+ }
40+ }
41+
42+ var avgGainMax = response . Entities . Max ( m => m . AvgGain ) ; // normalized to 1
43+ var avgGainMin = response . Entities . Min ( m => m . AvgGain ) ; // normalized to 0
44+
45+ foreach ( var ( teammate , synergyInfo ) in synergyInfos )
46+ {
47+ groupSynergy . Entities . Add ( synergyInfo . ToSynergyEnt ( teammate , avgGainMax , avgGainMin ) ) ;
48+ }
49+
50+ return groupSynergy ;
51+ }
52+ }
53+
54+ internal record GroupSynergyInfo
55+ {
56+ public List < int > Counts { get ; set ; } = [ ] ;
57+ public List < int > Wins { get ; set ; } = [ ] ;
58+ public List < double > AvgRatings { get ; set ; } = [ ] ;
59+ public List < double > AvgGains { get ; set ; } = [ ] ;
60+
61+ public SynergyEnt ToSynergyEnt ( Commander teammate , double avgGainMax , double avgGainMin )
62+ {
63+ // Calculate weighted average for AvgRating
64+ double totalWeightedRatingSum = 0 ;
65+ double totalCountForAvgRating = 0 ;
66+ for ( int i = 0 ; i < Counts . Count ; i ++ )
67+ {
68+ totalWeightedRatingSum += AvgRatings [ i ] * Counts [ i ] ;
69+ totalCountForAvgRating += Counts [ i ] ;
70+ }
71+
72+ double finalAvgRating = totalCountForAvgRating > 0 ? totalWeightedRatingSum / totalCountForAvgRating : 0 ;
73+
74+ // Calculate weighted average for AvgGain
75+ double totalWeightedGainSum = 0 ;
76+ double totalCountForAvgGain = 0 ;
77+ for ( int i = 0 ; i < Counts . Count ; i ++ )
78+ {
79+ totalWeightedGainSum += AvgGains [ i ] * Counts [ i ] ;
80+ totalCountForAvgGain += Counts [ i ] ;
81+ }
82+
83+ double finalAvgGain = totalCountForAvgGain > 0 ? totalWeightedGainSum / totalCountForAvgGain : 0 ;
84+
85+ return new SynergyEnt
86+ {
87+ Commander = Commander . None , // Placeholder for the group
88+ Teammate = teammate ,
89+ Count = Counts . Sum ( ) ,
90+ Wins = Wins . Sum ( ) ,
91+ AvgRating = finalAvgRating ,
92+ AvgGain = finalAvgGain ,
93+ NormalizedAvgGain = totalCountForAvgGain > 0
94+ ? ( finalAvgGain - avgGainMin ) / ( avgGainMax - avgGainMin )
95+ : 0
96+ } ;
97+ }
98+ }
0 commit comments