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; }
public WreckGroup(Wreck wreck) { this.Center = wreck.Pos.Clone(); this.Range2 = 0; this.Wrecks = new HashSet <Wreck> { wreck }; this.Weight = wreck.AvailableWater; }
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; }
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); }
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); }