예제 #1
0
 public static bool IsFd(this Delta d)
 => 0 < Clen(d) && Clen(d) <= 30;
예제 #2
0
 public static int Mlen(this Delta d)
 {
     return(Abs(d.DX) + Abs(d.DY) + Abs(d.DZ));
 }
예제 #3
0
 public static bool IsLld(this Delta d)
 => IsLd(d) && Mlen(d) <= 15;
예제 #4
0
 public static bool IsNd(this Delta d)
 => Mlen(d) <= 2 && Clen(d) == 1;
예제 #5
0
 public static int Clen(this Delta d)
 {
     return(Max3(Abs(d.DX), Abs(d.DY), Abs(d.DZ)));
 }
예제 #6
0
 public static bool IsLd(this Delta d)
 {
     return((d.DX != 0 && d.DY == 0 && d.DZ == 0) ||
            (d.DX == 0 && d.DY != 0 && d.DZ == 0) ||
            (d.DX == 0 && d.DY == 0 && d.DZ != 0));
 }
예제 #7
0
 public static Command SMove(Delta lld)
 {
     Requires.Arg(lld.IsLld(), nameof(lld), "Argument is not a valid lld.");
     return(new SMoveCommand(lld));
 }
예제 #8
0
 internal override Command DecodeText(IReadOnlyList <string> args)
 => Commands.SMove(Delta.Parse(args[0]));
예제 #9
0
 internal SMoveCommand(Delta lld)
 {
     mLld = lld;
 }
예제 #10
0
        private void Execute()
        {
            var   commands = new Command[S.Bots.Count];
            Delta down     = Delta.LinearY(-1);

            while (true)
            {
                int z = 0;

                while (true)
                {
                    for (int i = 0; i < S.Bots.Count; i++)
                    {
                        int dx = (S.Bots[i].Pos.X % 31 == (R - 1) % 31) ? -30 : +30;
                        if (S.Bots[i].Pos.X == 0)
                        {
                            dx = (R + 30) % 31;
                        }
                        dx = Math.Max(dx, -S.Bots[i].Pos.X);
                        int dz = (S.Bots[i].Pos.Z == z) ? +30 : -30;
                        commands[i] = Commands.GVoid(down, Delta.Of(dx, 0, dz));
                    }
                    S.DoTurn(commands);

                    if (z + 30 == MaxZ)
                    {
                        break;
                    }

                    int dz0 = Math.Min(z + 30, MaxZ - 30) - z;
                    z += dz0;

                    for (int dz = dz0; dz > 0; dz -= 15)
                    {
                        for (int i = 0; i < S.Bots.Count; i++)
                        {
                            commands[i] = Commands.SMove(Delta.LinearZ(Math.Min(dz, 15)));
                        }
                        S.DoTurn(commands);
                    }
                }

                for (int i = 0; i < S.Bots.Count; i++)
                {
                    commands[i] = Commands.SMove(down);
                }
                S.DoTurn(commands);

                if (S.Bots[0].Pos.Y == 0)
                {
                    for (; z > 0; z -= 15)
                    {
                        for (int i = 0; i < S.Bots.Count; i++)
                        {
                            commands[i] = Commands.SMove(Delta.LinearZ(-Math.Min(z, 15)));
                        }
                        S.DoTurn(commands);
                    }
                    break;
                }

                while (true)
                {
                    for (int i = 0; i < S.Bots.Count; i++)
                    {
                        int dx = (S.Bots[i].Pos.X % 31 == (R - 1) % 31) ? -30 : +30;
                        if (S.Bots[i].Pos.X == 0)
                        {
                            dx = (R + 30) % 31;
                        }
                        dx = Math.Max(dx, -S.Bots[i].Pos.X);
                        int dz = (S.Bots[i].Pos.Z == z) ? +30 : -30;
                        commands[i] = Commands.GVoid(down, Delta.Of(dx, 0, dz));
                    }
                    S.DoTurn(commands);

                    if (z == 0)
                    {
                        break;
                    }

                    int dz0 = z - Math.Max(z - 30, 0);
                    z -= dz0;

                    for (int dz = dz0; dz > 0; dz -= 15)
                    {
                        for (int i = 0; i < S.Bots.Count; i++)
                        {
                            commands[i] = Commands.SMove(Delta.LinearZ(-Math.Min(dz, 15)));
                        }
                        S.DoTurn(commands);
                    }
                }

                for (int i = 0; i < S.Bots.Count; i++)
                {
                    commands[i] = Commands.SMove(down);
                }
                S.DoTurn(commands);

                if (S.Bots[0].Pos.Y == 0)
                {
                    break;
                }
            }
        }
예제 #11
0
        private void Cleanup()
        {
            var commands = new List <Command>();

            foreach (Nanobot bot in S.Bots)
            {
                if (bot.Pos.X < R - 1)
                {
                    if (bot.Pos.X % 31 == (R - 1) % 31)
                    {
                        commands.Add(Commands.FusionP(Delta.LinearX(+1)));
                        continue;
                    }
                    if (bot.Pos.X % 31 == (R - 0) % 31)
                    {
                        commands.Add(Commands.FusionS(Delta.LinearX(-1)));
                        continue;
                    }
                }
                commands.Add(Commands.Wait());
            }
            S.DoTurn(commands);
            commands.Clear();

            while (true)
            {
                int z = 0;
                foreach (Nanobot bot in S.Bots)
                {
                    z = Math.Max(bot.Pos.Z, z);
                }
                if (z == 0)
                {
                    break;
                }
                foreach (Nanobot bot in S.Bots)
                {
                    if (bot.Pos.Z <= z - 2)
                    {
                        commands.Add(Commands.Wait());
                        continue;
                    }
                    if (bot.Pos.Z == z - 1)
                    {
                        commands.Add(Commands.FusionP(Delta.LinearZ(+1)));
                        continue;
                    }
                    if (z == 1 || z % 31 == R % 31)
                    {
                        commands.Add(Commands.FusionS(Delta.LinearZ(-1)));
                    }
                    else
                    {
                        int dz = -Math.Min(z - 1, 15);
                        commands.Add(Commands.SMove(Delta.LinearZ(dz)));
                    }
                }
                S.DoTurn(commands);
                commands.Clear();
            }

            while (true)
            {
                int x = 0;
                foreach (Nanobot bot in S.Bots)
                {
                    x = Math.Max(bot.Pos.X, x);
                }
                if (x == 0)
                {
                    break;
                }
                foreach (Nanobot bot in S.Bots)
                {
                    if (bot.Pos.X <= x - 2)
                    {
                        commands.Add(Commands.Wait());
                        continue;
                    }
                    if (bot.Pos.X == x - 1)
                    {
                        commands.Add(Commands.FusionP(Delta.LinearX(+1)));
                        continue;
                    }
                    if (x == 1 || x % 31 == R % 31)
                    {
                        commands.Add(Commands.FusionS(Delta.LinearX(-1)));
                    }
                    else
                    {
                        int dx = Math.Min(x - 1, 15);
                        commands.Add(Commands.SMove(Delta.LinearX(-dx)));
                    }
                }
                S.DoTurn(commands);
                commands.Clear();
            }
        }