private int Searching(List <PairWithIndex> cats,
                          List <PairWithIndex> mice,
                          List <Pair> cheeses,
                          out List <List <Pair> > catsPath,
                          out List <List <Pair> > micePath,
                          SearchRule rule)
    {
        // initialize
        int        count   = 0;
        int        height  = board.GetLength(0);
        int        width   = board.GetLength(1);
        BoardState current = new BoardState(null, new List <BoardState>(), cats, mice, cheeses);

        current.Gn = 0;
        current.Hn = 0;
        List <BoardState> searchList = new List <BoardState>();

        searchList.Add(current);
        BoardState checkBoard;

        micePath = new List <List <Pair> >();
        catsPath = new List <List <Pair> >();

        while (searchList.Count > 0)
        {
            count++;

            if (searchRule == SearchRule.AStar1 || searchRule == SearchRule.AStar2 || searchRule == SearchRule.AStar3)
            {
                searchList.Sort(new myComparer());
            }

            checkBoard = searchList[0];
            searchList.Remove(searchList[0]);

            // check cheeses
            List <Pair> currentCheeses;
            int         cheesesNum = CheckCheeses(checkBoard.mice, checkBoard.cheeses, out currentCheeses);
            if (cheesesNum == 0)
            {
                continue;
            }

            // check mice
            List <PairWithIndex> currentMice;
            int miceNum = CheckMice(checkBoard.mice, checkBoard.cats, checkBoard, out currentMice, micePath);
            if (miceNum == 0)
            {
                for (int i = 0; i < checkBoard.cats.Count; i++)
                {
                    List <Pair> catPath = new List <Pair>();
                    BoardState  temp    = checkBoard;
                    int         index   = checkBoard.cats[i].index;
                    while (temp.parent != null)
                    {
                        for (int k = 0; k < temp.cats.Count; k++)
                        {
                            if (temp.cats[k].index == index)
                            {
                                catPath.Insert(0, temp.cats[k].p);
                                break;
                            }
                        }
                        temp = temp.parent;
                    }
                    catsPath.Add(catPath);
                }
                break;
            }

            // mice move, only one possibility
            List <PairWithIndex> miceMove = new List <PairWithIndex>();
            for (int i = 0; i < currentMice.Count; i++)
            {
                // mice's next step
                Pair          p        = Mouse.NextStep(currentMice[i].p, currentCheeses, width, height);
                int           index    = currentMice[i].index;
                PairWithIndex nextStep = new PairWithIndex(p, index);
                miceMove.Add(nextStep);
            }

            // cats move, expand all possible states
            List <List <PairWithIndex> > catsCandidateSet = new List <List <PairWithIndex> >();
            for (int i = 0; i < checkBoard.cats.Count; i++)
            {
                List <PairWithIndex> oneCatMove = new List <PairWithIndex>();
                List <Pair>          candidates = Cat.FindCandidates(checkBoard.cats[i].p, board);
                for (int j = 0; j < candidates.Count; j++)
                {
                    Pair p     = candidates[j];
                    int  index = checkBoard.cats[i].index;
                    oneCatMove.Add(new PairWithIndex(p, index));
                }
                catsCandidateSet.Add(oneCatMove);
            }

            List <List <PairWithIndex> > catsMove = new List <List <PairWithIndex> >();
            Expand(catsMove, catsCandidateSet, new List <PairWithIndex>(), 0);

            switch (searchRule)
            {
            case SearchRule.DFS:
                DFS(searchList, checkBoard, catsMove, miceMove, currentCheeses);
                break;

            case SearchRule.BFS:
                BFS(searchList, checkBoard, catsMove, miceMove, currentCheeses);
                break;

            case SearchRule.AStar1:
                AStar1(searchList, checkBoard, catsMove, miceMove, currentCheeses);
                break;

            case SearchRule.AStar2:
                AStar2(searchList, checkBoard, catsMove, miceMove, currentCheeses);
                break;

            case SearchRule.AStar3:
                AStar3(searchList, checkBoard, catsMove, miceMove, currentCheeses);
                break;
            }
        }
        return(count);
    }
    private int DLS(BoardState current, List <Pair> cheeses, List <List <Pair> > catsPath, List <List <Pair> > micePath, int limit, out int maxDepth)
    {
        // initialize
        int count  = 0;
        int height = board.GetLength(0);
        int width  = board.GetLength(1);
        List <BoardState> searchList = new List <BoardState>();

        searchList.Add(current);
        BoardState checkBoard;

        maxDepth = -1;
        while (searchList.Count > 0)
        {
            count++;

            checkBoard = searchList[0];
            searchList.Remove(searchList[0]);

            // check cheeses
            List <Pair> currentCheeses;
            int         cheesesNum = CheckCheeses(checkBoard.mice, checkBoard.cheeses, out currentCheeses);
            if (cheesesNum == 0)
            {
                maxDepth = limit;
                continue;
            }


            // check mice
            List <PairWithIndex> currentMice;
            int miceNum = CheckMice(checkBoard.mice, checkBoard.cats, checkBoard, out currentMice, micePath);
            if (miceNum == 0)
            {
                for (int i = 0; i < checkBoard.cats.Count; i++)
                {
                    List <Pair> catPath = new List <Pair>();
                    BoardState  temp    = checkBoard;
                    int         index   = checkBoard.cats[i].index;
                    while (temp.parent != null)
                    {
                        for (int k = 0; k < temp.cats.Count; k++)
                        {
                            if (temp.cats[k].index == index)
                            {
                                catPath.Insert(0, temp.cats[k].p);
                                break;
                            }
                        }
                        temp = temp.parent;
                    }
                    catsPath.Add(catPath);
                }
                Debug.Log("Solution is found in depth of " + checkBoard.Gn);
                break;
            }

            // mice move, only one possibility
            List <PairWithIndex> miceMove = new List <PairWithIndex>();
            for (int i = 0; i < currentMice.Count; i++)
            {
                // mice's next step
                Pair          p        = Mouse.NextStep(currentMice[i].p, currentCheeses, width, height);
                int           index    = currentMice[i].index;
                PairWithIndex nextStep = new PairWithIndex(p, index);
                miceMove.Add(nextStep);
            }

            // cats move, expand all possible states
            List <List <PairWithIndex> > catsCandidateSet = new List <List <PairWithIndex> >();
            for (int i = 0; i < checkBoard.cats.Count; i++)
            {
                List <PairWithIndex> oneCatMove = new List <PairWithIndex>();
                List <Pair>          candidates = Cat.FindCandidates(checkBoard.cats[i].p, board);
                for (int j = 0; j < candidates.Count; j++)
                {
                    Pair p     = candidates[j];
                    int  index = checkBoard.cats[i].index;
                    oneCatMove.Add(new PairWithIndex(p, index));
                }
                catsCandidateSet.Add(oneCatMove);
            }

            List <List <PairWithIndex> > catsMove = new List <List <PairWithIndex> >();
            Expand(catsMove, catsCandidateSet, new List <PairWithIndex>(), 0);

            for (int i = 0; i < catsMove.Count; i++)
            {
                BoardState next = new BoardState(checkBoard, null, catsMove[i], miceMove, currentCheeses);
                next.Gn = checkBoard.Gn + 1;
                bool flag = false;
                for (int x = 0; x < searchList.Count; x++)
                {
                    if (searchList[x].Equals(next))
                    {
                        flag = true;
                        break;
                    }
                }

                if (!flag)
                {
                    searchList.Add(next);
                }
            }
        }
        return(count);
    }