@ -1230,115 +1230,143 @@ defer {
teams [ groupStage . index * groupStage . size + 1 + teamIndex ] = [ groupStageTeams [ teamIndex ] . id ]
teams [ groupStage . index * groupStage . size + 1 + teamIndex ] = [ groupStageTeams [ teamIndex ] . id ]
}
}
}
}
} else {
return teams
let final = rounds . last ? . playedMatches ( ) . last
}
if let winner = final ? . winningTeamId {
teams [ 1 ] = [ winner ]
let final = rounds . last ? . playedMatches ( ) . last
ids . insert ( winner )
if let winner = final ? . winningTeamId {
}
teams [ 1 ] = [ winner ]
if let finalist = final ? . losingTeamId {
ids . insert ( winner )
teams [ 2 ] = [ finalist ]
}
ids . insert ( finalist )
if let finalist = final ? . losingTeamId {
teams [ 2 ] = [ finalist ]
ids . insert ( finalist )
}
let others : [ Round ] = rounds . flatMap { round in
let losers = round . losers ( )
let minimumFinalPosition = round . seedInterval ( ) ? . last ? ? teamCount
if teams [ minimumFinalPosition ] = = nil {
teams [ minimumFinalPosition ] = losers . map { $0 . id }
} else {
teams [ minimumFinalPosition ] ? . append ( contentsOf : losers . map { $0 . id } )
}
}
print ( " round " , round . roundTitle ( ) )
let others : [ Round ] = rounds . flatMap { round in
let rounds = round . loserRoundsAndChildren ( ) . filter { $0 . isRankDisabled ( ) = = false && $0 . hasNextRound ( ) = = false }
let losers = round . losers ( )
print ( rounds . count , rounds . map { $0 . roundTitle ( ) } )
let minimumFinalPosition = round . seedInterval ( ) ? . last ? ? teamCount
return rounds
if teams [ minimumFinalPosition ] = = nil {
} . compactMap ( { $0 } )
teams [ minimumFinalPosition ] = losers . map { $0 . id }
} else {
others . forEach { round in
teams [ minimumFinalPosition ] ? . append ( contentsOf : losers . map { $0 . id } )
print ( " round " , round . roundTitle ( ) )
}
if let interval = round . seedInterval ( ) {
print ( " interval " , interval . localizedInterval ( ) )
print ( " round " , round . roundTitle ( ) )
let playedMatches = round . playedMatches ( ) . filter { $0 . disabled = = false || $0 . isReady ( ) }
let rounds = round . loserRoundsAndChildren ( ) . filter { $0 . isRankDisabled ( ) = = false && $0 . hasNextRound ( ) = = false }
print ( " playedMatches " , playedMatches . count )
print ( rounds . count , rounds . map { $0 . roundTitle ( ) } )
let winners = playedMatches . compactMap ( { $0 . winningTeamId } ) . filter ( { ids . contains ( $0 ) = = false } )
return rounds
print ( " winners " , winners . count )
} . compactMap ( { $0 } )
let losers = playedMatches . compactMap ( { $0 . losingTeamId } ) . filter ( { ids . contains ( $0 ) = = false } )
print ( " losers " , losers . count )
others . forEach { round in
if winners . isEmpty {
print ( " round " , round . roundTitle ( ) )
let disabledIds = playedMatches . flatMap ( { $0 . teamScores . compactMap ( { $0 . teamRegistration } ) } ) . filter ( { ids . contains ( $0 ) = = false } )
if let interval = round . seedInterval ( ) {
if disabledIds . isEmpty = = false {
print ( " interval " , interval . localizedInterval ( ) )
_removeStrings ( from : & teams , stringsToRemove : disabledIds )
let playedMatches = round . playedMatches ( ) . filter { $0 . disabled = = false || $0 . isReady ( ) }
teams [ interval . last ] = disabledIds
print ( " playedMatches " , playedMatches . count )
let teamNames : [ String ] = disabledIds . compactMap {
let winners = playedMatches . compactMap ( { $0 . winningTeamId } ) . filter ( { ids . contains ( $0 ) = = false } )
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
print ( " winners " , winners . count )
return t
let losers = playedMatches . compactMap ( { $0 . losingTeamId } ) . filter ( { ids . contains ( $0 ) = = false } )
} . map { $0 . canonicalName }
print ( " losers " , losers . count )
print ( " winners.isEmpty " , " \( interval . last ) : " , teamNames )
if winners . isEmpty {
disabledIds . forEach {
let disabledIds = playedMatches . flatMap ( { $0 . teamScores . compactMap ( { $0 . teamRegistration } ) } ) . filter ( { ids . contains ( $0 ) = = false } )
ids . insert ( $0 )
if disabledIds . isEmpty = = false {
_removeStrings ( from : & teams , stringsToRemove : disabledIds )
teams [ interval . last ] = disabledIds
let teamNames : [ String ] = disabledIds . compactMap {
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
return t
} . map { $0 . canonicalName }
print ( " winners.isEmpty " , " \( interval . last ) : " , teamNames )
disabledIds . forEach {
ids . insert ( $0 )
}
}
} else {
if winners . isEmpty = = false {
_removeStrings ( from : & teams , stringsToRemove : winners )
teams [ interval . first + winners . count - 1 ] = winners
let teamNames : [ String ] = winners . compactMap {
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
return t
} . map { $0 . canonicalName }
print ( " winners " , " \( interval . last + winners . count - 1 ) : " , teamNames )
winners . forEach { ids . insert ( $0 ) }
}
if losers . isEmpty = = false {
_removeStrings ( from : & teams , stringsToRemove : losers )
teams [ interval . first + winners . count ] = losers
let loserTeamNames : [ String ] = losers . compactMap {
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
return t
} . map { $0 . canonicalName }
print ( " losers " , " \( interval . first + winners . count ) : " , loserTeamNames )
losers . forEach { ids . insert ( $0 ) }
}
}
}
}
} else {
}
if winners . isEmpty = = false {
}
_removeStrings ( from : & teams , stringsToRemove : winners )
teams [ interval . first + winners . count - 1 ] = winners
if let groupStageLoserBracketPlayedMatches = groupStageLoserBracket ( ) ? . playedMatches ( ) {
let teamNames : [ String ] = winners . compactMap {
groupStageLoserBracketPlayedMatches . forEach ( { match in
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
if match . hasEnded ( ) {
return t
let sameMatchIndexCount = groupStageLoserBracketPlayedMatches . filter ( { $0 . index = = match . index } ) . count
} . map { $0 . canonicalName }
teams . setOrAppend ( match . winningTeamId , at : match . index )
print ( " winners " , " \( interval . last + winners . count - 1 ) : " , teamNames )
teams . setOrAppend ( match . losingTeamId , at : match . index + sameMatchIndexCount )
winners . forEach { ids . insert ( $0 ) }
}
}
} )
if losers . isEmpty = = false {
}
_removeStrings ( from : & teams , stringsToRemove : losers )
teams [ interval . first + winners . count ] = losers
let groupStages = groupStages ( )
let loserTeamNames : [ String ] = losers . compactMap {
let baseRank = teamCount - groupStageSpots ( ) + qualifiedPerGroupStage * groupStageCount + groupStageAdditionalQualified
let t : TeamRegistration ? = tournamentStore . teamRegistrations . findById ( $0 )
let alreadyPlaceTeams = Array ( teams . values . flatMap ( { $0 } ) )
return t
groupStages . forEach { groupStage in
} . map { $0 . canonicalName }
let groupStageTeams = groupStage . teams ( true )
print ( " losers " , " \( interval . first + winners . count ) : " , loserTeamNames )
for ( index , team ) in groupStageTeams . enumerated ( ) {
losers . forEach { ids . insert ( $0 ) }
if team . qualified = = false && alreadyPlaceTeams . contains ( team . id ) = = false {
let groupStageWidth = max ( ( ( index = = qualifiedPerGroupStage ) ? groupStageCount - groupStageAdditionalQualified : groupStageCount ) * ( index - qualifiedPerGroupStage ) , 0 )
let _index = baseRank + groupStageWidth + 1
if let existingTeams = teams [ _index ] {
teams [ _index ] = existingTeams + [ team . id ]
} else {
teams [ _index ] = [ team . id ]
}
}
}
}
}
}
}
}
}
if let groupStageLoserBracketPlayedMatches = groupStageLoserBracket ( ) ? . playedMatches ( ) {
return teams
groupStageLoserBracketPlayedMatches . forEach ( { match in
}
if match . hasEnded ( ) {
let sameMatchIndexCount = groupStageLoserBracketPlayedMatches . filter ( { $0 . index = = match . index } ) . count
func setRankings ( finalRanks : [ Int : [ String ] ] ) async -> [ Int : [ TeamRegistration ] ] {
teams . setOrAppend ( match . winningTeamId , at : match . index )
var rankings : [ Int : [ TeamRegistration ] ] = [ : ]
teams . setOrAppend ( match . losingTeamId , at : match . index + sameMatchIndexCount )
}
} )
}
let groupStages = groupStages ( )
finalRanks . keys . sorted ( ) . forEach { rank in
let baseRank = teamCount - groupStageSpots ( ) + qualifiedPerGroupStage * groupStageCount + groupStageAdditionalQualified
if let rankedTeamIds = finalRanks [ rank ] {
let alreadyPlaceTeams = Array ( teams . values . flatMap ( { $0 } ) )
let teams : [ TeamRegistration ] = rankedTeamIds . compactMap { self . tournamentStore . teamRegistrations . findById ( $0 ) }
groupStages . forEach { groupStage in
rankings [ rank ] = teams
let groupStageTeams = groupStage . teams ( true )
}
for ( index , team ) in groupStageTeams . enumerated ( ) {
}
if team . qualified = = false && alreadyPlaceTeams . contains ( team . id ) = = false {
let groupStageWidth = max ( ( ( index = = qualifiedPerGroupStage ) ? groupStageCount - groupStageAdditionalQualified : groupStageCount ) * ( index - qualifiedPerGroupStage ) , 0 )
rankings . keys . sorted ( ) . forEach { rank in
if let rankedTeams = rankings [ rank ] {
let _index = baseRank + groupStageWidth + 1
rankedTeams . forEach { team in
if let existingTeams = teams [ _index ] {
team . finalRanking = rank
teams [ _index ] = existingTeams + [ team . id ]
team . pointsEarned = isAnimation ( ) ? nil : tournamentLevel . points ( for : rank - 1 , count : teamCount )
} else {
teams [ _index ] = [ team . id ]
}
}
}
}
}
}
}
return teams
do {
try self . tournamentStore . teamRegistrations . addOrUpdate ( contentOfs : unsortedTeams ( ) )
} catch {
Logger . error ( error )
}
return rankings
}
}
func lockRegistration ( ) {
func lockRegistration ( ) {
@ -1977,6 +2005,7 @@ defer {
groupStageMatchFormat = groupStageSmartMatchFormat ( )
groupStageMatchFormat = groupStageSmartMatchFormat ( )
loserBracketMatchFormat = loserBracketSmartMatchFormat ( 5 )
loserBracketMatchFormat = loserBracketSmartMatchFormat ( 5 )
matchFormat = roundSmartMatchFormat ( 5 )
matchFormat = roundSmartMatchFormat ( 5 )
entryFee = tournamentLevel . entryFee
}
}
func roundSmartMatchFormat ( _ roundIndex : Int ) -> MatchFormat {
func roundSmartMatchFormat ( _ roundIndex : Int ) -> MatchFormat {
@ -2150,6 +2179,19 @@ defer {
}
}
func updateTournamentState ( ) {
Task {
if hasEnded ( ) {
let fr = await finalRanking ( )
_ = await setRankings ( finalRanks : fr )
}
}
}
func allLoserRoundMatches ( ) -> [ Match ] {
rounds ( ) . flatMap { $0 . loserRoundsAndChildren ( ) . flatMap ( { $0 . _matches ( ) } ) }
}
// MARK: -
// MARK: -
func insertOnServer ( ) throws {
func insertOnServer ( ) throws {