func (s *Species) FindChampion() *Organism {
	champFitness := -1.0
	var champion *Organism
	for _, org := range s.Organisms {
		if org.Fitness > champFitness {
			champFitness = org.Fitness
			champion = org
		}
	}
	return champion
}
FindChampion Returns most fit organism for this species
package genetics
import (
	"context"
	"errors"
	"fmt"
	"github.com/yaricom/goNEAT/v2/neat"
	"io"
	"math"
	"math/rand"
	"sort"
)
type Species struct {
	Id int
	Age int
	MaxFitnessEver float64
	ExpectedOffspring int
	IsNovel bool
	Organisms Organisms
	AgeOfLastImprovement int
	IsChecked bool
}
func NewSpecies(id int) *Species {
	return newSpecies(id)
}
func NewSpeciesNovel(id int, novel bool) *Species {
	s := newSpecies(id)
	s.IsNovel = novel
	return s
}
func newSpecies(id int) *Species {
	return &Species{
		Id:        id,
		Age:       1,
		Organisms: make([]*Organism, 0),
	}
}
func (s *Species) Write(w io.Writer) error {
	_, avg := s.ComputeMaxAndAvgFitness()
	if _, err := fmt.Fprintf(w, "/* Species #%d : (Size %d) (AF %.3f) (Age %d)  */\n",
		s.Id, len(s.Organisms), avg, s.Age); err != nil {
		return err
	}
	sortedOrganisms := make(Organisms, len(s.Organisms))
	copy(sortedOrganisms, s.Organisms)
	sort.Sort(sort.Reverse(sortedOrganisms))
	for _, org := range sortedOrganisms {
		if _, err := fmt.Fprintf(w, "/* Organism #%d Fitness: %.3f Error: %.3f */\n",
			org.Genotype.Id, org.Fitness, org.Error); err != nil {
			return err
		}
		if org.IsWinner {
			if _, err := fmt.Fprintf(w, "/* ## $ WINNER ORGANISM FOR SPECIES #%d $ ## */\n", s.Id); err != nil {
				return err
			}
		}
		if err := org.Genotype.Write(w); err != nil {
			return err
		}
	}
	return nil
}
func (s *Species) addOrganism(o *Organism) {
	s.Organisms = append(s.Organisms, o)
}
func (s *Species) removeOrganism(org *Organism) (bool, error) {
	orgs := make([]*Organism, 0)
	for _, o := range s.Organisms {
		if o != org {
			orgs = append(orgs, o)
		}
	}
	if len(orgs) != len(s.Organisms)-1 {
		return false, fmt.Errorf("attempt to remove nonexistent Organism from Species with #of organisms: %d", len(s.Organisms))
	} else {
		s.Organisms = orgs
		return true, nil
	}
}
func (s *Species) adjustFitness(opts *neat.Options) {
	ageDebt := (s.Age - s.AgeOfLastImprovement + 1) - opts.DropOffAge
	if ageDebt == 0 {
		ageDebt = 1
	}
	for _, org := range s.Organisms {
		org.originalFitness = org.Fitness
		if ageDebt >= 1 {
			org.Fitness = org.Fitness * 0.01
		}
		if s.Age <= 10 {
			org.Fitness = org.Fitness * opts.AgeSignificance
		}
		if org.Fitness < 0.0 {
			org.Fitness = 0.0001
		}
		org.Fitness = org.Fitness / float64(len(s.Organisms))
	}
	sort.Sort(sort.Reverse(s.Organisms))
	if s.Organisms[0].originalFitness > s.MaxFitnessEver {
		s.AgeOfLastImprovement = s.Age
		s.MaxFitnessEver = s.Organisms[0].originalFitness
	}
	numParents := int(math.Floor(opts.SurvivalThresh*float64(len(s.Organisms)) + 1.0))
	s.Organisms[0].isChampion = true  
	for c := numParents; c < len(s.Organisms); c++ {
		s.Organisms[c].toEliminate = true
	}
}
func (s *Species) ComputeMaxAndAvgFitness() (max, avg float64) {
	total := 0.0
	for _, o := range s.Organisms {
		total += o.Fitness
		if o.Fitness > max {
			max = o.Fitness
		}
	}
	if len(s.Organisms) > 0 {
		avg = total / float64(len(s.Organisms))
	}
	return max, avg
}