/// <summary> /// Compare the number of the Cell.PossibleOwners for a MainBlock to the number of MainBlock.PossibleBlocks. If the number is the same, the MainBlock requires that Cell to have a solution. /// If this occurs once for the Cell -> mark the Cell as owned. /// If this occurs more that once, multiple MainBlocks require the Cell for a solution, hence no solution is possible. /// </summary> private bool CompareCellToMainBlock(ICell cell) { LinkedListNode <IMainBlock> currentMainBlockNode = cell.GetPossibleMainBlocks.First; int counter = 0; IMainBlock BlockRequringCell = null; while (currentMainBlockNode != null) { if (cell.GetPossibleOwners[currentMainBlockNode.Value].Count == currentMainBlockNode.Value.PossibleBlocks.Count) { //Keep a reference to the last MainBlock that fulfilled the criteria, will be used if the count is 1. BlockRequringCell = currentMainBlockNode.Value; counter++; } currentMainBlockNode = currentMainBlockNode.Next; } if (counter == 1) { if (_ownershipSetter.MarkCellAsOwned(cell, BlockRequringCell) == true) { return(true); } } if (counter > 1) { return(true); } return(false); }
/// <summary> /// For the current Cell, loops though the PossibleOwners removing each value from the respective MainBlock.PossibleBlocks, except the OwnerMainBlock. /// </summary> public List <IMainBlock> RemoveImpossibleBlocks(ICell cell, IMainBlock mainBlock) { LinkedListNode <IMainBlock> CurrentMainBlockNode = cell.GetPossibleMainBlocks.First; List <IMainBlock> MainBlocksWithOnePossibleBlock = new List <IMainBlock>(); while (CurrentMainBlockNode != null) { if (mainBlock != CurrentMainBlockNode.Value) { foreach (int possibleBlock in cell.GetPossibleOwners[CurrentMainBlockNode.Value]) { CurrentMainBlockNode.Value.PossibleBlocks.Remove(possibleBlock); } if (CurrentMainBlockNode.Value.PossibleBlocks.Count == 0) { return(null); } else if (CurrentMainBlockNode.Value.PossibleBlocks.Count == 1) { MainBlocksWithOnePossibleBlock.Add(CurrentMainBlockNode.Value); } } CurrentMainBlockNode = CurrentMainBlockNode.Next; } return(MainBlocksWithOnePossibleBlock); }
/// <summary> /// Sets the DimensionSet, DimensionSet and MultipleMatrix properties. /// </summary> public static IPossibleBlock CreatPossibleBlockFromDimensionSetIndex(IMainBlock mainBlock, Dictionary <int, List <List <int> > > blockDimensionSets, int dimensionSetIndex) { IPossibleBlock possibleBlock = new PossibleBlock(mainBlock); possibleBlock.DimensionSetIndex = dimensionSetIndex; possibleBlock.DimensionSet = blockDimensionSets[mainBlock.Capacity][dimensionSetIndex]; possibleBlock.MultipleMatrix = AdditionalMethods.GetMultipleMatrix(possibleBlock.DimensionSet); return(possibleBlock); }
/// <summary> /// Marks the current Cell as owned by the current OwnerMainBlock, hence these properties need to be set correctly before calling this method. /// </summary> public bool MarkCellAsOwned(ICell cell, IMainBlock mainBlock) { ChangeHasOccured = true; if (CheckMainBlocks(_possibleBlockRemover.RemoveImpossibleBlocks(cell, mainBlock))) { return(true); } _possibleBlockRemover.SetOwnerMainBlockPossibleBlocks(cell, mainBlock); cell.Owner = mainBlock; return(false); }
/// <summary> /// Considers a single MainBlock at a time. /// </summary> private void ProcessMainBlock(IMainBlock mainBlock) { int dimensionSetIndex = 0; while (dimensionSetIndex < _solutionTracker.BlockDimensionSets[mainBlock.Capacity].Count) { PossibleBlock = AdditionalMethods.CreatPossibleBlockFromDimensionSetIndex(mainBlock, _solutionTracker.BlockDimensionSets, dimensionSetIndex); ProcessDimensionSet(); dimensionSetIndex++; } }
/// <summary> /// When the current Cell is marked as owned, only the possible blocks that contain this cell are valid. /// The MainBlock.PossibleBlock is updated accordingly. /// </summary> public void SetOwnerMainBlockPossibleBlocks(ICell cell, IMainBlock mainBlock) { HashSet <int> possibleBlocks = new HashSet <int>(); foreach (int possibleBlock in cell.GetPossibleOwners[cell.Owner]) { possibleBlocks.Add(possibleBlock); } mainBlock.PossibleBlocks = possibleBlocks; }
/// <summary> /// The input is the global list of MainBlocks, Grid.MainBlocks. /// </summary> /// <param name="mainBlocks"></param> /// <returns></returns> public static IMainBlock GetMainBlockWithFewestPossibleBlock(List <IMainBlock> mainBlocks) { //Keeps Tract of the MainBlock with the fewest remaining PossibleBlock. //It is returned and will be used to set each of its PossibleBlocks. IMainBlock MBWithFewestPB = null; foreach (IMainBlock mainBlock in mainBlocks) { if (mainBlock.Solution == -1) { if (MBWithFewestPB == null) { MBWithFewestPB = mainBlock; } else if (mainBlock.PossibleBlocks.Count < MBWithFewestPB.PossibleBlocks.Count) { MBWithFewestPB = mainBlock; } } } return(MBWithFewestPB); }
/// <summary> /// The MainBlock that this PossibleBlock belongs to. The SolutionTracker contains all possible DimensionSets. /// </summary> /// <param name="mainBlock"></param> /// <param name="solutionTracker"></param> public PossibleBlock(IMainBlock mainBlock) { MainBlock = mainBlock; }