public bool Analyze(int boardID, SortedIntList wonBoardIDs) { if (!_useShrubs) { return(AnalyzeShrubFree(boardID, wonBoardIDs)); } List <List <SortedIntList> > shrub; if (!_shrubs.TryGetValue(boardID, out shrub)) { return(InitializeShrubs(boardID, wonBoardIDs)); } foreach (var colorPairList in shrub) { colorPairList.RemoveAll(branchList => branchList.Intersects(wonBoardIDs)); if (colorPairList.Count <= 0) { return(true); } } return(false); }
bool InitializeShrubs(int boardID, SortedIntList wonBoardIDs) { var shrub = new List <List <SortedIntList> >(); _shrubs[boardID] = shrub; var board = _boardLookup[boardID]; var potKnowledge = _knowledge[board.Template.Value][board.ColorCount]; foreach (var colorPair in potKnowledge.ColorPairs.OrderByDescending(pair => Chronicle.BranchGenerator.EnumerateExactlyOneIntersecters(board, pair).Count() % 2)) { var colorPairList = new List <SortedIntList>(); shrub.Add(colorPairList); var winningSwapAlwaysExists = true; foreach (var branch in Chronicle.BranchGenerator.EnumerateBranches(board, colorPair)) { var branchList = new SortedIntList(); var winningSwapExists = false; foreach (var swap in branch) { board.DoMoveCombination(swap); var childID = _boardIDLookup[board]; board.DoMoveCombination(swap); if (wonBoardIDs.Contains(childID)) { winningSwapExists = true; break; } branchList.Add(childID); } if (!winningSwapExists) { colorPairList.Add(branchList); winningSwapAlwaysExists = false; } } if (winningSwapAlwaysExists) { return(true); } } return(false); }
public bool Intersects(SortedIntList other) { int j = 0; for (int i = 0; i < _length; i++) { var k = Array.BinarySearch <int>(other._data, j, other._length - j, _data[i]); if (k >= 0) { return(true); } j = ~k; } return(false); }
public bool Analyze(Template template, Action <Tuple <string, int> > progress = null) { BoardLookup = new Dictionary <int, Board>(); BoardIDLookup = new Dictionary <Board, int>(); WonBoardIDs = new SortedIntList(); SwapAnalyzer = new SlimSwapAnalyzer(Knowledge, BoardLookup, BoardIDLookup); FixerWonAllNearlyColorableBoards = true; var minimumColorCount = Math.Max(MinPot, template.Sizes.Max()); var maximumColorCount = Math.Min(MaxPot, template.Sizes.Sum()); var foundAtLeastOneBoard = false; foreach (var colorCount in MetaKnowledge.Interval(minimumColorCount, maximumColorCount)) { GenerateAllBoards(template, colorCount, progress); if (foundAtLeastOneBoard && BoardLookup.Count <= 0) { break; } TotalBoards = BoardLookup.Count; foundAtLeastOneBoard = true; RemainingBoardIDs = BoardLookup.Keys.ToList(); var breakerWin = !Analyze(progress); if (breakerWin && StopAnalysisOnBreakerWin) { return(false); } Knowledge[template].Promote(colorCount); } return(Knowledge[template].LostBoards.Count() <= 0); }