// --------------------------------------------------- //GENERAL USEFUL FUNCTIONS // --------------------------------------------------- private PuzzleSolverTile[] reverseList(PuzzleSolverTile[] original) { //reverses a list of PuzzleSolverTile objects PuzzleSolverTile[] newList = new PuzzleSolverTile[size]; for (int i = 0; i < size; i++) { int oppositeIndex = size - i; newList[i] = original[oppositeIndex - 1]; } return(newList); }
private void addHintsToTiles() { //each Tile has 4 hints that it contributes to. This adds those hints as properties of the tiles for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { PuzzleSolverTile tile = tilesArray[i, j]; tile.topHintTile = topHints[j]; tile.bottomHintTile = bottomHints[j]; tile.leftHintTile = leftHints[i]; tile.rightHintTile = rightHints[i]; } } }
private void createEmptyPuzzle() { //creates an empty puzzle of PuzzleSolverTile objects tilesArray = new PuzzleSolverTile[size, size]; tilesList = new PuzzleSolverTile[size * size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { PuzzleSolverTile x = new PuzzleSolverTile(); tilesArray[i, j] = x; tilesList[(i * size) + j] = x; x.xValue = j; x.yValue = i; } } }
private void immediateProhibition() { //the part of the puzzle-solving algorithm that happens second. Called by SolvePuzzle //any tile with numbers that can immediately be removed as possible solutions are crossed-out here foreach (PuzzleSolverSideTile h in hintsList) { //if hint is between 1 and the max number (exclusive), the tiles next to it cannot be high numbers if ((h.hint > 1) && (h.hint < size)) { int numTiles = h.hint - 1; for (int i = 0; i < numTiles; i++) { PuzzleSolverTile tile = h.row[i]; int prohibitTopX = numTiles - i; for (int j = 0; j < prohibitTopX; j++) { tile.prohibitValue(size - j); } } } } }
private void iterativeProhibition() { //every iteration, checks all hints and tiles to see which numbers can be crossed-out. Called by SolvePuzzle foreach (PuzzleSolverSideTile h in hintsList) { //go through every row, and add all used values as prohibited to other tiles List <int> containedValues = new List <int>(); foreach (PuzzleSolverTile t in h.row) { if (t.value != 0) { containedValues.Add(t.value); } } foreach (PuzzleSolverTile t in h.row) { t.prohibitValues(containedValues); } //if hint is between 1 and size (exclusive) and the row is already populated, you can prohibit high values on tiles near the hint if ((h.hint > 1) && (h.hint < size) && h.hasATileInRowBeenPopulated() && (!h.row[0].populated)) { List <int> unusedNumbers = h.getUnusedNumbers();//assumes unusedNumbers is sorted List <int> unusedNumbersHighToLow = reverseList(unusedNumbers); int numVisible = h.numBuildingsCurrentlyVisible(); int numYetToBeVisible = h.hint - numVisible; int tilesToProhibit = numYetToBeVisible - 1; for (int i = 0; i < tilesToProhibit; i++) { PuzzleSolverTile t = h.row[i]; int prohibitHighestX = tilesToProhibit - i; List <int> valuesToProhibit = new List <int>(); for (int j = 0; j < prohibitHighestX; j++) { valuesToProhibit.Add(unusedNumbersHighToLow[j]); } t.prohibitValues(valuesToProhibit); } } //if hint is 2, the highest remaining number in the row can't be between the adjacent tile and the highest value if ((h.hint == 2) && (!h.row[0].populated) && (h.isHighestValueInRow())) { List <int> u = h.getUnusedNumbers(); int highestUnusedVal = u[u.Count - 1]; bool foundMax = false; foreach (PuzzleSolverTile t in h.row) { if (t.value == size) { foundMax = true; } if ((!foundMax) && (t != h.row[0])) { t.prohibitValue(highestUnusedVal); } } } } foreach (PuzzleSolverTile t in tilesList) { //if a tile is populated, add all other numbers to its prohibited list if (t.populated) { for (int i = 1; i <= size; i++) { t.prohibitValue(i); } } } }