-
Notifications
You must be signed in to change notification settings - Fork 1
/
SimulationSystem.js
126 lines (106 loc) · 3.77 KB
/
SimulationSystem.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const HEALTH_PLUS = 30;
const HEALTH_MINUS = 40;
const NEW_TARGET_PROB = 0.5;
const NEW_VEHICLE_CONST = 0.1;
const AGING_CONST = 0.07;
const TARGET_THRESHOLD = 50;
let maxgen = 0;
let maxfitness = 0;
class Simulation {
constructor() {
this.vehicles = [];
this.targets = [];
}
addVehicles(count) {
for (let i = 0; i < count; i++) {
this.vehicles.push(new Vehicle(random(100, width - 100), random(100, height - 100)));
}
}
addTargets(count, typ) {
for (let i = 0; i < count; i++) {
this.targets.push(new Target(random(width), random(height), 5, typ));
}
}
reproduceVehicle() {
for (const vehicle of this.vehicles) {
let r = random();
if (r < 1 / this.vehicles.length * NEW_VEHICLE_CONST) {
let dna = new DNA([
vehicle.maxspeed,
vehicle.maxforce,
vehicle.seekgood,
vehicle.seekbad,
vehicle.generation + 1,
])
dna.mutation();
this.vehicles.push(vehicle.copyVec(dna));
}
}
}
reproduceTarget() {
let r = random();
if (r < 0.05 * (10 / this.targets.length)) {
this.targets.push(new Target(random(width), random(height), 5, 'good'));
} else if (r < 0.07 * (10 / this.targets.length)) {
this.targets.push(new Target(random(width), random(height), 5, 'bad'));
}
}
run() {
for (let i = this.targets.length - 1; i >= 0; i--) {
let target = this.targets[i];
target.addBorder();
target.update();
target.display();
let v = null;
for (let j = this.vehicles.length - 1; j >= 0; j--) {
let maxf = 0;
let vehicle = this.vehicles[j];
if (vehicle.generation > maxgen) {
maxgen = vehicle.generation;
}
if (vehicle.counter > maxfitness) {
maxfitness = vehicle.counter;
}
if (vehicle.counter > maxf) {
maxf = vehicle.counter;
v = vehicle;
}
// Kill vechile and put target instead
if (vehicle.health < 0) {
this.vehicles.splice(j, 1);
if (random() < 1 / this.targets.length * NEW_TARGET_PROB) {
this.targets.push(new Target(vehicle.pos.x, vehicle.pos.y, 5, 'good'));
}
if (this.targets.length > TARGET_THRESHOLD) {
if (random() < this.targets.length * NEW_TARGET_PROB / 10) {
this.targets.shift();
}
}
}
vehicle.addBorder();
// Call the appropriate steering behaviors for our agents
vehicle.search(target);
vehicle.update(log(this.vehicles.length) * AGING_CONST);
vehicle.display(target);
if (Collision.isCollide(target, vehicle)) {
if (target.typ == 'good') {
vehicle.health += HEALTH_PLUS;
// print("Boom!");
} else {
vehicle.health -= HEALTH_MINUS;
// print("Opps!");
}
this.targets.splice(i, 1);
}
}
if (v) {
push()
noFill();
stroke('white');
ellipse(v.pos.x, v.pos.y, 30);
pop();
v.displayDNA();
}
}
}
}