/// <summary> /// Input a PossibleBlock if its valid it is returned. Else return NULL /// </summary> /// <param name="pBlock"></param> /// <returns></returns> private bool IsPBlockValid(PossibleBlock pBlock, MainBlock MBlock) { // Does the Possible Block contian all the Cells int MainBlock.CertainCells? if (MBlock.CertainCells.IsSubsetOf(pBlock.Cells)) { //All the Cells in a possible block are looped through. Keeps track to check if all Cells are valid members of the Possible Block. bool isValid = true; // Loop through each cell in this Possible Block foreach (Cell cell in pBlock.Cells) { //Is the Cell owned by a different MainBlock? if (cell.IsOwnedByBlockOtherThan(MBlock)) { //If Cell is owned by other block then this Possible Block is no longer valid. isValid = false; break; } } //If the Possible Block is valid return it. Possible block must be superset of MainBlock.CertainCells && not contain a Cell owned by a different MainBlock if (isValid) { return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// Finds and returns the PossibleBlock from the new Grid that is equivalent to the input PossibleBlock. /// </summary> /// <param name="originalPBlock"></param> /// <param name="newGrid"></param> /// <returns></returns> private PossibleBlock GetEquivalentPossibleBlock(PossibleBlock originalPBlock, Grid newGrid) { // equivalent PossibleBlocks will have the same index in MainBlock.PossibleBlocks in both the orignal and new Grid. int PBlockPosition = OriginalGrid.Blocks[originalPBlock.Index].PossibleBlocks.IndexOf(originalPBlock); return(newGrid.Blocks[originalPBlock.Index].PossibleBlocks[PBlockPosition]); }
/// <summary> /// The input Cells are the equivalent new and original. Gives the new Cell a reference to the correct new PossibleBlock via Cell.PossibleIndexs /// Adds the new Cell to all the relevant new PossibleBlocks.Cells. /// Sets the TopLeftCell of the new PossibleBlocks. /// </summary> /// <param name="newCell"></param> /// <param name="originalCell"></param> private void CreateNewCellPBlockReference(Cell newCell, Cell originalCell) { //PossibleIndexs is a dictionary of <int, List<PossibleBlock>>. The int represents the Blocks Index and the List<PossibleBlock> represents //all the PossibleBlocks of given index that contain this cell foreach (KeyValuePair <int, List <PossibleBlock> > KVP in originalCell.PossibleIndexs) { //create new PossibleBlock List that will be the value of the new Cell's PossibleIndexs. Will contain references to the new PossibleBlocks. List <PossibleBlock> newCellPBlockList = new List <PossibleBlock>(); //The Key represents BlockIndex int blockIndex = KVP.Key; foreach (PossibleBlock originalPBlock in KVP.Value) { //Search for the orignal Possible Block in original Grid.Blocks[relevant].PossibleBlocks and get the position in the list. //The New and Original MainBlocks and PossibleBlocks have the equivalent block at the same position in the list. //This will be used to generate reference to the new Possible Block. int pBlockPosition = OriginalGrid.Blocks[blockIndex].PossibleBlocks.IndexOf(originalPBlock); //Create reference to the new PossibleBlock that is equivalent to the original PossibleBlock newPBlock = NewGrid.Blocks[blockIndex].PossibleBlocks[pBlockPosition]; //The new Cell is a Member of the new PossibleBlock newPBlock.Cells.Add(newCell); //The input Cells are the equivalents. If the original Cell is the TopLeftCell then the new Cell must also be if (originalPBlock.TopLeftCell == originalCell) { newPBlock.TopLeftCell = newCell; } newCellPBlockList.Add(newPBlock); } newCell.PossibleIndexs.Add(blockIndex, newCellPBlockList); } }
/// <summary> /// Clones a single PossibleBlock and returns it. The new PossibleBlock references the new Grid. /// </summary> /// <param name="originalPBlock"></param> /// <returns></returns> private PossibleBlock DeepClonePossibleBlock(PossibleBlock originalPBlock) { ///new Possible PossibleBlock newPossibleBlock = new PossibleBlock(originalPBlock.Index, originalPBlock.Area, originalPBlock.DefinedCell, NewGrid); newPossibleBlock.Dimensions = originalPBlock.Dimensions; return(newPossibleBlock); //TopLeftCell (Cell) and Cells(Hashset<Cell>) remain unfilled for now as the new cells have not been created yet. }
/// <summary> /// Finds the Largest Unsolved MainBlock. For each PossibleBlock in the MainBlock.PossibleBlock, Clones the Grid and sets the relevant PossibleBlock to be the Mainblock. /// Adds all the copied grids to a list and returns the list. /// </summary> /// <returns></returns> public List <Grid> GetGridsWithSetBlocks() { MainBlock largestUnsolved = GetLargestUnsolvedMainBlock(); GridPlusSetBlocks = new List <Grid>(); foreach (PossibleBlock possibleBlock in largestUnsolved.PossibleBlocks) { Grid newGrid = _cloneGrid.CloneGrid(); PossibleBlock toTry = GetEquivalentPossibleBlock(possibleBlock, newGrid); toTry.SetAsMainBlock(); GridPlusSetBlocks.Add(newGrid); } return(GridPlusSetBlocks); }
/// <summary> /// Loops through all MainBlocks. Removes invalid PossibleBlocks. If there /// </summary> public void RemoveImposBlocksAndsetCertain() { foreach (MainBlock MBlock in Grid.Blocks) { RemoveImpossibleBlocks(MBlock); if (MBlock.PossibleBlocks.Count == 1) { PossibleBlock pBlock = MBlock.PossibleBlocks[0]; pBlock.SetAsMainBlock(); } else if (MBlock.PossibleBlocks.Count == 0) { ProvesNoSolution = true; } } }
/// <summary> /// Creates a possible block by adding cells to a collection. If all the cells are lie within the grid and are not owned by another block, the possible block is valid. /// If the possible block is valid it is created and added to the relevant Block.PossibleBlocks /// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <param name="xDim"></param> /// <param name="yDim"></param> private void CreatePossibleBlock(int i, int j, int xDim, int yDim, MainBlock block) { //xPos and yPos represent coordinates of the TopLefTCell of the PossibleBlock. int xPos = block.DefinedCell.XPos + i, yPos = block.DefinedCell.YPos + j; HashSet <Cell> tempHash = new HashSet <Cell>(); for (int k = 0; k < xDim; k++) { for (int l = 0; l < yDim; l++) { if (Grid.AreValidCoordinates(xPos + k, yPos + l)) { Cell tempCell = Grid.Cells[xPos + k, yPos + l]; if (!tempCell.IsOwnedByBlockOtherThan(block)) { tempHash.Add(tempCell); } else { return; } } else { return; } } } PossibleBlock tempBlock = new PossibleBlock(block.Index, block.Area, block.DefinedCell, Grid) { Cells = tempHash, TopLeftCell = Grid.Cells[xPos, yPos] }; tempBlock.Dimensions[0] = xDim; tempBlock.Dimensions[1] = yDim; block.PossibleBlocks.Add(tempBlock); }