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
	}
}
Can change the fitness of the organisms in the Species to be higher for very new species (to protect them).
Divides the fitness by the size of the Species, so that fitness is "shared" by the species.
NOTE: Invocation of this method will result of species organisms sorted by fitness in descending order, i.e. most fit will be first.
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
	}
}