예제 #1
0
        public Solved Solve(State state)
        {
            result = new List <ActionBase>();

            BoosterMaster.CreatePalka(state, result, 1);
            var map = state.Map;

            MinFreeY = Enumerable.Repeat(int.MaxValue, state.Map.SizeX).ToArray();
            for (int x = 0; x < map.SizeX; x++)
            {
                for (int y = 0; y < map.SizeY; y++)
                {
                    if (map[new V(x, y)] == CellState.Void)
                    {
                        MinFreeY[x] = Math.Min(MinFreeY[x], y);
                    }
                }
            }
            state.OnWrap = v =>
            {
                if (v.Y == MinFreeY[v.X])
                {
                    MinFreeY[v.X] = int.MaxValue;
                    for (int y = v.Y + 1; y < map.SizeY; y++)
                    {
                        if (map[new V(v.X, y)] == CellState.Void)
                        {
                            MinFreeY[v.X] = y;
                            break;
                        }
                    }
                }
            };

            int palkaDown = -state.SingleWorker.Manipulators.Min(m => m.Y);

            while (state.UnwrappedLeft > 0)
            {
                if (result.Count == 213)
#pragma warning disable 1717
                {
                    palkaDown = palkaDown;
                }
#pragma warning restore 1717

                for (int check = 0; check < 2; check++)
                {
                    var me = state.SingleWorker;

                    var pathBuilder = new PathBuilder(map, me.Position, MinFreeY, palkaDown, check == 0);

                    V   best     = null;
                    var bestDist = int.MaxValue;
                    var bestY    = int.MaxValue;
                    var bestSize = double.MaxValue;

                    var(comp, csize) = ComponentBuilder.Build(map, me.Position);

                    for (int y = 0; y < map.SizeY; y++)
                    {
                        for (int x = 0; x < map.SizeX; x++)
                        {
                            if (map[new V(x, y)] != CellState.Void)
                            {
                                continue;
                            }

                            var dist = pathBuilder.Distance(new V(x, y));
                            var size = csize[comp[new V(x, y)]];

                            if (dist == int.MaxValue)
                            {
                                continue;
                            }

                            if (check == 0 && (size < bestSize || size == bestSize && dist < bestDist) ||
                                check == 1 && (dist < bestDist && bestY >= y || bestY > y))
                            {
                                bestDist = dist;
                                bestY    = y;
                                bestSize = size;
                                best     = new V(x, y);
                            }
                        }
                    }

                    if (best == null)
                    {
                        continue;
                    }

                    var actions = pathBuilder.GetActions(best).ToList();
                    state.ApplyRange(actions);
                    result.AddRange(actions);
                    break;
                }
            }

            return(new Solved {
                Actions = new List <List <ActionBase> > {
                    result
                }
            });
        }
        public Solved Solve(State state)
        {
            result = new List <List <ActionBase> > {
                new List <ActionBase>()
            };

            if (palka)
            {
                BoosterMaster.CreatePalka(state, result[0], 1);
            }

            BoosterMaster.CloneAttack(state, result);

            var pathBuilder = new PathBuilder(state.Map);

            while (state.UnwrappedLeft > 0)
            {
                var workerActions = new List <(Worker worker, ActionBase action)>();

                for (int i = 0; i < state.Workers.Count; i++)
                {
                    var map = state.Map;
                    var me  = state.Workers[i];

                    pathBuilder.Build(map, me.Position, state.Workers.Take(i).Select(w => w.Position).ToList());

                    V   best     = null;
                    var bestDist = int.MaxValue;

                    for (int x = 0; x < map.SizeX; x++)
                    {
                        for (int y = 0; y < map.SizeY; y++)
                        {
                            if (map[new V(x, y)] != CellState.Void)
                            {
                                continue;
                            }

                            var dist = pathBuilder.Distance(new V(x, y));
                            if (dist == int.MaxValue)
                            {
                                continue;
                            }

                            if (dist < bestDist)
                            {
                                bestDist = dist;
                                best     = new V(x, y);
                            }
                        }
                    }

                    var action = best == null ? new Wait() : pathBuilder.GetActions(best).First();
                    workerActions.Add((me, action));
                    result[i].Add(action);
                }

                state.Apply(workerActions);
            }

            return(new Solved {
                Actions = result
            });
        }