Пример #1
0
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.Clear();
            Console.Title         = "Missile Guidance System 5.1";
            Console.WindowWidth   = 85;
            Console.WindowHeight  = 25;
            Console.BufferWidth   = 85;
            Console.BufferHeight  = short.MaxValue - 1;
            Console.CursorVisible = false;
            Console.WriteLine("Press any key to begin.");
            ConsoleKey key = Console.ReadKey(true).Key;

            if (key == ConsoleKey.Escape)
            {
                return;
            }
            Console.Clear();
            Random r = new Random();

            while (true)
            {
                double dec = Math.Pow(10.0, DecimalDigits);
                double tax = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double tay = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double taz = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double tvx = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double tvy = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double tvz = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double tpx = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double tpy = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double tpz = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double sax = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double say = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double saz = r.Next((int)(-ABound * dec), (int)(ABound * dec)) / dec;
                double svx = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double svy = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double svz = r.Next((int)(-VBound * dec), (int)(VBound * dec)) / dec;
                double spx = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double spy = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double spz = r.Next((int)(-PBound * dec), (int)(PBound * dec)) / dec;
                double pam = r.Next((int)(PamBound * dec)) / dec;
                double pvm = r.Next((int)(PvmBound * dec)) / dec;
                double ppm = r.Next((int)(PpmBound * dec)) / dec;
                int    rbt = r.Next(RbtBound);
                Console.Title           = "Attempting to lock on";
                Console.ForegroundColor = ConsoleColor.Blue;
                Output.Clear();
                Output.WriteLine("INITALIZATION\n");
                Output.WriteLine("TAX:\t\t" + tax);
                Output.WriteLine("TAY:\t\t" + tay);
                Output.WriteLine("TAZ:\t\t" + taz);
                Output.WriteLine("TVX:\t\t" + tvx);
                Output.WriteLine("TVY:\t\t" + tvy);
                Output.WriteLine("TVZ:\t\t" + tvz);
                Output.WriteLine("TPX:\t\t" + tpx);
                Output.WriteLine("TPY:\t\t" + tpy);
                Output.WriteLine("TPZ:\t\t" + tpz);
                Output.WriteLine("SAX:\t\t" + sax);
                Output.WriteLine("SAY:\t\t" + say);
                Output.WriteLine("SAZ:\t\t" + saz);
                Output.WriteLine("SVX:\t\t" + svx);
                Output.WriteLine("SVY:\t\t" + svy);
                Output.WriteLine("SVZ:\t\t" + svz);
                Output.WriteLine("SPX:\t\t" + spx);
                Output.WriteLine("SPY:\t\t" + spy);
                Output.WriteLine("SPZ:\t\t" + spz);
                Output.WriteLine("PAM:\t\t" + pam);
                Output.WriteLine("PVM:\t\t" + pvm);
                Output.WriteLine("PPM:\t\t" + ppm);
                Output.WriteLine("RBT:\t\t" + rbt);
                Console.ForegroundColor = ConsoleColor.Cyan;
                AbstractObject shooter = new AbstractObject(new Point3D(sax, say, saz), new Point3D(svx, svy, svz), new Point3D(spx, spy, spz));
                AbstractObject target  = new AbstractObject(new Point3D(tax, tay, taz), new Point3D(tvx, tvy, tvz), new Point3D(tpx, tpy, tpz));
                double         dist    = shooter.DistanceTo(target);
                Output.WriteLine("\nTRACKING\n");
                Output.WriteLine("Time:\t\t-2");
                Output.WriteLine("Target:\t\t" + target);
                Output.WriteLine("Shooter:\t" + shooter);
                Output.WriteLine("Fuel:\t\t" + rbt);
                Output.WriteLine("Distance:\t" + dist);
                Output.WriteLine("");
                Point3D tp1 = (Point3D)target.P.Clone();
                target.Update();
                shooter.Update();
                double lastDist = dist;
                dist = shooter.DistanceTo(target);
                audio(dist, lastDist);
                Output.WriteLine("TRACKING\n");
                Output.WriteLine("Time:\t\t-1");
                Output.WriteLine("Target:\t\t" + target);
                Output.WriteLine("Shooter:\t" + shooter);
                Output.WriteLine("Fuel:\t\t" + rbt);
                Output.WriteLine("Distance:\t" + dist);
                Output.WriteLine("");
                Point3D tp2 = (Point3D)target.P.Clone();
                target.Update();
                shooter.Update();
                lastDist = dist;
                dist     = shooter.DistanceTo(target);
                audio(dist, lastDist);
                Output.WriteLine("TRACKING\n");
                Output.WriteLine("Time:\t\t0");
                Output.WriteLine("Target:\t\t" + target);
                Output.WriteLine("Shooter:\t" + shooter);
                Output.WriteLine("Fuel:\t\t" + rbt);
                Output.WriteLine("Distance:\t" + dist);
                Output.WriteLine("");
                Point3D tp3   = (Point3D)target.P.Clone();
                Point3D tEstA = new Point3D(Targeting.CalculateAcceleration(tp1.X, tp2.X, tp3.X), Targeting.CalculateAcceleration(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateAcceleration(tp1.Z, tp2.Z, tp3.Z));
                Point3D tEstV = new Point3D(Targeting.CalculateVelocity(tp1.X, tp2.X, tp3.X), Targeting.CalculateVelocity(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateVelocity(tp1.Z, tp2.Z, tp3.Z));
                lastDist = dist;
                dist     = shooter.DistanceTo(target);
                audio(dist, lastDist);
                double[] tui;
                double[,] vectors;
                bool able = Targeting.Intercept(tEstA.X, tEstA.Y, tEstA.Z, tEstV.X, tEstV.Y, tEstV.Z, target.P.X, target.P.Y, target.P.Z, shooter.V.X, shooter.V.Y, shooter.V.Z, shooter.P.X, shooter.P.Y, shooter.P.Z, pam, pvm, ppm, rbt, RadiusOfTolerance, out vectors, out tui);
                if (AutoRestartOnUnable && !able)
                {
                    continue;
                }
                AbstractObject missile = (AbstractObject)shooter.Clone();
                Console.ForegroundColor = able ? ConsoleColor.Green : ConsoleColor.DarkGreen;
                int i = 0;
                if (tui.Length == 0)
                {
                    Console.Title = "Unable to lock on";
                    missile.A     = new Point3D(pam * vectors[0, 0], pam * vectors[0, 1], pam * vectors[0, 2]);
                    missile.V.Add(new Point3D(pvm * vectors[0, 0], pvm * vectors[0, 1], pvm * vectors[0, 2]));
                    missile.P.Add(new Point3D(ppm * vectors[0, 0], ppm * vectors[0, 1], ppm * vectors[0, 2]));
                    Output.WriteLine("No intercept exists.\nPress any key to attempt");
                    if (AutoRestartOnUnable)
                    {
                        Output.WriteLine("\nINITAL\n");
                        Output.WriteLine("Target:\t\t" + target);
                        Output.WriteLine("Missile:\t" + missile);
                        Output.WriteLine("Fuel:\t\t" + rbt);
                        Output.WriteLine("Distance:\t" + missile.DistanceTo(target));
                        Output.WriteLine("T until impact:\tNEVER");
                    }
                    key = Console.ReadKey(true).Key;
                    if (key == ConsoleKey.Escape)
                    {
                        return;
                    }
                    if (AutoRestartOnUnable)
                    {
                        continue;
                    }
                }
                else if (tui.Length == 1)
                {
                    Console.Title = "Locked onto target";
                    missile.A     = new Point3D(pam * vectors[0, 0], pam * vectors[0, 1], pam * vectors[0, 2]);
                    missile.V.Add(new Point3D(pvm * vectors[0, 0], pvm * vectors[0, 1], pvm * vectors[0, 2]));
                    missile.P.Add(new Point3D(ppm * vectors[0, 0], ppm * vectors[0, 1], ppm * vectors[0, 2]));
                    Output.WriteLine("Only one intercept exists.\nPress any key to simulate.\n");
                    key = Console.ReadKey(true).Key;
                    if (key == ConsoleKey.Escape)
                    {
                        return;
                    }
                }
                else
                {
                    Console.Title = "Locked onto target";
                    string input;
                    Output.WriteLine("More than one intercept exists.\nEnter '1' for the fastest intercept, '" + vectors.GetLength(0) + "' for the slowest, or any intiger in between.\nA blank entry will imply a selection of '1'\n\n");
                    int loc = Console.CursorTop - 1;
                    Console.CursorTop = loc;
                    do
                    {
                        input             = Console.ReadLine();
                        Console.CursorTop = loc;
                        Console.Write(new string(' ', input.Length));
                        Console.CursorLeft = 0;
                    }while (!int.TryParse(input == "" ? "1" : input, out i) || i < 1 || i > tui.Length);
                    Console.CursorTop = loc;
                    Console.Write(new string(' ', input.Length));
                    Console.CursorLeft = 0;
                    if (input != "")
                    {
                        Output.WriteLine(input + "\n");
                    }
                    i--;
                    missile.A = new Point3D(pam * vectors[i, 0], pam * vectors[i, 1], pam * vectors[i, 2]);
                    missile.V.Add(new Point3D(pvm * vectors[i, 0], pvm * vectors[i, 1], pvm * vectors[i, 2]));
                    missile.P.Add(new Point3D(ppm * vectors[i, 0], ppm * vectors[i, 1], ppm * vectors[i, 2]));
                }
                int index = i;
                Output.WriteLine("INITAL\n");
                Output.WriteLine("Target:\t\t" + target);
                Output.WriteLine("Missile:\t" + missile);
                Output.WriteLine("Fuel:\t\t" + rbt);
                Output.WriteLine("Distance:\t" + missile.DistanceTo(target));
                Output.WriteLine("T until impact:\t" + (tui.Length == 0 ? "NEVER" : tui[i].ToString()) + "\n");
                Console.ForegroundColor = rbt == 0 ? ConsoleColor.White : ConsoleColor.Yellow;
                for (int t = 1; true; t++)
                {
                    if (t - 1 == rbt)
                    {
                        missile.A = new Point3D(0.0, 0.0, 0.0);
                        pam       = 0.0;
                        index     = 0;
                        Console.ForegroundColor = tui.Length == 0 ? ConsoleColor.Gray : ConsoleColor.White;
                    }
                    lastDist      = missile.DistanceTo(target);
                    Console.Title = tui.Length == 0 ? "Impact is not expected" : "Expecting impact in T-" + tui[i].ToString();
                    if (Console.KeyAvailable)
                    {
                        if (Console.ReadKey(true).Key == ConsoleKey.Escape)
                        {
                            return;
                        }
                        else
                        {
                            break;
                        }
                    }
                    Point3D targetLast  = (Point3D)target.P.Clone();
                    Point3D missileLast = (Point3D)missile.P.Clone();
                    target.Update();
                    missile.Update();
                    if (Math.Sign(targetLast.X - missileLast.X) != Math.Sign(target.P.X - missile.P.X) && Math.Sign(targetLast.Y - missileLast.Y) != Math.Sign(target.P.Y - missile.P.Y) && Math.Sign(targetLast.Z - missileLast.Z) != Math.Sign(target.P.Z - missile.P.Z))
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Output.WriteLine("IMPACT APEX\n");
                    }
                    dist  = missile.DistanceTo(target);
                    tp1   = (Point3D)tp2.Clone();
                    tp2   = (Point3D)tp3.Clone();
                    tp3   = (Point3D)target.P.Clone();
                    tEstA = new Point3D(Targeting.CalculateAcceleration(tp1.X, tp2.X, tp3.X), Targeting.CalculateAcceleration(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateAcceleration(tp1.Z, tp2.Z, tp3.Z));
                    tEstV = new Point3D(Targeting.CalculateVelocity(tp1.X, tp2.X, tp3.X), Targeting.CalculateVelocity(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateVelocity(tp1.Z, tp2.Z, tp3.Z));
                    double[,] updates;
                    index = i;
                    Console.ForegroundColor = Targeting.Intercept(tEstA.X, tEstA.Y, tEstA.Z, tEstV.X, tEstV.Y, tEstV.Z, target.P.X, target.P.Y, target.P.Z, missile.V.X, missile.V.Y, missile.V.Z, missile.P.X, missile.P.Y, missile.P.Z, pam, 0.0, 0.0, rbt - t, RadiusOfTolerance, out updates, out tui) ? rbt < t + 1 ? ConsoleColor.White : ConsoleColor.Yellow : rbt < t + 1 ? ConsoleColor.Gray : ConsoleColor.DarkYellow;
                    i = Math.Max(0, Math.Min(i, tui.Length - 1));
                    Point3D error;
                    if (i == -1)
                    {
                        error = new Point3D();
                    }
                    else
                    {
                        error     = new Point3D(Math.Abs(vectors[i, 0] - updates[i, 0]), Math.Abs(vectors[i, 1] - updates[i, 1]), Math.Abs(vectors[i, 2] - updates[i, 2]));
                        missile.A = new Point3D(pam * updates[i, 0], pam * updates[i, 1], pam * updates[i, 2]);
                    }
                    while (dist <= RadiusOfTolerance)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Output.WriteLine("IPACT");
                        Output.WriteLine("Time:\t\t" + t);
                        Output.WriteLine("Target:\t\t" + target);
                        Output.WriteLine("Missile:\t" + missile);
                        Output.WriteLine("Fuel:\t\t" + Math.Max(0, rbt - t++));
                        Output.WriteLine("Distance:\t" + dist);
                        Output.WriteLine("T until impact:\t" + (tui.Length == 0 ? "NEVER" : tui[i].ToString()) + "\n");
                        Console.ForegroundColor = tui.Length == 0 ? t > rbt ? ConsoleColor.Gray : ConsoleColor.DarkYellow : t > rbt ? ConsoleColor.White : ConsoleColor.Yellow;
                        target.Update();
                        missile.Update();
                        tp1   = (Point3D)tp2.Clone();
                        tp2   = (Point3D)tp3.Clone();
                        tp3   = (Point3D)target.P.Clone();
                        tEstA = target.A;
                        tEstV = target.V;
                        tEstA = new Point3D(Targeting.CalculateAcceleration(tp1.X, tp2.X, tp3.X), Targeting.CalculateAcceleration(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateAcceleration(tp1.Z, tp2.Z, tp3.Z));
                        tEstV = new Point3D(Targeting.CalculateVelocity(tp1.X, tp2.X, tp3.X), Targeting.CalculateVelocity(tp1.Y, tp2.Y, tp3.Y), Targeting.CalculateVelocity(tp1.Z, tp2.Z, tp3.Z));
                        index = i;
                        Console.ForegroundColor = Targeting.Intercept(tEstA.X, tEstA.Y, tEstA.Z, tEstV.X, tEstV.Y, tEstV.Z, target.P.X, target.P.Y, target.P.Z, missile.V.X, missile.V.Y, missile.V.Z, missile.P.X, missile.P.Y, missile.P.Z, pam, 0.0, 0.0, rbt - t, RadiusOfTolerance, out vectors, out tui) ? rbt < t + 1 ? ConsoleColor.White : ConsoleColor.Yellow : rbt < t + 1 ? ConsoleColor.Gray : ConsoleColor.DarkYellow;
                        i             = Math.Min(index, tui.Length - 1);
                        Console.Title = tui.Length == 0 ? "Impact is not expected" : "Expecting impact in T-" + tui[i].ToString();
                        if (i != -1)
                        {
                            missile.A = new Point3D(pam * vectors[i, 0], pam * vectors[i, 1], pam * vectors[i, 2]);
                        }
                        dist = missile.DistanceTo(target);
                        audio(dist, lastDist);
                    }
                    audio(dist, lastDist);
                    Output.WriteLine("Time:\t\t" + t);
                    Output.WriteLine("Target:\t\t" + target);
                    Output.WriteLine("Missile:\t" + missile);
                    Output.WriteLine("Fuel:\t\t" + Math.Max(0, rbt - t));
                    Output.WriteLine("Distance:\t" + dist);
                    Output.WriteLine("Error:\t\t" + (double.IsNaN(error.X) ? "LAUNCH ERROR" : error.ToString()));
                    Output.WriteLine("T until impact:\t" + (tui.Length == 0 ? "NEVER" : tui[i].ToString()) + "\n");
                    vectors = updates;
                }
            }
        }