コード例 #1
0
ファイル: org.go プロジェクト: dnesting/alife
// Divide spawns a new organism in the neighboring cell in the direction the
// organism is pointing.  Energy from the parent, multiplied by energyFrac, will
// be transferred to the child to give it something to start off with.  The
// returns organism will be associated with a grid2d.Locator and given driver,
// but still requires the caller spawn a goroutine to drive it.  Returns nil and
// an error if there was insufficient energy to divide, or if the cell the child
// would be spawned within is already occupied by anything other than Food.
func (o *Organism) Divide(driver interface{}, energyFrac float64) (*Organism, error) {
	Logger.Printf("%v.Divide(%v, %v)\n", o, driver, energyFrac)
	if err := o.Discharge(BodyEnergy); err != nil {
		return nil, err
	}

	n := Random()
	n.Driver = driver
	dx, dy := o.delta(1)
	if _, loc := o.loc.Put(dx, dy, n, PutWhenFood); loc != nil {
		energy.Transfer(n, o, int(float64(o.Energy())*energyFrac))
		Logger.Printf("- parent: %v\n", o)
		Logger.Printf("-  child: %v\n", n)
		runtime.Gosched()
		return n, nil
	}
	return nil, ErrNotEmpty
}
コード例 #2
0
ファイル: org.go プロジェクト: dnesting/alife
// Eat attempts to transfer energy from the occupant in the neighboring cell in the
// direction the organism points.  Returns the amount transferred successfully or
// an error if there was insufficient energy to complete the action.
func (o *Organism) Eat(amt int) (int, error) {
	Logger.Printf("%v.Eat(%v)\n", o, amt)
	if err := o.Discharge(int(math.Ceil(float64(amt) / 100.0))); err != nil {
		return 0, err
	}
	if n := o.loc.Get(o.delta(1)); n != nil {
		Logger.Printf("- got %v\n", n.Value())
		if n, ok := n.Value().(energy.Energetic); ok {
			amt, _, _ = energy.Transfer(o, n, amt)
			Logger.Printf("- transferred %v\n", amt)
			Logger.Printf("  - %v\n", o)
			Logger.Printf("  - %v\n", n)
			runtime.Gosched()
			return -amt, nil
		} else {
			Logger.Printf("- not energetic\n")
		}
	}
	return 0, nil
}