public Resolution Check(WavePropagator wp) { var wave = wp.Wave; var indices = wp.Indices; // Initialize couldBePath and mustBePath based on wave possibilities var couldBePath = new bool[indices]; var mustBePath = new bool[indices]; for (int i = 0; i < indices; i++) { var couldBe = false; var mustBe = true; for (int p = 0; p < wp.PatternCount; p++) { if (wave.Get(i, p)) { if (PathPatterns.Contains(p)) { couldBe = true; } if (!PathPatterns.Contains(p)) { mustBe = false; } } } couldBePath[i] = couldBe; mustBePath[i] = mustBe; } // Select relevant cells, i.e. those that must be connected. bool[] relevant; if (EndPoints == null) { relevant = mustBePath; } else { relevant = new bool[indices]; if (EndPoints.Length == 0) { return(Resolution.Undecided); } foreach (var endPoint in EndPoints) { var index = wp.Topology.GetIndex(endPoint.X, endPoint.Y, endPoint.Z); relevant[index] = true; } } var walkable = couldBePath; var isArticulation = PathConstraintUtils.GetArticulationPoints(wp.Topology, walkable, relevant); if (isArticulation == null) { return(Resolution.Contradiction); } // All articulation points must be paths, // So ban any other possibilities for (var i = 0; i < indices; i++) { if (!isArticulation[i]) { continue; } for (int p = 0; p < wp.PatternCount; p++) { if (!PathPatterns.Contains(p) && wave.Get(i, p)) { wp.InternalBan(i, p); } } } return(Resolution.Undecided); }