예제 #1
0
 public WreckGroup(Wreck wreck1, Wreck wreck2, int range2)
 {
     this.Center = wreck1.Center(wreck2);
     this.Range2 = range2;
     this.Wrecks = new HashSet <Wreck> {
         wreck1, wreck2
     };
     this.Weight = wreck1.AvailableWater + wreck2.AvailableWater;
 }
예제 #2
0
        public WreckGroup(Wreck wreck)
        {
            this.Center = wreck.Pos.Clone();
            this.Range2 = 0;

            this.Wrecks = new HashSet <Wreck> {
                wreck
            };
            this.Weight = wreck.AvailableWater;
        }
예제 #3
0
        public void Add(Wreck wreck, int range2, Wreck farestWreck)
        {
            if (range2 > this.Range2)
            {
                this.Range2 = range2;
                this.Center = wreck.Center(farestWreck);
            }

            this.Wrecks.Add(wreck);
            this.Weight += wreck.AvailableWater;
        }
예제 #4
0
        public Entity Build(string[] inputs)
        {
            Entity entity;

            var id     = int.Parse(inputs[0]);
            var type   = int.Parse(inputs[1]);
            var player = int.Parse(inputs[2]);

            var mass   = float.Parse(inputs[3]);
            var radius = int.Parse(inputs[4]);

            var pos = new Position
            {
                X = int.Parse(inputs[5]),
                Y = int.Parse(inputs[6])
            };
            var speed = new Speed
            {
                Vx = int.Parse(inputs[7]),
                Vy = int.Parse(inputs[8])
            };

            var remaining = int.Parse(inputs[9]);
            var maxWater  = int.Parse(inputs[10]);

            switch (type)
            {
            case 0:
                var reaper = new Reaper
                {
                    Player = player,
                    Speed  = speed
                };
                entity = reaper;
                break;

            case 1:
                var destroyer = new Destroyer
                {
                    Player = player,
                    Speed  = speed
                };
                entity = destroyer;
                break;

            case 2:
                var doof = new Doof
                {
                    Player = player,
                    Speed  = speed
                };
                entity = doof;
                break;

            case 3:
                var tanker = new Tanker
                {
                    Speed          = speed,
                    AvailableWater = remaining,
                    MaxWater       = maxWater
                };
                entity = tanker;
                break;

            case 4:
                var wreck = new Wreck
                {
                    AvailableWater = remaining
                };
                entity = wreck;
                break;

            case 5:
                var tar = new Tar
                {
                    RemainingRound = remaining
                };
                entity = tar;
                break;

            case 6:
                var oil = new Oil
                {
                    RemainingRound = remaining
                };
                entity = oil;
                break;

            default:
                throw new NotImplementedException($"type '{type}' is not supported.");
            }

            entity.Id     = id;
            entity.Pos    = pos;
            entity.Radius = radius;

            return(entity);
        }
예제 #5
0
        public static List <WreckGroup> BuildGroups(Wreck[] wrecks, Position reaperPos)
        {
            const int MaxRange  = 3000;
            const int MaxRange2 = MaxRange * MaxRange;

            // compute dist
            var dist2Matrix = new int[wrecks.Length, wrecks.Length];
            var sortetDist2 = new SortedList <int, Tuple <Wreck, Wreck> >();

            for (var i = 0; i < wrecks.Length; i++)
            {
                for (var j = i + 1; j < wrecks.Length; j++)
                {
                    var dist2 = wrecks[i].Dist2(wrecks[j]);
                    dist2Matrix[i, j] = dist2Matrix[j, i] = dist2;
                    sortetDist2.Add(dist2, new Tuple <Wreck, Wreck>(wrecks[i], wrecks[j]));
                }
            }

            // compute group
            var groups      = new List <WreckGroup>();
            var wreckGroups = new WreckGroup[wrecks.Length];

            foreach (var item in sortetDist2)
            {
                var wreck1      = item.Value.Item1;
                var wreck2      = item.Value.Item2;
                var wreckGroup1 = wreckGroups[wreck1.WreckId];
                var wreckGroup2 = wreckGroups[wreck2.WreckId];

                if (wreckGroup1 != null && wreckGroup2 != null)
                {
                    continue;
                }

                if (wreckGroup1 == null && wreckGroup2 == null)
                {
                    if (item.Key <= MaxRange2)
                    {
                        var group = new WreckGroup(wreck1, wreck2, item.Key);
                        wreckGroups[wreck1.WreckId] = group;
                        wreckGroups[wreck2.WreckId] = group;
                        groups.Add(group);
                    }
                    else
                    {
                        var group1 = new WreckGroup(wreck1);
                        wreckGroups[wreck1.WreckId] = group1;
                        groups.Add(group1);

                        var group2 = new WreckGroup(wreck2);
                        wreckGroups[wreck2.WreckId] = group2;
                        groups.Add(group2);
                    }
                }
                else
                {
                    WreckGroup group;
                    Wreck      wreckToAdd;
                    if (wreckGroup1 == null)
                    {
                        group      = wreckGroup2;
                        wreckToAdd = wreck1;
                    }
                    else
                    {
                        group      = wreckGroup1;
                        wreckToAdd = wreck2;
                    }

                    var   maxDist2ToGroup = int.MinValue;
                    Wreck farestWreck     = null;
                    foreach (var wreck in group.Wrecks)
                    {
                        var dist2 = dist2Matrix[wreckToAdd.WreckId, wreck.WreckId];
                        if (dist2 >= maxDist2ToGroup)
                        {
                            maxDist2ToGroup = dist2;
                            farestWreck     = wreck;
                        }
                    }
                    if (maxDist2ToGroup <= MaxRange2)
                    {
                        group.Add(wreckToAdd, maxDist2ToGroup, farestWreck);
                        wreckGroups[wreckToAdd.WreckId] = group;
                    }
                    else
                    {
                        var group2 = new WreckGroup(wreckToAdd);
                        wreckGroups[wreckToAdd.WreckId] = group2;
                        groups.Add(group2);
                    }
                }
            }

            // compute best pos for each group
            foreach (var @group in groups)
            {
                var groupWrecks = @group.Wrecks.OrderByDescending(w => w.AvailableWater).ThenBy(w => w.Pos.Dist2(reaperPos)).ToArray();
                @group.BestPos        = groupWrecks[0].Pos;
                @group.BestPosWeight  = groupWrecks[0].AvailableWater;
                @group.IsBestPosInter = false;
                for (var i = 0; i < groupWrecks.Length - 1; i++)
                {
                    for (var j = i + 1; j < groupWrecks.Length; j++)
                    {
                        var wreck1 = groupWrecks[i];
                        var wreck2 = groupWrecks[j];
                        var weight = wreck1.AvailableWater + wreck2.AvailableWater;
                        if (weight <= @group.BestPosWeight)
                        {
                            continue;
                        }

                        var radius = wreck1.Radius + wreck2.Radius;
                        if (dist2Matrix[wreck1.WreckId, wreck2.WreckId] <= radius * radius)
                        {
                            var x = (wreck1.Pos.X * wreck2.Radius + wreck2.Pos.X * wreck1.Radius) / radius;
                            var y = (wreck1.Pos.Y * wreck2.Radius + wreck2.Pos.Y * wreck1.Radius) / radius;
                            @group.BestPos        = new Position(x, y);
                            @group.BestPosWeight  = weight;
                            @group.IsBestPosInter = true;
                        }
                    }
                }
            }

            return(groups);
        }