// Run executes Step repeatedly, until Step returns an error, at which point this // method will invoke o.Die and return. func (c *Cpu) Run(o *org.Organism) error { Logger.Printf("%v.Run(%v)\n", c, o) for { if err := c.Step(o); err != nil { Logger.Printf("%v.Run: %v\n", c, err) o.Die() return err } } }
// opSenseOthers: sense energy ahead, excluding those with the same bytecode, capped at 255 func opSenseOthers(o *org.Organism, c *Cpu) error { filter := func(n interface{}) float64 { if org, ok := n.(*org.Organism); ok { if nc, ok := org.Driver.(*Cpu); ok { if c.Hash() == nc.Hash() { return 0.0 } } } return 1.0 } c.R[0] = clip(int(o.Sense(filter)), 0, 255) return nil }
// Step executes one CPU operation. Any error returned either assessing the // operation's energy cost or executing it will be returned by this method. // Execution is expected to cease (and the organism's Die method // invoked) if an error is returned. func (c *Cpu) Step(o *org.Organism) (err error) { op, ip := c.readOp() c.Ip = ip if op == nil { return unableToReadErr } Logger.Printf("%v.Step(%v): %v\n", c, o, op) // All operations cost at least 1 energy, to avoid infinite loops. if err := o.Discharge(1 + op.Cost); err != nil { return err } if err := op.Fn(o, c); err != nil { return err } return nil }
// opDivide: spawn a new organism in neighboring cell with same bytecode // and energy fraction described by A/256. func opDivide(o *org.Organism, c *Cpu) error { lenc := len(c.Code) if err := o.Discharge(lenc); err != nil { return err } nc := c.Copy() if rand.Float64() < MutationRate { nc.Mutate() } n, err := o.Divide(nc, float64(c.R[0])/256.0) if err == org.ErrNotEmpty { return nil } if err != nil { return err } go nc.Run(n) return nil }
// opSense: sense energy ahead, capped at 255 func opSense(o *org.Organism, c *Cpu) error { c.R[0] = clip(int(o.Sense(nil)), 0, 255) return nil }
// opForward: move forward if able func opForward(o *org.Organism, c *Cpu) error { if err := o.Forward(); err != nil && err != org.ErrNotEmpty { return err } return nil }
// opRight: turn right func opRight(o *org.Organism, c *Cpu) error { o.Right() return nil }
// opLeft: turn left func opLeft(o *org.Organism, c *Cpu) error { o.Left() return nil }
// opEat: Consume A*10 energy from neighbor func opEat(o *org.Organism, c *Cpu) error { if _, err := o.Eat(c.R[0] * 10); err != nil { return err } return nil }