public StepNode(NineSquareElement startElement = null, int index = -1, bool rotated = false, bool bt = false) { StartAtElement = startElement; ElementIndex = index; RotateCW = rotated; BT = bt; }
public static NineSquareElement[] GetElementsNear(ref NineSquareElement elementRelatedTo, ref NineSquareElement[] nineSquareElements) { if ((nineSquareElements?.Count() ?? 0) < 9) return null; var index = IndexOf(elementRelatedTo, nineSquareElements); if (index == -1) return null; int row = index/3; int col = index%3; NineSquareElement[] elements = new NineSquareElement[4]; //Console.WriteLine("l t r b : {0} {1} {2} {3}", (col - 1 < 0 ? 2 : col - 1) + (row*3), // col + ((row - 1 < 0 ? 2 : row - 1)*3), ((col + 1)%3) + (row*3), col + (((row + 1)%3)*3)); // left elements[0] = nineSquareElements[(col - 1 < 0 ? 2 : col - 1) + (row*3)]; // top elements[1] = nineSquareElements[col + ((row - 1 < 0 ? 2 : row - 1)*3)]; // right elements[2] = nineSquareElements[((col + 1)%3) + (row*3)]; // bottom elements[3] = nineSquareElements[col + (((row + 1)%3)*3)]; return elements; }
public static bool CheckSolvable(NineSquareElement[] elements) { int result = 0; // check non-null and element count == 9 if ((elements?.Count() ?? 0) != 9) return false; // add up all edges // should return 0 if valid. elements.ToList() .ForEach( element => result += element.EdgeLeftWeight + element.EdgeTopWeight + element.EdgeRightWeight + element.EdgeBottomWeight); return result == 0; }
private void button1_Click(object sender, EventArgs e) { NineSquareElement[] elements = new NineSquareElement[9]; for (int i = 0; i < 9; i++) { int left = 0, right = 0, top = 0, bottom = 0; var textBox = FindControl("textBox" + (i + 1) + "l") as TextBox; int.TryParse(textBox.Text.Trim(), out left); textBox = FindControl("textBox" + (i + 1) + "t") as TextBox; int.TryParse(textBox.Text.Trim(), out top); textBox = FindControl("textBox" + (i + 1) + "r") as TextBox; int.TryParse(textBox.Text.Trim(), out right); textBox = FindControl("textBox" + (i + 1) + "b") as TextBox; int.TryParse(textBox.Text.Trim(), out bottom); NineSquareElement element = new NineSquareElement(left, top, right, bottom); elements[i] = element; } NineSquarePuzzle puzzle = new NineSquarePuzzle(elements); if (!NineSquarePuzzle.CheckSolvable(elements)) MessageBox.Show("Invalid Puzzle..", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); if (puzzle.Solve()) { for (int i = 0; i < 9; i++) { int left = 0, right = 0, top = 0, bottom = 0; var textBox = FindControl("textBox" + (i + 1) + "l") as TextBox; textBox.Text = puzzle.SolvedNineSquareElements[i].EdgeLeftWeight.ToString(); textBox = FindControl("textBox" + (i + 1) + "t") as TextBox; textBox.Text = puzzle.SolvedNineSquareElements[i].EdgeTopWeight.ToString(); textBox = FindControl("textBox" + (i + 1) + "r") as TextBox; textBox.Text = puzzle.SolvedNineSquareElements[i].EdgeRightWeight.ToString(); textBox = FindControl("textBox" + (i + 1) + "b") as TextBox; textBox.Text = puzzle.SolvedNineSquareElements[i].EdgeBottomWeight.ToString(); } } }
public static int IndexOf(NineSquareElement element, NineSquareElement[] elements) { var index = -1; for (var i = 0; i < 9; i++) { if (elements[i] == element) index = i; } return index; }
private void Revert(ref NineSquareElement[] oldElements, ref NineSquareElement[] newElements) { if (oldElements == null) return; if (newElements == null) newElements = new NineSquareElement[9]; oldElements.CopyTo(newElements, 0); for (int i = 0; i < 9; i++) { if (i + 1 < 9) newElements[i].ForwardElement = newElements[i + 1]; else newElements[i].ForwardElement = null; } }
public bool LoadPuzzle(NineSquareElement[] puzzleElements) { bool validPuzzle = CheckSolvable(puzzleElements); if (validPuzzle) { NineSquareElements = puzzleElements; for (int i = 0; i < 9; i++) { if (i + 1 < 9) NineSquareElements[i].ForwardElement = NineSquareElements[i + 1]; else NineSquareElements[i].ForwardElement = null; } } return validPuzzle; }
public NineSquarePuzzle(NineSquareElement[] puzzleElements = null) { LoadPuzzle(puzzleElements); }
public bool BT(NineSquareElement start, ref NineSquareElement[] nineSquareElements) { int rotateCount = 0; NineSquareElement[] oldElements = null; // used here to clone current elements into oldElements Revert(ref nineSquareElements, ref oldElements); if (VerifySolved(nineSquareElements)) return true; ++nestedCount; while (start != null) { var elements = GetElementsNear(ref start, ref nineSquareElements); if (rotateCount <= 3) { if (VerifySolved(nineSquareElements)) { --nestedCount; return true; } else if (BT(start.ForwardElement, ref nineSquareElements)) { --nestedCount; // verify this particular node. return true; } else if (rotateCount <= 3) { // Check & Rotate StepsToSolve.Enqueue(new StepNode((NineSquareElement) start.Clone(), IndexOf(start, nineSquareElements), true)); NineSquarePuzzle puzzle = new NineSquarePuzzle(nineSquareElements); VisualPuzzleSolve.Enqueue(puzzle); start.RotateCW(); rotateCount++; } else if (rotateCount > 3 && start != nineSquareElements[0]) { // backtrack //Console.WriteLine("BT..."); StepsToSolve.Enqueue(new StepNode((NineSquareElement) start.Clone(), IndexOf(start, nineSquareElements), false, true)); Revert(ref oldElements, ref nineSquareElements); NineSquarePuzzle puzzle = new NineSquarePuzzle(nineSquareElements); VisualPuzzleSolve.Enqueue(puzzle); } else { --nestedCount; return false; } } else { --nestedCount; return false; } } --nestedCount; return false; }
public static bool VerifySolved(NineSquareElement[] elements) { if (elements?.Count() != 9) return false; int i = 0; bool result = true; foreach (var element in elements) { var directionalElements = GetElementsNear(ref elements[i++], ref elements); if (element.EdgeLeftWeight + directionalElements[0].EdgeRightWeight != 0 || element.EdgeTopWeight + directionalElements[1].EdgeBottomWeight != 0 || element.EdgeRightWeight + directionalElements[2].EdgeLeftWeight != 0 || element.EdgeBottomWeight + directionalElements[3].EdgeTopWeight != 0) { result = false; break; } } return result; }
public static void PrintPuzzle(NineSquareElement[] elements) { string line1 = "", line2 = "", line3 = ""; string s = ""; int i = 0; for (i = 0; i <= 9; i++) { if (i%3 == 0 && i != 0) { s = line1 + "\n" + line2 + "\n" + line3 + "\n" + new string('-', 16*3 + 5); line1 = ""; line2 = ""; line3 = ""; Console.WriteLine(s); if (i == 9) break; } line1 += "\t" + elements[i].EdgeTopWeight + "\t | "; line2 += elements[i].EdgeLeftWeight + "\t\t" + elements[i].EdgeRightWeight + " | "; line3 += "\t" + elements[i].EdgeBottomWeight + "\t | "; } }