Пример #1
0
        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);
        }
Пример #2
0
 public void Maths_LineIntersectsCircleIn2Points_()
 {
     Double[] l = { 40, -40, -4000 };
     Assert.IsTrue(GameMaths.LineIntersectsCircle(GameMaths.LineEquation(new Point(10, 10),
                                                                         new Point(50, 50)), 20, 30, 10));
 }