private bool cast_to_all(Ray ray) { // if mistake_happened repeat // if mistakes.count is 256 return iteration = 0; while (Program.ApplicationRunning && iteration++ < 255) { l = ray.laser.L; nearest_danger = l; nearest_edible = l; d = 160; lock (Blast.BlastLock) { foreach (Circle blast in Blast.All) { nearest_edible = Math.Min(nearest_edible, ray.AutoDistance(blast)); } } lock (ActiveLock) { foreach (Keys k in ActiveKeys) { if (k != key) { nearest_danger = Math.Min(nearest_danger, ray.AutoDistance(HEADS[k])); } } } lock (Orb.OrbLock) { foreach (Orb orb in Orb.All) { if (orb.isWhite) { nearest_edible = Math.Min(nearest_edible, ray.AutoDistance(orb)); } } for (int i = Orb.All.Count - 1; i >= 0; i--) { d = ray.AutoDistance(Orb.All[i]); if (Orb.All[i].isDangerTo(key)) { nearest_danger = Math.Min(nearest_danger, d); if (Orb.All[i].pos * HEAD.pos <= m + OrbR && (Map.InOrbit(HEAD.pos) != (HEAD.act == Activities.DEFAULT))) { if (SyncUpdate) { new Thread(action).Start(); } else { action(); } return(true); } } } } if (nearest_danger < l && nearest_danger <= nearest_edible) { if (nearest_danger == nearest_edible) { continue; } action(); return(true); } return(false); } return(false); }
private void update() { if (pressed) { if (counter++ >= 5) { pressed = false; HEAD.key.Release(); } } if (state != States.INGAME || HEAD.Died || HEAD.Dashing || HEAD.act == Activities.STARTROUND) { return; } // distance Orb or Blast in straight line // any Head in danger zone // dangerous Orb in danger zone // nearest dangerous Orb // distance to orbit side // in orbit or not ray.Set(HEAD.pos, HEAD.v); bool in_orbit = Map.InOrbit(HEAD.pos); distances.Add(diagonal); foreach (Circle orbit in Map.Orbits) { if (ray.Hit(orbit)) { distances.Add(ray.Distance(orbit)); } } double d_orbit = distances.Min(); distances.Clear(); ray.laser.L = 160; if (cast_to_all(ray)) { return; } ray.laser.L = m * 2; ray.laser.A -= Math.PI / 6; if (cast_to_all(ray)) { return; } ray.laser.A += Math.PI / 3; if (cast_to_all(ray)) { return; } n_edible = diagonal; ray.laser.A = HEAD.v.A; ray.laser.L = diagonal; lock (Orb.OrbLock) { foreach (Orb orb in Orb.All) { if (orb.isWhite) { n_edible = Math.Min(n_edible, ray.AutoDistance(orb)); } } } lock (Blast.BlastLock) foreach (Circle blast in Blast.All) { n_edible = Math.Min(n_edible, ray.AutoDistance(blast)); } if (HEAD.Orbiting) { if (n_edible < diagonal) { action(); return; } } else { if (in_orbit && d_orbit < HeadR && n_edible == diagonal) { action(); return; } } }
private void fetch_input() { //inorbit, rotation, x, y, orbs in tail //twelve rays //each has distance to first { orbit, blast, orb, orb, player } //type: player | blast | orb(w) | orb(p) | wall | orbits //65 input nodes total if (!HEADS.ContainsKey(Key) || Map.phase != Phases.NONE) { return; } Head head = HEADS[Key]; if (head.Died) { return; } ray.Set(head.pos, head.v); Input[0].add(BoolToInt(Map.InOrbit(head.pos))); Input[1].add(head.v.A / PI); Input[2].add(head.pos.X / W * 2 - 1); Input[3].add(head.pos.Y / W); lock (Orb.OrbLock) Input[4].add(head.tail.length == 0? -1 : 1 / head.tail.length); for (int i = 0; i < 12; i++) { foreach (Circle orbit in Map.Orbits) { if (ray.Hit(orbit)) { distances.Add(ray.Distance(orbit)); } } if (distances.Count == 0) { distances.Add(diagonal); } Input[5 + 5 * i].add(distances.Min() / diagonal); distances.Clear(); lock (Blast.BlastLock) foreach (Circle blast in Blast.All) { if (ray.Hit(blast)) { distances.Add(ray.Distance(blast)); } } if (distances.Count == 0) { distances.Add(diagonal); } Input[6 + 5 * i].add(distances.Min() / diagonal); distances.Clear(); lock (Orb.OrbLock) { int color = 760; double d = diagonal; double d_temp; foreach (Orb orb in Orb.All) { if (orb.state == (byte)OrbStates.TRAVELLING) { d_temp = ray.AutoDistance(orb); } else { d_temp = diagonal; } if (d_temp < d) { d = d_temp; color = (orb.color.R + orb.color.G + orb.color.B); } } Input[7 + 5 * i].add(d / diagonal); Input[8 + 5 * i].add(color / 760d); } lock (ActiveLock) foreach (Keys k in ActiveKeys) { if (k != Key && ray.Hit(HEADS[k])) { distances.Add(ray.Distance(HEADS[k])); } } if (distances.Count == 0) { distances.Add(diagonal); } Input[9 + 5 * i].add(distances.Min() / diagonal); distances.Clear(); ray.laser.A += deltaA; } // 66th input neuron Input[65].add(1); // Always on }