public Wall(Vec p1, Vec p2) { this.p1 = p1; this.p2 = p2; }
public void tick() { // tick the environment this.clock++; // fix input to all agents based on environment for (int i = 0, n = this.agents.Count; i < n; i++) { var a = this.agents[i]; for (int ei = 0, ne = a.eyes.Count; ei < ne; ei++) { var e = a.eyes[ei]; // we have a line from p to p->eyep var eyep = new Vec((float)a.p.X + (float)e.max_range * (float)Math.Sin(a.angle + e.angle), (float)a.p.Y + e.max_range * (float)Math.Cos(a.angle + e.angle)); var res = this.stuff_collide_(a.p, eyep, true, true); if (res != null) { // eye collided with wall e.sensed_proximity = res.up.dist_from(a.p); e.sensed_type = res.type; } else { e.sensed_proximity = e.max_range; e.sensed_type = -1; } } } // let the agents behave in the world based on their input for (int i = 0, n = this.agents.Count; i < n; i++) { this.agents[i].forward(); } // apply outputs of agents on evironment for (int i = 0, n = this.agents.Count; i < n; i++) { var a = this.agents[i]; a.op = a.p; // back up old position a.oangle = a.angle; // and angle // steer the agent according to outputs of wheel velocities var v = new Vec(0, a.rad / 2.0f); v = v.rotate(a.angle + (float)Math.PI / 2); var w1p = a.p.add(v); // positions of wheel 1 and 2 var w2p = a.p.sub(v); var vv = a.p.sub(w2p); vv = vv.rotate(-a.rot1); var vv2 = a.p.sub(w1p); vv2 = vv2.rotate(a.rot2); var np = w2p.add(vv); np.scale(0.5f); var np2 = w1p.add(vv2); np2.scale(0.5f); a.p = np.add(np2); a.angle -= a.rot1; if (a.angle < 0) { a.angle += 2 * (float)Math.PI; } a.angle += a.rot2; if (a.angle > 2 * Math.PI) { a.angle -= 2 * (float)Math.PI; } // agent is trying to move from p to op. Check walls var res = this.stuff_collide_(a.op, a.p, true, false); if (res != null) { // wall collision! reset position a.p = a.op; } // handle boundary conditions if (a.p.X < 0) { a.p.X = 0; } if (a.p.X > this.W) { a.p.X = this.W; } if (a.p.Y < 0) { a.p.Y = 0; } if (a.p.Y > this.H) { a.p.Y = this.H; } } // tick all items var update_items = false; for (int i = 0, n = this.items.Count; i < n; i++) { var it = this.items[i]; it.age += 1; // see if some agent gets lunch for (int j = 0, m = this.agents.Count; j < m; j++) { var a = this.agents[j]; var d = a.p.dist_from(it.p); if (d < it.rad + a.rad) { // wait lets just make sure that this isn't through a wall var rescheck = this.stuff_collide_(a.p, it.p, true, false); if (rescheck == null) { // ding! nom nom nom if (it.type == 1) { a.digestion_signal += 5.0f; // mmm delicious apple } if (it.type == 2) { a.digestion_signal += -6.0f; // ewww poison } it.cleanup_ = true; update_items = true; break; // break out of loop, item was consumed } } } if (it.age > 5000 && this.clock % 100 == 0 && Util.RandF(0, 1) < 0.1) { it.cleanup_ = true; // replace this one, has been around too long update_items = true; } } if (update_items) { var nt = new List <Item>(); for (int i = 0, n = this.items.Count; i < n; i++) { var it = this.items[i]; if (!it.cleanup_) { nt.Add(it); } } this.items = nt; // swap } if (this.items.Count < 30 && this.clock % 10 == 0 && Util.RandF(0, 1) < 0.25) { var newitx = Util.RandF(20, this.W - 20); var newity = Util.RandF(20, this.H - 20); var newitt = Util.Randi(1, 3); // food or poison (1 and 2) var newit = new Item(newitx, newity, newitt); this.items.Add(newit); } // agents are given the opportunity to learn based on feedback of their action on environment for (int i = 0, n = this.agents.Count; i < n; i++) { this.agents[i].backward(); } }
public Vec add(Vec v) { return(new Vec(this.X + v.X, this.Y + v.Y)); }
public Vec sub(Vec v) { return(new Vec(this.X - v.X, this.Y - v.Y)); }
public float dist_from(Vec v) { return((float)Math.Sqrt(Math.Pow(this.X - v.X, 2) + Math.Pow(this.Y - v.Y, 2))); }