// 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 }