示例#1
0
        private uint DoExtraSearch(SolverParam param)
        {
            uint   walk   = 0;
            Random rnd    = new Random();
            Stroke stroke = puzzleData;

            int         nbVerses  = stroke.Verses.Count;
            Stack <int> proposal  = new Stack <int>(),
                        candidate = new Stack <int>(Enumerable.Reverse(Enumerable.Range(0, nbVerses)));
            List <Verse> result   = new List <Verse>();

            List <int>[] visited = new List <int> [nbVerses];
            for (int vv = 0; vv < nbVerses; ++vv)
            {
                visited[vv] = new List <int>();
            }
            while (candidate.Count > 0)
            {
                int        curIdx      = candidate.Pop();
                List <int> curVisisted = visited[curIdx];
                // Existing verses construct the constraints.
                List <int[]> constraints    = stroke.Anchors;
                int          requiredLength = stroke.Verses[curIdx].Length;
                bool         foundOne       = true;
                // Look up in the data.
                int   s = 0;
                Verse v = new Verse();
                if (stroke.Verses[curIdx].Content[0] != 0xFF)
                {
                    // Fixed verse.
                    s = dictDataMatrices[requiredLength].FindIndex(
                        (x) =>
                    {
                        bool found = true;
                        for (int i = 0; i < requiredLength; ++i)
                        {
                            if (x[i] != stroke.Verses[curIdx].Content[i])
                            {
                                found = false;
                                break;
                            }
                        }
                        return(found);
                    });
                }
                else
                {
                    // Variant verse.
                    for (s = 0; s < dictDataMatrices[requiredLength].Count; ++s)
                    {
                        if (param.MaxStep > 0 && walk > param.MaxStep)
                        {
                            return(walk);
                        }
                        // Prevent replicate verses.
                        foundOne = true;
                        if (usedIndices[requiredLength].Contains(s) || curVisisted.Contains(s))
                        {
                            foundOne = false;
                            continue;
                        }
                        ++walk;
                        ushort[] content = dictDataMatrices[requiredLength][s];
                        foreach (int[] a in constraints)
                        {
                            if (a[4] == 0xFF)
                            {
                                // Variant anchor.
                                if (proposal.Contains(a[0]) && curIdx == a[2])
                                {
                                    ushort trait = content[a[3]],
                                       check     = result[a[0]].Content[a[1]];
                                    if (trait != check)
                                    {
                                        foundOne = false;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                // Fixed anchor.
                                if (a[0] == curIdx && content[a[1]] != a[4])
                                {
                                    foundOne = false;
                                    break;
                                }
                                if (a[2] == curIdx && content[a[3]] != a[4])
                                {
                                    foundOne = false;
                                    break;
                                }
                            }
                            // For each search, check the constraints.
                        }
                        if (foundOne)
                        {
                            break;
                        }
                    }
                }
                if (foundOne)
                {
                    // Next step.
                    curVisisted.Add(s);
                    v.Length  = requiredLength;
                    v.Content = dictDataMatrices[requiredLength][s];
                    result.Add(v);
                    proposal.Push(curIdx);
                }
                else
                {
                    // Trace back.
                    curVisisted.Clear();
                    result.RemoveAt(result.Count - 1);
                    int lastIdx = proposal.Pop();
                    candidate.Push(curIdx);
                    candidate.Push(lastIdx);
                }
            }
            // Get result.
            stroke.Verses = result;
            for (int i = 0; i < nbVerses; ++i)
            {
                int requiredLength = stroke.Verses[i].Length;
                int usedIdx        = visited[i][visited[i].Count - 1];
                if (!param.Reuse)
                {
                    usedIndices[requiredLength].Add(usedIdx);
                }
            }
            stroke.IsCompleted = true;
            return(walk);
        }
示例#2
0
 public void ClearPuzzleData()
 {
     puzzleData = null;
 }