public bool InternalSelect(int index, int chosenPattern) { for (var pattern = 0; pattern < patternCount; pattern++) { if (pattern == chosenPattern) { continue; } if (wave.Get(index, pattern)) { if (InternalBan(index, pattern)) { return(true); } } } return(false); }
public void DoBan(int index, int pattern) { // Assumes DoBan is called before wave.RemovePossibility if (wave.GetPatternCount(index) == 2) { for (var p = 0; p < patternCount; p++) { if (p == pattern) { continue; } if (wave.Get(index, p)) { DoSelect(index, p); return; } } } }
public bool InternalSelect(int index, int chosenPattern) { // Simple, inefficient way if (!Optimizations.QuickSelect) { for (var pattern = 0; pattern < patternCount; pattern++) { if (pattern == chosenPattern) { continue; } if (wave.Get(index, pattern)) { if (InternalBan(index, pattern)) { return(true); } } } return(false); } bool isContradiction = false; patternModelConstraint.DoSelect(index, chosenPattern); for (var pattern = 0; pattern < patternCount; pattern++) { if (pattern == chosenPattern) { continue; } if (wave.Get(index, pattern)) { // This is mostly a repeat of InternalBan, as except for patternModelConstraint, // Selects are just seen as a set of bans // Record information for backtracking if (backtrack) { backtrackItems.Push(new IndexPatternItem { Index = index, Pattern = pattern, }); } // Don't update patternModelConstraint here, it's been done above in DoSelect // Update the wave isContradiction = isContradiction || wave.RemovePossibility(index, pattern); // Update trackers foreach (var tracker in trackers) { tracker.DoBan(index, pattern); } } } return(false); }
/** * Resets the wave to it's original state */ public Resolution Clear() { wave = new Wave(frequencies, indices, topology.Mask); toPropagate.Clear(); status = Resolution.Undecided; if (backtrack) { prevWaves = new Stack <Wave>(); prevCompatible = new Stack <int[, , ]>(); prevChoices = new Stack <PropagateItem>(); } compatible = new int[indices, patternCount, directionsCount]; for (int index = 0; index < indices; index++) { if (!topology.ContainsIndex(index)) { continue; } for (int pattern = 0; pattern < patternCount; pattern++) { for (int d = 0; d < directionsCount; d++) { var inverseDirection = topology.Directions.Inverse(d); var compatiblePatterns = propagator[pattern][inverseDirection].Length; compatible[index, pattern, d] = compatiblePatterns; if (compatiblePatterns == 0 && topology.TryMove(index, inverseDirection, out var dest) && wave.Get(index, pattern)) { if (InternalBan(index, pattern)) { return(status = Resolution.Contradiction); } break; } } } } return(InitConstraints()); }