tournaments/standings.go
func NewStandings(tournaments Tournaments) PlayerStandings {

	// First, find all active players for these tournaments
	// Also, get the max number of players for a given set of tournaments
	// This gives us the basis for low point scoring
	activePlayers, maxPlayers := getActivePlayers(tournaments)

	// Then, loop through tournaments again to keep track of relevant stats
	winnings := make(map[uuid.UUID]int)
	sumPlace := make(map[uuid.UUID]int)
	points := make(map[uuid.UUID][]int)
	numHeadsUp := make(map[uuid.UUID]int)
	numWins := make(map[uuid.UUID]int)
	numPlayed := make(map[uuid.UUID]int)
	knockouts := make(map[uuid.UUID]int)
	results := make(map[uuid.UUID][]PlayerResult)
	numTotal := 0

	for _, t := range tournaments {
		if !t.Played || len(t.Result) == 0 {
			continue
		}
		numTotal += 1
		seenPlayer := make(map[uuid.UUID]bool)
		for i, player := range t.Result {
			place := i + 1
			results[player] = append(results[player], PlayerResult{
				Place:      place,
				When:       t.Info.Scheduled,
				NumPlayers: len(t.Result),
			})

			sumPlace[player] += place
			numPlayed[player] += 1
			seenPlayer[player] = true
			points[player] = append(points[player], place)

			switch place {
			case 1:
				numWins[player] += 1
				winnings[player] += (len(t.Result) - 2) * t.Info.Stake
				numHeadsUp[player] += 1
			case 2:
				numHeadsUp[player] += 1
			default:
				winnings[player] -= t.Info.Stake
			}
		}

		for _, player := range activePlayers {
			if _, seen := seenPlayer[player]; !seen {
				points[player] = append(points[player], maxPlayers+1)
			}
		}

		for player := range t.BountyHunters {
			knockouts[player] += len(t.BountyHunters[player])
		}
	}

	// Finally, loop through active players and set totals, returning standings
	var standings PlayerStandings

	for _, player := range activePlayers {

		// Remove worst point score at 10 and 20 played tournaments
		pp := points[player]
		sort.Ints(pp)

		if numPlayed[player] >= 10 {
			i := len(pp) - 1
			pp = append(pp[:i], pp[i+1:]...) // delete element at index i (last)
		}
		if numPlayed[player] >= 20 {
			i := len(pp) - 1
			pp = append(pp[:i], pp[i+1:]...) // delete element at index i (last)
		}

		// Now, sum up the points
		sumPoints := 0
		for _, p := range pp {
			sumPoints += p
		}

		// Check if player has enough tournaments
		// TODO: Is this a property of season?
		enough := false
		if numPlayed[player] >= 11 {
			enough = true
		}

		standings = append(standings, &PlayerStanding{
			Player:     player,
			Results:    results[player],
			Winnings:   winnings[player],
			AvgPlace:   float64(sumPlace[player]) / float64(numPlayed[player]),
			Points:     sumPoints,
			NumHeadsUp: numHeadsUp[player],
			NumWins:    numWins[player],
			NumPlayed:  numPlayed[player],
			Enough:     enough,
			NumTotal:   numTotal,
			Knockouts:  knockouts[player],
		})
	}

	return standings
}
func NewStandings(tournaments Tournaments) PlayerStandings {

	// First, find all active players for these tournaments
	// Also, get the max number of players for a given set of tournaments
	// This gives us the basis for low point scoring
	activePlayers, maxPlayers := getActivePlayers(tournaments)

	// Then, loop through tournaments again to keep track of relevant stats
	winnings := make(map[uuid.UUID]int)
	sumPlace := make(map[uuid.UUID]int)
	points := make(map[uuid.UUID][]int)
	numHeadsUp := make(map[uuid.UUID]int)
	numWins := make(map[uuid.UUID]int)
	numPlayed := make(map[uuid.UUID]int)
	knockouts := make(map[uuid.UUID]int)
	results := make(map[uuid.UUID][]PlayerResult)
	numTotal := 0

	for _, t := range tournaments {
		if !t.Played || len(t.Result) == 0 {
			continue
		}
		numTotal += 1
		seenPlayer := make(map[uuid.UUID]bool)
		for i, player := range t.Result {
			place := i + 1
			results[player] = append(results[player], PlayerResult{
				Place:      place,
				When:       t.Info.Scheduled,
				NumPlayers: len(t.Result),
			})

			sumPlace[player] += place
			numPlayed[player] += 1
			seenPlayer[player] = true
			points[player] = append(points[player], place)

			switch place {
			case 1:
				numWins[player] += 1
				winnings[player] += (len(t.Result) - 2) * t.Info.Stake
				numHeadsUp[player] += 1
			case 2:
				numHeadsUp[player] += 1
			default:
				winnings[player] -= t.Info.Stake
			}
		}

		for _, player := range activePlayers {
			if _, seen := seenPlayer[player]; !seen {
				points[player] = append(points[player], maxPlayers+1)
			}
		}

		for player := range t.BountyHunters {
			knockouts[player] += len(t.BountyHunters[player])
		}
	}

	// Finally, loop through active players and set totals, returning standings
	var standings PlayerStandings

	for _, player := range activePlayers {

		// Remove worst point score at 10 and 20 played tournaments
		pp := points[player]
		sort.Ints(pp)

		if numPlayed[player] >= 10 {
			i := len(pp) - 1
			pp = append(pp[:i], pp[i+1:]...) // delete element at index i (last)
		}
		if numPlayed[player] >= 20 {
			i := len(pp) - 1
			pp = append(pp[:i], pp[i+1:]...) // delete element at index i (last)
		}

		// Now, sum up the points
		sumPoints := 0
		for _, p := range pp {
			sumPoints += p
		}

		// Check if player has enough tournaments
		// TODO: Is this a property of season?
		enough := false
		if numPlayed[player] >= 11 {
			enough = true
		}

		standings = append(standings, &PlayerStanding{
			Player:     player,
			Results:    results[player],
			Winnings:   winnings[player],
			AvgPlace:   float64(sumPlace[player]) / float64(numPlayed[player]),
			Points:     sumPoints,
			NumHeadsUp: numHeadsUp[player],
			NumWins:    numWins[player],
			NumPlayed:  numPlayed[player],
			Enough:     enough,
			NumTotal:   numTotal,
			Knockouts:  knockouts[player],
		})
	}

	return standings
}
func NewStandings ( tournaments Tournaments ) PlayerStandings { // First, find all active players for these tournaments // Also, get the max number of players for a given set of tournaments // This gives us the basis for low point scoring activePlayers , maxPlayers := getActivePlayers ( tournaments ) // Then, loop through tournaments again to keep track of relevant stats winnings := make ( map [ uuid . UUID ] int ) sumPlace := make ( map [ uuid . UUID ] int ) points := make ( map [ uuid . UUID ] [ ] int ) numHeadsUp := make ( map [ uuid . UUID ] int ) numWins := make ( map [ uuid . UUID ] int ) numPlayed := make ( map [ uuid . UUID ] int ) knockouts := make ( map [ uuid . UUID ] int ) results := make ( map [ uuid . UUID ] [ ] PlayerResult ) numTotal := 0 for _ , t := range tournaments { if ! t . Played || len ( t . Result ) == 0 { continue } numTotal += 1 seenPlayer := make ( map [ uuid . UUID ] bool ) for i , player := range t . Result { place := i + 1 results [ player ] = append ( results [ player ] , PlayerResult { Place : place , When : t . Info . Scheduled , NumPlayers : len ( t . Result ) , } ) sumPlace [ player ] += place numPlayed [ player ] += 1 seenPlayer [ player ] = true points [ player ] = append ( points [ player ] , place ) switch place { case 1 : numWins [ player ] += 1 winnings [ player ] += ( len ( t . Result ) - 2 ) * t . Info . Stake numHeadsUp [ player ] += 1 case 2 : numHeadsUp [ player ] += 1 default : winnings [ player ] -= t . Info . Stake } } for _ , player := range activePlayers { if _ , seen := seenPlayer [ player ] ; ! seen { points [ player ] = append ( points [ player ] , maxPlayers + 1 ) } } for player := range t . BountyHunters { knockouts [ player ] += len ( t . BountyHunters [ player ] ) } } // Finally, loop through active players and set totals, returning standings var standings PlayerStandings for _ , player := range activePlayers { // Remove worst point score at 10 and 20 played tournaments pp := points [ player ] sort . Ints ( pp ) if numPlayed [ player ] >= 10 { i := len ( pp ) - 1 pp = append ( pp [ : i ] , pp [ i + 1 : ] ... ) // delete element at index i (last) } if numPlayed [ player ] >= 20 { i := len ( pp ) - 1 pp = append ( pp [ : i ] , pp [ i + 1 : ] ... ) // delete element at index i (last) } // Now, sum up the points sumPoints := 0 for _ , p := range pp { sumPoints += p } // Check if player has enough tournaments // TODO: Is this a property of season? enough := false if numPlayed [ player ] >= 11 { enough = true } standings = append ( standings , & PlayerStanding { Player : player , Results : results [ player ] , Winnings : winnings [ player ] , AvgPlace : float64 ( sumPlace [ player ] ) / float64 ( numPlayed [ player ] ) , Points : sumPoints , NumHeadsUp : numHeadsUp [ player ] , NumWins : numWins [ player ] , NumPlayed : numPlayed [ player ] , Enough : enough , NumTotal : numTotal , Knockouts : knockouts [ player ] , } ) } return standings }
// TODO: Split into smaller functions
TODO : Split into smaller functions