public String Shoot(double polarAngle, double scanAngle, int energy, String attackCode) { string bigoutput = ""; if (this.Energy < energy) { Console.WriteLine("You do not have enough energy to shoot"); return(null); } this.Energy -= energy; // cordinates of the spaceship // cordinates of the spaceship double x = this.XCoordinate; double y = this.YCoordinate; int r = this.Capacity / 100; ArrayList list = new ArrayList(); int dist = (int)Math.Round(energy / Math.Abs(Math.Sin((Math.PI - scanAngle) / 2 * Math.PI / 180.0)), 0); double xA = Math.Round(x + r * Math.Cos(polarAngle * Math.PI / 180.0), 2); double yA = Math.Round(y + r * Math.Sin(polarAngle * Math.PI / 180.0), 2); // B and C are points of the scan extremes double xB = Math.Round(xA + dist * Math.Cos((polarAngle - scanAngle * 0.5) * Math.PI / 180.0), 2); double yB = Math.Round(yA + dist * Math.Sin((polarAngle - scanAngle * 0.5) * Math.PI / 180.0), 2); double xC = Math.Round(xA + dist * Math.Cos((polarAngle + scanAngle * 0.5) * Math.PI / 180.0), 2); double yC = Math.Round(yA + dist * Math.Sin((polarAngle + scanAngle * 0.5) * Math.PI / 180.0), 2); Point a, b, c; a = new Point(xA, yA); b = new Point(xB, yB); c = new Point(xC, yC); // get a list of the planets and spacehsips // check if they are inside the triangle ABC // or if the sides of the triangle cu the spaceships (as a circle) var dict = this.SpaceshipsInsideWithShadow(a, b, c); foreach (KeyValuePair <Spaceship, double> kvp in dict) { Console.WriteLine("You attacked " + ((Spaceship)(kvp.Key)).Name + " with ratio " + kvp.Value); } foreach (KeyValuePair <Spaceship, double> kvp in dict) { Console.WriteLine("You attacked " + ((Spaceship)(kvp.Key)).Name + " with ratio " + kvp.Value); Spaceship ship = kvp.Key; list.Add(ship); double x_coord = ship.XCoordinate; double y_coord = ship.YCoordinate; int other_radius = ship.Capacity / 100; double ratio; // ratio of the energy with which we are attacking // if the spaceship is inside the shoot array' if (GameMaths.IsInside(a, b, c, new Point(x_coord, y_coord))) { // B'C' is parallel to BC, we need the the slope and the other spaceship coordinates to find the equation and distance of B'C' double slope = (yB - yC) / (xB - xC); // find an equation of the type y = slope * x + b_ // aim: find out another point on B'C' double b_ = y_coord - slope * x_coord; double x_new_point = 1; // random, doesn't matter double y_new_point = slope * x_new_point + b_; Point b_prime = GameMaths.LineIntersection(a, b, new Point(x_coord, y_coord), new Point(x_new_point, y_new_point)); Point c_prime = GameMaths.LineIntersection(a, c, new Point(x_coord, y_coord), new Point(x_new_point, y_new_point)); double dist_b_c_prime = GameMaths.Distance2Points(b_prime, c_prime); // multiple cases depending on where the spaceship lies on the line if (GameMaths.DistanceToLine(GameMaths.LineEquation(a, b), x_coord, y_coord) < other_radius) // other spaceship is closer to AB, and extends outside { double distance_to_ab = GameMaths.DistanceToLine(GameMaths.LineEquation(a, b), x_coord, y_coord); double dist_to_add; double b_o_dist = distance_to_ab * Math.Sin(((Math.PI - scanAngle) / 2) * Math.PI / 180.0); if (dist_b_c_prime - b_o_dist >= other_radius) { dist_to_add = other_radius; } else { dist_to_add = dist_b_c_prime - b_o_dist; } ratio = (dist_to_add + b_o_dist) / dist_b_c_prime; } else if (GameMaths.DistanceToLine(GameMaths.LineEquation(a, c), x_coord, y_coord) < other_radius) { double distance_to_ac = GameMaths.DistanceToLine(GameMaths.LineEquation(a, c), x_coord, y_coord); double dist_to_add; double c_o_dist = distance_to_ac * Math.Sin(((Math.PI - scanAngle) / 2) * Math.PI / 180.0); if (dist_b_c_prime - c_o_dist >= other_radius) { dist_to_add = other_radius; } else { dist_to_add = dist_b_c_prime - c_o_dist; } ratio = (dist_to_add + c_o_dist) / dist_b_c_prime; } else { // spaceship is on the line equally distributed if (2 * other_radius < dist_b_c_prime) { ratio = (2 * other_radius) / dist_b_c_prime; } else { ratio = 1; } } ratio += dict[ship]; ratio /= 2; ratio *= (StringDistance.Compute(ship.Code, attackCode) / 16.0 + 1) / 2.0; bigoutput += this.Attack(ship, (int)(Math.Round((energy * ratio), 0))); } // if the other spacehsip center is outside of the shoot triangle else if (GameMaths.ContainsSpaceship(a, b, c, new Point(x_coord, y_coord), other_radius)) // && this.UserId != ship.UserId) { // B'C' is parallel to BC, we need the the slope and the other spaceship coordinates to find the equation and distance of B'C' double slope = (yB - yC) / (xB - xC); // find an equation of the type y = slope * x + b // aim: find out another point on B'C' double b_ = y_coord - slope * x_coord; double x_new_point = 1; // random, doesn't matter double y_new_point = slope * x_new_point + b_; Point b_prime = GameMaths.LineIntersection(a, b, new Point(x_coord, y_coord), new Point(x_new_point, y_new_point)); Point c_prime = GameMaths.LineIntersection(a, c, new Point(x_coord, y_coord), new Point(x_new_point, y_new_point)); double dist_b_c_prime = GameMaths.Distance2Points(b_prime, c_prime); ratio = (other_radius - GameMaths.SmallestDistance(a, b, c, new Point(x_coord, y_coord), other_radius)) / dist_b_c_prime; ratio += dict[ship]; ratio /= 2; ratio *= (StringDistance.Compute(ship.Code, attackCode) / 16.0 + 1) / 2.0; bigoutput += this.Attack(ship, (int)(Math.Round((energy * ratio), 0))); } } return(bigoutput); }