예제 #1
0
        private static void VoidAll(State s)
        {
            var commands = new Command[s.Bots.Count];
            int r        = s.Matrix.R;

            Delta down = Delta.LinearY(-1);

            while (s.Bots[0].Pos.Y > 0)
            {
                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 - 63;
                    }
                    dx = Math.Max(dx, -s.Bots[i].Pos.X);
                    int dz = (s.Bots[i].Pos.Z % 31 == (r - 1) % 31) ? -30 : +30;
                    if (s.Bots[i].Pos.Z == 0)
                    {
                        dz = r - 63;
                    }
                    dz          = Math.Max(dz, -s.Bots[i].Pos.Z);
                    commands[i] = Commands.GVoid(down, Delta.Of(dx, 0, dz));
                }
                s.DoTurn(commands);
                for (int i = 0; i < s.Bots.Count; i++)
                {
                    commands[i] = Commands.SMove(down);
                }
                s.DoTurn(commands);
            }
        }
예제 #2
0
 internal static Delta DecodeFd(int dx, int dy, int dz)
 {
     Requires.Range(dx, nameof(dx), 0, 60);
     Requires.Range(dy, nameof(dy), 0, 60);
     Requires.Range(dz, nameof(dz), 0, 60);
     dx -= 30; dy -= 30; dz -= 30;
     return(Delta.Of(dx, dy, dz));
 }
예제 #3
0
        private void Execute()
        {
            Delta down = Delta.LinearY(-1);

            var gvoid = new Command[S.Bots.Count];

            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 % 31 == (R - 1) % 31) ? -30 : +30;
                if (S.Bots[i].Pos.Z == 0)
                {
                    dz = (R + 30) % 31;
                }
                dz       = Math.Max(dz, -S.Bots[i].Pos.Z);
                gvoid[i] = Commands.GVoid(down, Delta.Of(dx, 0, dz));
            }

            var smove = new Command[S.Bots.Count];

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

            var flipw = new Command[S.Bots.Count];

            for (int i = 0; i < S.Bots.Count; i++)
            {
                flipw[i] = (i == 0) ? Commands.Flip() : Commands.Wait();
            }

            while (S.Bots[0].Pos.Y > 0)
            {
                if (S.Harmonics == Low && mHarmonics[S.Bots[0].Pos.Y - 1] == High)
                {
                    S.DoTurn(flipw);
                }
                S.DoTurn(gvoid);
                if (S.Harmonics == High && mHarmonics[S.Bots[0].Pos.Y - 1] == Low)
                {
                    S.DoTurn(flipw);
                }
                S.DoTurn(smove);
            }
        }
예제 #4
0
        internal static Delta DecodeNd(int nd)
        {
            Requires.Range(nd, nameof(nd), 0, 26);

            int dx = (nd / 9) % 3 - 1;
            int dy = (nd / 3) % 3 - 1;
            int dz = (nd / 1) % 3 - 1;

            Delta decoded = Delta.Of(dx, dy, dz);

            Requires.Arg(decoded.IsNd(), nameof(nd),
                         $"{nd} is not a valid encoding of a near difference.");
            return(decoded);
        }
예제 #5
0
        protected void LocateBots(IReadOnlyList <Coord> dests)
        {
            var commands = new List <Command>();

            while (true)
            {
                if (S.Bots.Count < dests.Count)
                {
                    int dx = (S.Bots.Count % 2 == 1) ? 1 : 0;
                    int dz = (S.Bots.Count % 2 == 1) ? 0 : 1;
                    commands.Add(Commands.Fission(Delta.Of(dx, 0, dz), 0));
                }
                else
                {
                    commands.Add(Commands.Wait());
                }

                for (int i = 1; i < S.Bots.Count; i++)
                {
                    int dx = dests[i].X - S.Bots[i].Pos.X;
                    int dz = dests[i].Z - S.Bots[i].Pos.Z;
                    if (dx > 0 && (i % 2 == 1 || dz == 0))
                    {
                        commands.Add(Commands.SMove(Delta.LinearX(Math.Min(dx, 15))));
                        continue;
                    }
                    if (dz > 0 && (i % 2 == 0 || dx == 0))
                    {
                        commands.Add(Commands.SMove(Delta.LinearZ(Math.Min(dz, 15))));
                        continue;
                    }
                    commands.Add(Commands.Wait());
                }

                if (IsNoop(commands))
                {
                    break;
                }
                S.DoTurn(commands);
                commands.Clear();
            }
        }
예제 #6
0
        private static void LocateBots(State s)
        {
            var commands = new List <Command>();
            int r        = s.Matrix.R;

            while (s.Bots[0].Pos.Y < r - 1)
            {
                int dy = r - 1 - s.Bots[0].Pos.Y;
                s.DoTurn(new [] { Commands.SMove(Delta.LinearY(Math.Min(dy, 15))) });
            }

            var dests = new List <Coord>();

            {
                int[] coords = { r - 1, r - 31, r - 32, r - 62, r - 63, 0 };

                var upper = new List <Coord>();

                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        upper.Add(Coord.Of(coords[i], r - 1, coords[j]));
                    }
                }
                upper.Sort((c1, c2) => {
                    int n1 = c1.X + c1.Z;
                    int n2 = c2.X + c2.Z;
                    return(-Comparer <Int32> .Default.Compare(n1, n2));
                });

                dests.Add(Coord.Of(0, r - 1, 0));

                for (int i = 0; i <= 4; i++)
                {
                    dests.Add(Coord.Of(coords[i], r - 1, coords[i]));
                }
                foreach (Coord c in upper)
                {
                    dests.Add(c); dests.Add(Coord.Of(c.Z, c.Y, c.X));
                }
            }

            while (true)
            {
                commands.Clear();

                if (s.Bots.Count < dests.Count)
                {
                    int dx = (s.Bots.Count % 2 == 1) ? 1 : 0;
                    int dz = (s.Bots.Count % 2 == 1) ? 0 : 1;
                    commands.Add(Commands.Fission(Delta.Of(dx, 0, dz), 0));
                }
                else
                {
                    commands.Add(Commands.Wait());
                }

                for (int i = 1; i < s.Bots.Count; i++)
                {
                    int dx = dests[i].X - s.Bots[i].Pos.X;
                    int dz = dests[i].Z - s.Bots[i].Pos.Z;
                    if (dx > 0 && (i % 2 == 1 || dz == 0))
                    {
                        commands.Add(Commands.SMove(Delta.LinearX(Math.Min(dx, 15))));
                        continue;
                    }
                    if (dz > 0 && (i % 2 == 0 || dx == 0))
                    {
                        commands.Add(Commands.SMove(Delta.LinearZ(Math.Min(dz, 15))));
                        continue;
                    }
                    commands.Add(Commands.Wait());
                }

                if (IsNoop(commands))
                {
                    break;
                }
                s.DoTurn(commands);
            }
        }
예제 #7
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;
                }
            }
        }