protected override EnvShooter.Action GetAction() { Vector2 move_target = new Vector2(this.Pos.X, 20); Vector2 aim_target = new Vector2(0, 0); if (env.Bullets.Length == 0) { move_target.Y = this.Pos.Y; } EnvShooter.Bot[] bots = this.enemies.ToList().FindAll(x => x.Alive).ToArray(); aim_target = bots[rand.Next(bots.Length)].Pos; bool do_charge = false;//this.Id == 0; Bullet[] collectible_bullets = this.env.Bullets.ToList().FindAll(x => x.Collectible).ToArray(); Bullet[] active_bullets = this.env.Bullets.ToList().FindAll(x => !x.Collectible).ToArray(); Vector2[,] bullet_poses = BulletSim3.Get_Bullet_Poses(active_bullets, this.map, frames_till_hit_max); /* MOVEMENT START */ MovementDecision md = new MovementDecision(bullet_poses); // Add the most desired position first and least desired one last // 1. Get out of danger Zone if (InMortalDanger(this.Pos, enemies[0].Pos)) { Vector2 rel_vec = -(enemies[0].Pos - this.Pos); if (!IsPosInWall(this.Pos + rel_vec)) { md.desired_poses.Add(TargetToNextFramePos(this.Pos + rel_vec)); } } // 2. Get to collectable List <Tuple <float, Vector2> > collectible_dists = collectible_bullets.Select(x => new Tuple <float, Vector2>(Vector2.Distance(x.Pos, this.Pos), x.Pos)).ToList(); collectible_dists.OrderBy(x => x.Item1); for (int i = 0; i < collectible_dists.Count; i++) { if (!InMortalDanger(collectible_dists[i].Item2, enemies[0].Pos)) { md.desired_poses.Add(TargetToNextFramePos(collectible_dists[i].Item2)); } } //if (!InMortalDanger(new Vector2(9, 9), enemies[0].Pos) && // !InNoChargeSafeZone(new Vector2(9, 9), enemies[0].Pos)) // md.desired_poses.Add(TargetToNextFramePos(new Vector2(9, 9))); // 3. Get to edge of no charge safe zone if (InSafety(this.Pos, enemies[0].Pos)) { Vector2 rel_vec = (enemies[0].Pos - this.Pos); if (!IsPosInWall(this.Pos + rel_vec)) { md.desired_poses.Add(TargetToNextFramePos(this.Pos + rel_vec)); } } else if (InNoChargeSafeZone(this.Pos, enemies[0].Pos)) { Vector2 rel_vec = -(enemies[0].Pos - this.Pos); if (!IsPosInWall(this.Pos + rel_vec)) { md.desired_poses.Add(TargetToNextFramePos(this.Pos + rel_vec)); } } // Add backup targets Vector2[] move_vecs = new Vector2[] { new Vector2(1, -1), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1), new Vector2(-1, 1), new Vector2(-1, 0), new Vector2(-1, -1), new Vector2(0, -1) }; for (int i = 0; i < move_vecs.Length; i++) { md.desired_poses.Add(TargetToNextFramePos(this.Pos + move_vecs[i])); } md.desired_poses.Add(Vector2.Zero); move_target = md.GetOptimalPos(this.Pos); /* MOVEMENT END */ color = md.IsMovementTargetSafe == true ? Color.DeepPink : Color.Purple; /* CHARGE START */ if (InMortalDanger(move_target, enemies[0].Pos) || md.IsMovementTargetSafe == false) { do_charge = false; } else { // Fully charged if (this.Charge >= 0.95) { // Only shoot in no charge safety zone if (InNoChargeSafeZone(this.Pos, enemies[0].Pos)) { do_charge = false; } else { do_charge = true; } } else { do_charge = true; } } /* CHARGE END */ //if (this.Id == 0) // do_charge = false; EnvShooter.Action action = GoToXY(move_target); action.aim = AimToPos(aim_target); action.charge = do_charge; return(action); }
public Vector2 GetOptimalPos(Vector2 pos) { Vector2 point_out = Vector2.Zero; for (int i = 1; i < 10; i++) { Vector2[] poses = new Vector2[desired_poses.Count]; for (int j = 0; j < desired_poses.Count; j++) { poses[j] = pos + (desired_poses[j] * (float)i); } int[] col_steps = new int[desired_poses.Count]; for (int j = 0; j < col_steps.Length; j++) { // Border check if (poses[j].X - 0.4f < 1 || poses[j].X + 0.4f > 19 || poses[j].Y - 0.4f < 1 || poses[j].Y + 0.4f > 19) { col_steps[j] = 4; continue; } // Bullet collision check int min_bullet = BulletSim3.CollidesWith(poses[j], 0.6f, bullet_poses); // No collisions if (min_bullet == -1) { col_steps[j] = -1; break; } else { col_steps[j] = min_bullet; } } int max_dist = -1; int max_dist_idx = -1; bool minus_one_found = false; for (int j = 0; j < col_steps.Length; j++) { if (col_steps[j] == -1) { point_out = poses[j]; minus_one_found = true; break; } else if (col_steps[j] > max_dist) { max_dist = col_steps[j]; max_dist_idx = j; } } if (minus_one_found == false) { point_out = poses[max_dist_idx]; this.IsMovementTargetSafe = false; } else { this.IsMovementTargetSafe = true; break; } } return(point_out); }