示例#1
0
        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);
        }