Skip to main content
Post Undeleted by BanMe
Post Deleted by BanMe
Condensed answer
Source Link
BanMe
  • 75
  • 1
  • 12

Linq version, reduces Search Area, by directly checking Target sequence in Search Area Instead of using SubListIndex.

        var m = SearchImage.Length - 1;
        return (from line in Enumerable.Range(0, SourceArea.GetUpperBound(0))
                                        let Index = SubListIndex(SourceArea[line].AsEnumerable(), 0, TargetArea[m])
                                        where Index != -1
                                        let Test = SourceArea[line - m].AsEnumerable().Skip(Index).SequenceEqual(TargetArea[0])
                                        let Test2 = SourceArea[line - (m / 2)].AsEnumerable().Skip(Index).SequenceEqual(TargetArea[m / 2])
                                        where Test && Test2
                                        select new Point(Index + (TargetArea[0].Length / 2), line + (TargetArea.Length / 2))).FirstOrDefault();

Linq version, reduces Search Area, by directly checking Target sequence in Search Area Instead of using SubListIndex.

        var m = SearchImage.Length - 1;
        return (from line in Enumerable.Range(0, SourceArea.GetUpperBound(0))
                                        let Index = SubListIndex(SourceArea[line].AsEnumerable(), 0, TargetArea[m])
                                        where Index != -1
                                        let Test = SourceArea[line - m].AsEnumerable().Skip(Index).SequenceEqual(TargetArea[0])
                                        let Test2 = SourceArea[line - (m / 2)].AsEnumerable().Skip(Index).SequenceEqual(TargetArea[m / 2])
                                        where Test && Test2
                                        select new Point(Index + (TargetArea[0].Length / 2), line + (TargetArea.Length / 2))).FirstOrDefault();
Source Link
BanMe
  • 75
  • 1
  • 12

Ok so let's focus on this part the actual search routine.

        for (int i = ba2.GetUpperBound(0); i > 0; i--)
        {
            if (SubListIndex(ba2[i].AsEnumerable(), 0, Base.LastOrDefault()) != -1)
            {
                if (Base.Count() == 1)
                {
                    MoveTo(
                            SubListIndex(ba2[i].AsEnumerable(), 0, Base.LastOrDefault()) + (ba1[0].Length / 2),
                            i + (ba1.GetUpperBound(0) / 2));
                    return true;
                }
                else
                {
                    Base = Base.Take(Base.Count() - 1);
                }
            }
        }
        return false;

This routine resizes the search Image on each successful pass instead of iterating it

The amount of checking when finding a potential match can be reduced to 3 checks.

        var m = SearchImage.Length - 1;
        for (int i = SearchArea.GetUpperBound(0); i > 0; i--)
        {
            if (SubListIndex(SearchArea[i].AsEnumerable(), 0, SearchImage[m]) != -1)
            {
                int x;
                if (SubListIndex(SearchArea[i - m].AsEnumerable(), 0, SearchImage[0]) != -1)
                {
                    if (SubListIndex(SearchArea[i - (m / 2)].AsEnumerable(), 0, SearchImage[m / 2]) != -1)
                    {
                        x = SubListIndex(SearchArea[i - m].AsEnumerable(), 0, SearchImage[0]);
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    continue;
                }

                if (x != -1)
                {
                    return new Point(x + (SearchImage.Length / 2), (SearchImage.Length / 2) + i);
                }
            }
        }
        return default;