func TestOptimalAttackVectorSort(t *testing.T) { rand.Seed(0) predator := vpTesterAgent(0.0, 0.0) predator.vsr = 1.0 predator.τ = colour.RGB{Red: 0.71, Green: 0.1, Blue: 0.39} prey := []ColourPolymorphicPrey{} for i := 1; i <= 10; i++ { agentA := cpPreyTesterAgent(calc.RandFloatIn(-1, 1), calc.RandFloatIn(-1, 1)) agentB := cpPreyTesterAgent(calc.RandFloatIn(-1, 1), calc.RandFloatIn(-1, 1)) agentA.colouration = colour.RGB{Red: rand.Float64(), Green: rand.Float64(), Blue: rand.Float64()} agentB.colouration = colour.RGB{Red: rand.Float64(), Green: rand.Float64(), Blue: rand.Float64()} prey = append(prey, agentA) prey = append(prey, agentB) } c := math.Pow(2, 3) f := visualSignalStrength(c) optimals := []visualRecognition{} for i := range prey { 𝛘 := colour.RGBDistance(predator.τ, prey[i].colouration) δ, _ := geometry.VectorDistance(predator.pos, prey[i].pos) // fmt.Printf("%v\t%v\t%v\t%p\n", i, 𝛘, δ, &prey[i]) a := visualRecognition{δ, 𝛘, f, c, &prey[i]} optimals = append(optimals, a) }
// RandRGBClamped will return a random valid RGB object within some differential of `col` func RandRGBClamped(col RGB, diff float64) RGB { diff = rand.NormFloat64() * diff red := col.Red + calc.RandFloatIn(-diff, diff) green := col.Green + calc.RandFloatIn(-diff, diff) blue := col.Blue + calc.RandFloatIn(-diff, diff) red = calc.ClampFloatIn(red, 0.0, 1.0) green = calc.ClampFloatIn(green, 0.0, 1.0) blue = calc.ClampFloatIn(blue, 0.0, 1.0) return RGB{red, green, blue} }
// Action = Rule Based Behaviour that each cpPrey agent engages in once per turn, counts as the agent's action for that turn/phase. func (c *ColourPolymorphicPrey) Action(conditions ConditionParams, popSize int) (newpop []ColourPolymorphicPrey) { newkids := []ColourPolymorphicPrey{} jump := "" // BEGIN jump = c.Age(conditions) switch jump { case "DEATH": goto End case "SPAWN": progeny := c.Birth(conditions) // max spawn size, mutation factor newkids = append(newkids, progeny...) case "FERTILE": if popSize <= conditions.CpPreyPopulationCap { c.Reproduction(conditions.CpPreyReproductionChance, conditions.CpPreyGestation) } fallthrough case "EXPLORE": � := calc.RandFloatIn(-conditions.CpPreyTurn, conditions.CpPreyTurn) c.Turn(�) c.Move() } newpop = append(newpop, *c) End: newpop = append(newpop, newkids...) // add the newly created children to the returning population return }
func TestCPPComparitorSort(t *testing.T) { rand.Seed(0) predator := vpTesterAgent(0.0, 0.0) predator.vsr = 1.0 predator.τ = colour.RGB{Red: 0.71, Green: 0.1, Blue: 0.39} prey := []ColourPolymorphicPrey{} for i := 1; i <= 10; i++ { agentA := cpPreyTesterAgent(calc.RandFloatIn(-1, 1), calc.RandFloatIn(-1, 1)) agentB := cpPreyTesterAgent(calc.RandFloatIn(-1, 1), calc.RandFloatIn(-1, 1)) agentA.colouration = colour.RGB{Red: rand.Float64(), Green: rand.Float64(), Blue: rand.Float64()} agentB.colouration = colour.RGB{Red: rand.Float64(), Green: rand.Float64(), Blue: rand.Float64()} prey = append(prey, agentA) prey = append(prey, agentB) } f := func(v geometry.Vector) func(geometry.Vector) float64 { return func(u geometry.Vector) float64 { dist, _ := geometry.VectorDistance(v, u) return dist } }(predator.pos) compers := []compCPP{} for i := range prey { // fmt.Printf("%v\t%v\t%p\n", i, prey[i].pos, &prey[i]) a := compCPP{f, &prey[i]} compers = append(compers, a) } sort.Sort(byComparitor(compers)) // for i := range compers { // fmt.Printf("%v\t%v\t%p\t%v\n", i, compers[i].pos, compers[i].ColourPolymorphicPrey, f(compers[i].pos)) // } want := fmt.Sprintf("%p", &prey[19]) got := fmt.Sprintf("%p", &(*compers[0].ColourPolymorphicPrey)) if want != got { t.Errorf("want:\n%q\ngot:\n%q\n", want, got) } }
// RandVector will give a random vector within boundaries the axes of len(bounds) dimensions func RandVector(bounds []float64) Vector { var v Vector for i := 0; i < len(bounds); i++ { d := bounds[i] val := calc.RandFloatIn(-d, d) v = append(v, val) } return v }
// FuzzifyVector will return a a 'fuzzy', slightly randomised version of v, at a random variance in range (-ε, +ε) offset from each existing element of v. func FuzzifyVector(v Vector, ε float64) (Vector, error) { if len(v) == 0 { return nil, errors.New("v is an empty vector") } vf := v for i := 0; i < len(vf); i++ { vf[i] = vf[i] + calc.RandFloatIn(-ε, ε) } return vf, nil }
// Action : Rule-Based-Behaviour for Visual Predator Agent func (vp *VisualPredator) Action(errCh chan<- error, conditions ConditionParams, start int, turn int, cpPreyPop []ColourPolymorphicPrey, neighbours []VisualPredator, me int) []VisualPredator { var returning []VisualPredator var Φ float64 popSize := len(neighbours) jump := vp.Age(conditions, popSize) switch jump { case "DEATH": goto End case "PREY SEARCH": success := vp.SearchAndAttack(cpPreyPop, conditions, errCh) if success { goto Add } goto Patrol case "FERTILE": if len(neighbours) <= 0 { goto Patrol } mate := vp.MateSearch(neighbours, me, errCh) success := vp.Copulation(mate, conditions) if !success { goto Patrol } case "SPAWN": children := vp.Birth(conditions, start, turn) returning = append(returning, children...) default: log.Println("vp.Action Switch: FAIL: jump =", jump) } Patrol: Φ = calc.RandFloatIn(-vp.tr, vp.tr) vp.Turn(Φ) vp.Move() Add: returning = append(returning, *vp) End: return returning }
// RandRGB will return a random valid RGB object within the complete range of all possible RGB values. func RandRGB() RGB { red := calc.RandFloatIn(0, math.Nextafter(1.0, 2.0)) green := calc.RandFloatIn(0, math.Nextafter(1.0, 2.0)) blue := calc.RandFloatIn(0, math.Nextafter(1.0, 2.0)) return RGB{red, green, blue} }