Last active
September 3, 2019 09:05
-
-
Save amatiasq/2af7e9b20ca6930e0dcf92e0ea246ab2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const a = new Life(); | |
a.pos = new Vector(10, 10); | |
a.setParameter(Parameter.ENERGY, 100); | |
a.setParameter(Parameter.WEIGHT, 1); | |
a.setParameter(Parameter.FOOD, x => x.hasParameter(Parameter.IS_PLANT)); | |
a.addSense(new Sight({ radius: 10, angle: 270, precision: 1 })) | |
a.addSense(new Hearing({ radius: 1, angle: 360, }) | |
a.addBehaviour(new FlockingBehaviour(), { intensity: 0.5 }); | |
a.addBehaviour(new PredatorBehaviour(), { intensity: 1 }); | |
a.addBehaviour(new PeopleBehaviour(), { intensity: 0.2 }); | |
a.tick(world); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type ConstructorOf<T> = new() => T; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IBehaviour { | |
tick(event: TickEvent); | |
reset(); // kind of Tick destructor, to remove any cache for the tick | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ISense { | |
sense(at: IVector, world: IWorld): Life[]; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IVector { | |
readonly x: number; | |
readonly y: number; | |
multiply(value: number): IVector; | |
merge(other: IVector): IVector; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IWorld { | |
getEntitiesAt(center: IVector, radius: number): Life[]; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Life { | |
pos: IVector; | |
acceleration: IVector; | |
private readonly parameters = new Map<Parameter, any>(); | |
private readonly senses: ISense[] = []; | |
private readonly behaviours = new Map(); | |
setParameter(param: Parameter, value: any) { | |
this.parameters.set(param, value); | |
} | |
getParameter<T>(param: Parameter) { | |
return this.parameters.get(param) as T; | |
} | |
addSense(sense: ISense) { | |
this.senses.push(sense); | |
} | |
getSenses() { | |
return this.senses; | |
} | |
addBehaviour(behaviour: IBehaviour, { intensity }: { intensity: number } = { intensity: 1 }) { | |
this.behaviours.set(behaviour.constructor, { | |
implementation: behaviour, | |
intensity | |
}); | |
} | |
getBehaviour<T>(Class: ConstructorOf<T>): T { | |
const entry = this.behaviours.get(Class); | |
return entry && entry.implementation; | |
} | |
shove(force) { | |
this.acceleration = this.acceleration.merge(force); | |
} | |
tick(world: IWorld) { | |
// Can be cached | |
const event = new TickEvent(this, world); | |
this.behaviours.forEach(({ implementation, intensity }) => { | |
event.intensity = intensity; | |
implementation.tick(event); | |
}); | |
const force = event.getWillForce(); | |
if (force) { | |
this.shove(force); | |
} | |
} | |
reset() { | |
this.behaviours.forEach(({ implementation }) => implementation.reset()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum Parameter { | |
ENERGY, | |
WEIGHT, | |
FOOD, | |
IS_PLANT, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FlockingBehaviour implements IBehaviour { | |
private _isFlocking = false; | |
get isFlocking() { | |
return this._isFlocking; | |
} | |
tick(event: TickEvent) { | |
const neighbors = event.useSenses(); | |
const flockings = neighbors | |
.map(x => x.getBehaviour(FlockingBehaviour)) | |
.filter(Boolean); | |
if (flockings.some(x => x.isFlocking)) { | |
this._isFlocking = true; | |
... | |
event.setWill(flockingDirection); | |
} | |
} | |
reset() { | |
this._isFlocking = false; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TickEvent { | |
intensity = 1; | |
private readonly pushes: IVector[] = []; | |
constructor( | |
private readonly self: Life, | |
private readonly world: IWorld | |
) {} | |
useSenses(): Life[] { | |
const senses = this.self.getSenses(); | |
return senses.flatMap(x => x.sense(this.self.pos, this.world)); | |
} | |
setWill(force: IVector) { | |
this.pushes.push(force.multiply(this.intensity)); | |
} | |
getWillForce() { | |
return this.pushes.reduce((a, b) => a.merge(b)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment