private void AddArea(Area newArea) { if (!areaLookup.ContainsKey(newArea.Location)) { int id = lastId; lastId++; newArea.Id = id; areaIdLookup.Add(id, newArea); areaLookup.Add(newArea.Location, newArea); foreach (int spot in newArea.Location.spots) { areaSpotLookups[spot % width, spot / width].Add(id); } } }
private void CreateAreaWithCenter(int x, int y, int count) { Area newArea = new Area(); for (int j = -1; j <= 1; j++) { if (y + j < 0) continue; if (y + j >= height) continue; for (int i = -1; i <= 1; i++) { if (x + i < 0) continue; if (x + i >= width) continue; newArea.Location.spots.Add(x + i + (y + j) * width); } } newArea.maxCount = count; newArea.minCount = count; AddArea(newArea); }
internal void MarkParts(Area other, out Area left, out Area right, out Area inters) { left = new Area(); inters = new Area(); right = new Area(); foreach (int spot in Location.spots) { if (!other.Location.spots.Contains(spot)) left.Location.spots.Add(spot); else inters.Location.spots.Add(spot); } foreach (int spot in other.Location.spots) { if (!Location.spots.Contains(spot)) right.Location.spots.Add(spot); } left.maxCount = left.Location.spots.Count; inters.maxCount = inters.Location.spots.Count; right.maxCount = right.Location.spots.Count; bool progress; do { progress = false; int nlMax = Math.Min(this.maxCount - inters.minCount, this.maxCount - other.minCount + right.maxCount); if (nlMax < left.maxCount) { left.maxCount = nlMax; progress = true; } int nlMin = Math.Max(this.minCount - inters.maxCount, this.minCount - other.maxCount + right.minCount); if (nlMin > left.minCount) { left.minCount = nlMin; progress = true; } int nrMax = Math.Min(other.maxCount - inters.minCount, other.maxCount - this.minCount + left.maxCount); if (nrMax < right.maxCount) { right.maxCount = nrMax; progress = true; } int nrMin = Math.Max(other.minCount - inters.maxCount, other.minCount - this.maxCount + left.minCount); if (nrMin > right.minCount) { right.minCount = nrMin; progress = true; } int niMax = Math.Min(this.maxCount - left.minCount, other.maxCount - right.minCount); if (niMax < inters.maxCount) { inters.maxCount = niMax; progress = true; } int niMin = Math.Max(this.minCount - left.maxCount, other.minCount - right.maxCount); if (niMin > inters.minCount) { inters.minCount = niMin; progress = true; } /* i=A-j i=A-B-k j=A-i j=B-k k=B-j k=B-A-i * */ } while (progress); }