void FindSuperabundantBoards(Action <Tuple <string, int> > progress) { NonSuperabundantBoardCount = 0; NonSuperabundantExtraPsiBoardCount = 0; if (!OnlySuperabundantBoards) { return; } for (int i = _remainingBoards.Count - 1; i >= 0; i--) { var b = _remainingBoards[i]; var superabundant = IsSuperabundantForGraph(b, G, 0); if (superabundant) { SuperabundantBoards.Add(b); if (ExtraPsi > 0) { if (ComputeAbundanceSurplus(b) >= ExtraPsi) { SuperabundantWithExtraPsiBoards.Add(b); } else { NonSuperabundantExtraPsiBoardCount++; if (AllIntermediateBoardsInRestrictedClass) { _remainingBoards.RemoveAt(i); DoProgress(progress, "Finding all superabundant positions with extra psi..."); } } } } else { NonSuperabundantBoardCount++; BreakerWonBoards.Add(b); _remainingBoards.RemoveAt(i); DoProgress(progress, "Finding all superabundant positions..."); } } }
bool Analyze(Action <Tuple <string, int> > progress = null) { int winLength = 0; var totalBoards = _remainingBoards.Count; var lastP = -1; BoardsOfDepth = new Dictionary <int, List <SuperSlimBoard> >(); BoardCounts = new List <int>(); BoardCountsList.Add(BoardCounts); BoardCounts.Add(_remainingBoards.Count); for (int i = _remainingBoards.Count - 1; i >= 0; i--) { var b = _remainingBoards[i]; if (_coloringAnalyzer.Analyze(b)) { _remainingBoards.RemoveAt(i); _wonBoards.Add(b); ColorableBoards.Add(b); } if (progress != null) { var p = 100 * (totalBoards - _remainingBoards.Count) / totalBoards; if (p > lastP) { progress(new Tuple <string, int>("Finding all colorable positions...", p)); lastP = p; } } } BoardsOfDepth[winLength] = _wonBoards.ToList(); BoardCounts.Add(_remainingBoards.Count); var nonSuperabundantBoards = new List <SuperSlimBoard>(); for (int i = _remainingBoards.Count - 1; i >= 0; i--) { var b = _remainingBoards[i]; if (!IsSuperabundant(b)) { if (OnlyConsiderNearlyColorableBoards && MissingEdgeIndex >= 0) { HasNonSuperabundantBoardThatIsNearlyColorable = true; BreakerWonBoard = b; if (!PerformCompleteAnalysis) { return(false); } } _remainingBoards.RemoveAt(i); nonSuperabundantBoards.Add(b); } if (progress != null) { var p = 100 * (totalBoards - _remainingBoards.Count) / totalBoards; if (p > lastP) { progress(new Tuple <string, int>("Finding all non-superabundant positions...", p)); lastP = p; } } } if (nonSuperabundantBoards.Count > 0 && !SuperabundantOnly) { if (!OnlyConsiderNearlyColorableBoards && !ExcludeNonNearlyColorableNonSuperabundantBoards) { FixerWonAllNearlyColorableBoards = false; BreakerWonBoard = nonSuperabundantBoards[0]; BreakerWonBoards.AddRange(nonSuperabundantBoards); if (!PerformCompleteAnalysis) { return(false); } } else if (ExistsNearlyColorableBoardForEachEdge(nonSuperabundantBoards)) { FixerWonAllNearlyColorableBoards = false; HasNonSuperabundantBoardThatIsNearlyColorable = true; BreakerWonBoard = nonSuperabundantBoards[0]; BreakerWonBoards.AddRange(nonSuperabundantBoards); if (!PerformCompleteAnalysis) { return(false); } } } BoardCounts.Add(_remainingBoards.Count); NonColorableBoards.AddRange(_remainingBoards); while (_remainingBoards.Count > 0) { var count = _remainingBoards.Count; winLength++; var boardIndicesToAdd = WinFilter.Filter(_remainingBoards, _wonBoards).OrderByDescending(x => x).ToList(); var wonBoards = _remainingBoards.Where((b, i) => boardIndicesToAdd.Contains(i)).ToList(); foreach (var b in wonBoards) { _wonBoards.Add(b); } BoardsOfDepth[winLength] = wonBoards; foreach (var i in boardIndicesToAdd) { _remainingBoards.RemoveAt(i); } if (progress != null) { var p = 100 * (totalBoards - _remainingBoards.Count) / totalBoards; if (p > lastP) { progress(new Tuple <string, int>(string.Format("Finding all {0} move wins...", winLength), p)); lastP = p; } } BoardCounts.Add(_remainingBoards.Count); if (_remainingBoards.Count == count) { BreakerWonBoards.AddRange(_remainingBoards); if (BreakerWonBoard == null) { BreakerWonBoard = _remainingBoards[0]; } if (OnlyConsiderNearlyColorableBoards && MissingEdgeIndex >= 0) { FixerWonAllNearlyColorableBoards = false; } else if (ExistsNearlyColorableBoardForEachEdge(_remainingBoards)) { FixerWonAllNearlyColorableBoards = false; BreakerWonBoard = _remainingBoards.FirstOrDefault(b => _coloringAnalyzer.ColorableWithoutEdge(b, 0)); if (BreakerWonBoard == null) { BreakerWonBoard = _remainingBoards.First(b => _coloringAnalyzer.ColorableWithoutEdge(b, 0)); } } return(false); } } return(true); }