public bool startsolve() { current = FirstNode = FindFirstNode(); HintStack.Push(FirstNode); maxval = FindMaxVal(); history = new history(); history.AddNode(current); NextNode = FindNextNode(current); HintStack.Push(NextNode); if (solve()) { return(true); } else { return(false); } }
private bool solve() { show(); PrevNode = HintStack.Peek(); bool PrevNodeIsPossible = ChekPrevPossibleVal(current); if (HintStack.Peek().data != NextNode.data) { HintStack.Push(FindNextNode(current)); PrevNode = HintStack.Peek(); } if (current.data == NextNode.data - 1 && NextNode.data != maxval) { if (PrevNodeIsPossible == true) { current = NextNode; hidatoCount = current.data; NextNode = FindNextNode(current); } else { if (InsertCount < 50) { InsertCount++; } else if (HowManyExitStack >= PossibleHowManyExitStack) { HowManyExitStack = 1; InsertCount = 0; } else { HowManyExitStack++; InsertCount = 0; } StackCount = 1; if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } if (current.data != PrevNode.data) { current.data = 0; } current = history.GetPrevElement().node; hidatoCount = current.data; return(false); } } } else if (current.data == maxval - 1 && ChekPrevPossibleVal(current)) { return(true); } if ((current != NextNode) && (current.data == NextNode.data)) { if (InsertCount < 50) { InsertCount++; } else if (HowManyExitStack >= PossibleHowManyExitStack) { HowManyExitStack = 1; InsertCount = 0; } else { HowManyExitStack++; InsertCount = 0; } StackCount = 1; if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } if (PrevNode.data != current.data) { current.data = 0; } current = history.GetPrevElement().node; hidatoCount = current.data; return(false); } } SurchMarking marker = FindOption(current); if (marker.sizeOfnumSet() == 0) { if (InsertCount < 50) { InsertCount++; } else if (HowManyExitStack >= PossibleHowManyExitStack) { HowManyExitStack = 1; InsertCount = 0; } else { HowManyExitStack++; InsertCount = 0; } StackCount = 1; if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } if (PrevNode.data != current.data) { current.data = 0; } current = history.GetPrevElement().node; hidatoCount = current.data; return(false); } } //SurchMarking marker1 = ChekPrevNodeCorrectVal(NextNode); //8개의 인접한 칸에 뭐가 있으면서도(0이 아니면) 이전노드보다 1이 작지 않으면 for (int i = 0; i < 8; i++) { while (StackCount < HowManyExitStack) { StackCount++; if (current.data != 1) { current.data = 0; current = history.GetPrevElement().node; hidatoCount = current.data; return(false); } } if (marker.SurchMarker[(int)side.N] == true) { //HowManyTry++; //현재노드를 북쪽으로 설정한 다음 current = current.N; hidatoCount++; current.data = hidatoCount; history.AddNode(current); //이미 탐색한 자리임으로 false마킹 marker.SurchMarker[(int)side.N] = false; } else if (marker.SurchMarker[(int)side.NE] == true) { //HowManyTry++; current = current.NE; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.NE] = false; } else if (marker.SurchMarker[(int)side.E] == true) { //HowManyTry++; current = current.E; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.E] = false; } else if (marker.SurchMarker[(int)side.SE] == true) { //HowManyTry++; current = current.SE; history.AddNode(current); hidatoCount++; current.data = hidatoCount; marker.SurchMarker[(int)side.SE] = false; } else if (marker.SurchMarker[(int)side.S] == true) { //HowManyTry++; current = current.S; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.S] = false; } else if (marker.SurchMarker[(int)side.SW] == true) { //HowManyTry++; current = current.SW; history.AddNode(current); marker.SurchMarker[(int)side.SW] = false; hidatoCount++; current.data = hidatoCount; } else if (marker.SurchMarker[(int)side.W] == true) { //HowManyTry++; current = current.W; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.W] = false; } else if (marker.SurchMarker[(int)side.NW] == true) { //HowManyTry++; current = current.NW; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.NW] = false; } else { if (InsertCount < 50) { InsertCount++; } else if (HowManyExitStack >= PossibleHowManyExitStack) { InsertCount = 0; HowManyExitStack = 1; } else { HowManyExitStack++; InsertCount = 0; } StackCount = 1; if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } if (PrevNode.data != current.data) { current.data = 0; } current = history.GetPrevElement().node; hidatoCount = current.data; return(false); } else { continue; } } //if(solve())와 같은 표현 if (solve() == true) { return(true); } } return(false); }
private bool solve() { ///디버그 하기 쉽게 출력을 시켜줌 show(); int DataOfCurrentNode = current.data; PrevNode = HintStack.Peek(); bool PrevNodeIsPossible = ChekPrevPossibleVal(current); ///HintStack의 맨 위에 있는 노드의 데이타가 다음 노드의 데이타와 같지 않으면 if (HintStack.Peek().data != NextNode.data) { ///현재 노드의 다음 노드를 찾아서 집어넣음 HintStack.Push(FindNextNode(current)); ///이전 노드는 힌트 스텍의 맨 위쪽 PrevNode = HintStack.Peek(); } SurchMarking marker = FindOption(current); ///현재 노드의 데이터가 다음 노드의 데이터보다 1이 작고, 다음 노드가 최대값이 아니면서 if (current.data == NextNode.data - 1 && NextNode.data != maxval) { ///바로 이전 노드가 올바르면(붙어 있으면) if (PrevNodeIsPossible == true) { //NextNode를 업데이트하고 현재 노드를 업데이트 전의 NextNode로 바꿈 current = NextNode; hidatoCount = current.data; NextNode = FindNextNode(current); history.AddNode(current); if (solve()) { return(true); } } else //그렇지 않으면 { ///InsertCount를 +1하고, if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } //현재 노드가 힌트와 겹치면(히다토에서 미리 정해져 있는 상수) if (current.data == PrevNode.data) { //바로 이전 노드로 되돌리기만함 current = history.GetPrevElement().node; } else { //아니면, 현재노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 current.data = 0; current = history.GetPrevElement().node; } //HidatoCount변수를 바꾼 현재노드의 데이터로 설정한 후 hidatoCount = current.data; //NextNode변수를 업데이트 하고 NextNode = FindNextNode(current); hidatoCount = current.data; return(false); } } } else if (current.data == maxval - 1 && PrevNodeIsPossible == true) { return(true); } if (current.data == NextNode.data - 1 && PrevNodeIsPossible == false) { if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } //현재 노드가 힌트와 겹치면(히다토에서 미리 정해져 있는 상수) if (current.data == PrevNode.data) { //바로 이전 노드로 되돌리기만함 current = history.GetPrevElement().node; } else { //아니면, 현재노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 current.data = 0; current = history.GetPrevElement().node; } //HidatoCount변수를 바꾼 현재노드의 데이터로 설정한 후 hidatoCount = current.data; NextNode = FindNextNode(current); return(false); } } if ((current != NextNode) && (current.data == NextNode.data)) { if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } current.data = 0; current = history.GetPrevElement().node; hidatoCount = current.data; NextNode = FindNextNode(current); hidatoCount = current.data; return(false); } } if (marker.sizeOfnumSet() == 0) { if (current.data != 1) { //PrevNode변수는 HintStack에 가장 윗 부분이다.HintStack의 가장 윗부분은 NextNode임으로(다음 노드임으로) if (PrevNode.data > current.data) { //가장 윗부분을 덜어낸 다음 HintStack.Pop(); //덜어낸 스택의 가장 윗부분을 이전 노드로 설정 PrevNode = HintStack.Peek(); } //현재 노드가 힌트와 겹치면(히다토에서 미리 정해져 있는 상수) if (current.data == PrevNode.data) { //바로 이전 노드로 되돌리기만함 current = history.GetPrevElement().node; } else { //아니면, 현재노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 current.data = 0; current = history.GetPrevElement().node; } //HidatoCount변수를 바꾼 현재노드의 데이터로 설정한 후 hidatoCount = current.data; //바로 NextNode를 업데이트 하고 NextNode = FindNextNode(current); return(false); } } //SurchMarking marker1 = ChekPrevNodeCorrectVal(NextNode); //8개의 인접한 칸에 뭐가 있으면서도(0이 아니면) 이전노드보다 1이 작지 않으면 for (int i = 0; i < 8; i++) { if (marker.SurchMarker[(int)side.N] == true) { //현재노드를 북쪽으로 설정한 다음 current = current.N; hidatoCount++; current.data = hidatoCount; history.AddNode(current); //이미 탐색한 자리임으로 false마킹 marker.SurchMarker[(int)side.N] = false; } else if (marker.SurchMarker[(int)side.NE] == true) { current = current.NE; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.NE] = false; } else if (marker.SurchMarker[(int)side.E] == true) { current = current.E; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.E] = false; } else if (marker.SurchMarker[(int)side.SE] == true) { current = current.SE; history.AddNode(current); hidatoCount++; current.data = hidatoCount; marker.SurchMarker[(int)side.SE] = false; } else if (marker.SurchMarker[(int)side.S] == true) { current = current.S; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.S] = false; } else if (marker.SurchMarker[(int)side.SW] == true) { current = current.SW; history.AddNode(current); hidatoCount++; current.data = hidatoCount; marker.SurchMarker[(int)side.SW] = false; } else if (marker.SurchMarker[(int)side.W] == true) { //HowManyTry++; current = current.W; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.W] = false; } else if (marker.SurchMarker[(int)side.NW] == true) { //HowManyTry++; current = current.NW; hidatoCount++; current.data = hidatoCount; history.AddNode(current); marker.SurchMarker[(int)side.NW] = false; } else { if (current.data != 1) { if (PrevNode.data > current.data) { HintStack.Pop(); PrevNode = HintStack.Peek(); } //현재 노드가 힌트와 겹치면(히다토에서 미리 정해져 있는 상수) if (current.data == PrevNode.data) { //바로 이전 노드로 되돌리기만함 current = history.GetPrevElement().node; } else { //아니면, 현재노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 current.data = 0; current = history.GetPrevElement().node; } //HidatoCount변수를 바꾼 현재노드의 데이터로 설정한 후 hidatoCount = current.data; return(false); } else { continue; } } //if(solve())와 같은 표현 if (solve() == true) { return(true); } } return(false); }
private bool Solve() { #if DEBUG //디버그 할 때만 할당되는 모니터링용 변수 int CurrentData = current.Data; #endif if (SolveCancel) { return(true); } bool PrevNodeIsPossible = ChekPrevPossibleVal(current); current.marker = FindOption(current); //비어있는 칸이 더 이상 없으면 if (EmptyNodeCount == 0) { //풀린 것 return(true); } //현재 노드의 데이터가 다음 노드의 데이터보다 1이 작고, 다음 노드가 최댓값이 아니면서 #region 현재 노드와 NextNode가 실제로 붙어 있는지 검사 if (current.Data == NextNode.Data - 1 && PrevNodeIsPossible == true) { //지금 현재 노드와 다음 노드가 붙어 있으면 history.AddNode(current); if (SmartSuch == true) { current = FindMinPossibe(); NextNode = FindNextNode(current); } else { //NextNode를 업데이트하고 현재 노드를 업데이트 전의 NextNode로 바꿈 current = NextNode; hidatoCount = current.Data; NextNode = FindNextNode(current); } if (Solve()) { return(true); } } else if (current.Data == NextNode.Data - 1 && PrevNodeIsPossible == false) { if (current.Data != 1) { //현재 노드의 작업 공간(worksace)를 0으로 설정하고,(변경사항 없음 이라고 표시) 바로 이전 노드로 되돌림 HidatoGrid.Node prevNode = history.GetPrevNode(current); current.WorkSapce = 0; current.EmptyMarker(); //애초에 빈 노드이므로 EmptyNodecount를 1증가시킴 if (current.Input == 0) { EmptyNodeCount++; } current = prevNode; //HidatoCount변수를 바꾼 현재 노드의 데이터로 설정한 후 hidatoCount = current.Data; //NextNode를 업데이트 함 NextNode = FindNextNode(current); #region 모니터링 하기 위해 업데이트 하는 부분 if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } #endregion #if DEBUG HoWManyExit++; Console.WriteLine(""); Console.WriteLine("{0}", EmptyNodeCount); Console.WriteLine("{0}", maxval - HintCount()); Console.WriteLine("{0}", HoWManyExit); #endif return(false); } } if ((current.Data == NextNode.Data) && (current != NextNode)) { if (current.Data != 1) { HidatoGrid.Node prevNode = history.GetPrevNode(current); current.WorkSapce = 0; current.EmptyMarker(); if (current.Input == 0) { EmptyNodeCount++; } current = prevNode; hidatoCount = current.Data; //NextNode를 업데이트 함 NextNode = FindNextNode(current); #region 모니터링 하기 위해 업데이트 하는 부분 if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } #endregion return(false); } } if (current.marker.SizeOfnumSet() == 0) { if (current.Data != 1) { //현재 노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 HidatoGrid.Node prevNode = history.GetPrevNode(current); current.WorkSapce = 0; current.EmptyMarker(); if (current.Input == 0) { EmptyNodeCount++; } current = prevNode; //HidatoCount변수를 바꾼 현재 노드의 데이터로 설정한 후 hidatoCount = current.Data; //NextNode를 업데이트 함 NextNode = FindNextNode(current); #region 모니터링 하기 위해 업데이트 하는 부분 if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } #endregion return(false); } } #endregion for (int i = 0; i < 8; i++) { bool InsertSuccess = false; for (int j = 0; j < 8; j++) { if (current.marker.SurchMarker[insertNow.Current] == true) { hidatoCount = current.Data; //이미 탐색한 자리임으로 false마킹 history.AddNode(current); #region 이미 탐색한 자리는 false로 마킹 if (insertNow.Current == (int)Side.N) { current.marker.SurchMarker[(int)Side.N] = false; } else if (insertNow.Current == (int)Side.NE) { current.marker.SurchMarker[(int)Side.NE] = false; } else if (insertNow.Current == (int)Side.E) { current.marker.SurchMarker[(int)Side.E] = false; } else if (insertNow.Current == (int)Side.SE) { current.marker.SurchMarker[(int)Side.SE] = false; } else if (insertNow.Current == (int)Side.S) { current.marker.SurchMarker[(int)Side.S] = false; } else if (insertNow.Current == (int)Side.SW) { current.marker.SurchMarker[(int)Side.SW] = false; } else if (insertNow.Current == (int)Side.W) { current.marker.SurchMarker[(int)Side.W] = false; } else if (insertNow.Current == (int)Side.NW) { current.marker.SurchMarker[(int)Side.NW] = false; } #endregion #region current참조를 알맞은 위치로 옮김 if (insertNow.Current == (int)Side.N) { current = current.N; } else if (insertNow.Current == (int)Side.NE) { current = current.NE; } else if (insertNow.Current == (int)Side.E) { current = current.E; } else if (insertNow.Current == (int)Side.SE) { current = current.SE; } else if (insertNow.Current == (int)Side.S) { current = current.S; } else if (insertNow.Current == (int)Side.SW) { current = current.SW; } else if (insertNow.Current == (int)Side.W) { current = current.W; } else if (insertNow.Current == (int)Side.NW) { current = current.NW; } #endregion NodeOfHidatoGridList.Add(current); hidatoCount++; current.WorkSapce = hidatoCount; //비어있는 칸이 1칸 줄어들기 때문에 1을 줄여야 합니다. EmptyNodeCount--; #region 모니터링 하기 위해 업데이트 하는 부분 if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } #endregion InsertSuccess = true; break; } insertNow.Increase(); } if (!InsertSuccess) { if (current.Data != 1) { //아니면, 현재 노드의 데이터를 0으로 설정하고,(비워놓음) 바로 이전 노드로 되돌림 HidatoGrid.Node prevNode = history.GetPrevNode(current); current.WorkSapce = 0; current.EmptyMarker(); if (current.Input == 0) { EmptyNodeCount++; } current = prevNode; //HidatoCount변수를 바꾼 현재 노드의 데이터로 설정한 후 hidatoCount = current.Data; NextNode = FindNextNode(current); #region 모니터링하기 위해 업데이트 하는 부분 if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } #endregion return(false); } else { continue; } } if (ShowAllProcess == true) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); Thread.Sleep(ProcessWaitTime); } else if (DateTime.Now > DTNextUpdate) { RefBoard.UpdateTextBoxes(); DTNextUpdate = DateTime.Now.AddSeconds(NextUpdateSoconds); } if (Solve() == true) { return(true); } } return(false); }