@@ -77,43 +77,42 @@ export class FlagService {
7777 static async getRandomOptions ( flags : Flag [ ] , correctFlag : Flag , count : number = 3 , sourceFlags ?: Flag [ ] , difficulty : Difficulty = 'medium' ) : Promise < Flag [ ] > {
7878 await this . loadDifficultyGroups ( ) ;
7979
80- const correctGroups = this . getGroupsForCountry ( correctFlag . country ) ;
8180 const options = [ correctFlag ] ;
8281 const availableFlags = ( sourceFlags || flags ) . filter ( f => f . country !== correctFlag . country ) ;
82+ const correctGroups = this . getGroupsForCountry ( correctFlag . country ) ;
8383
84- const similarPercentage = difficulty === 'easy' ? 0.1 :
85- difficulty === 'medium' ? 0.5 : 0.9 ;
86-
87- const similarCount = Math . round ( count * similarPercentage ) ;
88-
89- // Get similar flags
90- if ( similarCount > 0 ) {
91- const similarFlags = availableFlags
92- . map ( flag => ( {
93- flag,
94- commonGroups : this . getGroupsForCountry ( flag . country )
95- . filter ( group => correctGroups . some ( g => g . name === group . name ) )
96- } ) )
97- . filter ( ( { commonGroups } ) => commonGroups . length > 0 )
98- . filter ( ( { flag } ) => ! options . some ( existingFlag => existingFlag . country === flag . country ) )
99- . sort ( ( a , b ) => {
100- const aMaxWeight = Math . max ( ...a . commonGroups . map ( g => g . weight ) ) ;
101- const bMaxWeight = Math . max ( ...b . commonGroups . map ( g => g . weight ) ) ;
102- return difficulty === 'easy' ? aMaxWeight - bMaxWeight : bMaxWeight - aMaxWeight ;
103- } ) ;
104-
105- for ( let i = 0 ; i < similarCount && similarFlags . length > 0 ; i ++ ) {
106- const randomIndex = Math . floor ( Math . random ( ) * Math . min ( 3 , similarFlags . length ) ) ;
107- options . push ( similarFlags [ randomIndex ] . flag ) ;
108- similarFlags . splice ( randomIndex , 1 ) ;
109- }
84+ // Calculate similarity scores for all available flags
85+ const flagsWithScores = availableFlags . map ( flag => {
86+ const commonGroups = this . getGroupsForCountry ( flag . country )
87+ . filter ( group => correctGroups . some ( g => g . name === group . name ) ) ;
88+
89+ // Calculate similarity score based on common groups and their weights
90+ const similarityScore = commonGroups . reduce ( ( sum , group ) => sum + group . weight , 0 ) ;
91+
92+ return { flag, similarityScore } ;
93+ } ) ;
94+
95+ // Sort by similarity score (higher score = more similar)
96+ flagsWithScores . sort ( ( a , b ) => b . similarityScore - a . similarityScore ) ;
97+
98+ // Select flags based on difficulty
99+ const similarCount = difficulty === 'easy' ? Math . round ( count * 0.3 ) :
100+ difficulty === 'medium' ? Math . round ( count * 0.7 ) :
101+ Math . round ( count * 0.9 ) ;
102+
103+ // Get similar flags from top portion
104+ const topSimilar = flagsWithScores . slice ( 0 , Math . ceil ( flagsWithScores . length * 0.2 ) ) ;
105+ for ( let i = 0 ; i < similarCount && topSimilar . length > 0 ; i ++ ) {
106+ const randomIndex = Math . floor ( Math . random ( ) * topSimilar . length ) ;
107+ options . push ( topSimilar [ randomIndex ] . flag ) ;
108+ topSimilar . splice ( randomIndex , 1 ) ;
110109 }
111110
112111 // Fill remaining with random flags
113- const remainingFlags = availableFlags . filter ( flag =>
114- ! options . some ( existingFlag => existingFlag . country === flag . country )
115- ) ;
116-
112+ const remainingFlags = flagsWithScores
113+ . filter ( ( { flag } ) => ! options . some ( opt => opt . country === flag . country ) )
114+ . map ( ( { flag } ) => flag ) ;
115+
117116 while ( options . length < count + 1 && remainingFlags . length > 0 ) {
118117 const randomIndex = Math . floor ( Math . random ( ) * remainingFlags . length ) ;
119118 options . push ( remainingFlags [ randomIndex ] ) ;
0 commit comments