예제 #1
0
        public void Add(Processor p)
        {
            CheckProcessorSizes(p);

            void SetProps()
            {
                _procNames.Add(char.ToUpper(p.Tag[0]));
                Count++;
                IsEmpty = false;
            }

            int hash = HashCreator.GetHash(p);

            if (_dicProcsWithTag.TryGetValue(hash, out List <Processor> prcs))
            {
                if (prcs.Any(prc => ProcessorCompare(prc, p, true)))
                {
                    return;
                }
                prcs.Add(GetUniqueProcessor(p));
                SetProps();
                return;
            }
            _dicProcsWithTag.Add(hash, new List <Processor> {
                GetUniqueProcessor(p)
            });
            SetProps();
        }
예제 #2
0
        public static Processor RenameProcessor(Processor processor, string newTag)
        {
            if (processor == null)
            {
                throw new ArgumentNullException(nameof(processor));
            }
            if (processor.Tag == newTag)
            {
                return(processor);
            }
            if (string.IsNullOrWhiteSpace(newTag))
            {
                throw new ArgumentException($"\"{nameof(newTag)}\" не может быть пустым или содержать только пробел.", nameof(newTag));
            }

            SignValue[,] sv = new SignValue[processor.Width, processor.Height];
            for (int i = 0; i < processor.Width; i++)
            {
                for (int j = 0; j < processor.Height; j++)
                {
                    sv[i, j] = processor[i, j];
                }
            }
            return(new Processor(sv, newTag));
        }
예제 #3
0
 static bool ProcessorCompare(Processor p1, Processor p2)
 {
     if (p1 == null)
     {
         throw new ArgumentNullException();
     }
     if (p2 == null)
     {
         throw new ArgumentNullException();
     }
     if (p1.Height != p2.Height)
     {
         throw new ArgumentException();
     }
     if (p1.Width != p2.Width)
     {
         throw new ArgumentException();
     }
     for (int i = 0; i < p1.Width; ++i)
     {
         for (int j = 0; j < p1.Height; ++j)
         {
             if (p1[i, j] != p2[i, j])
             {
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #4
0
 static bool ProcessorCompare(Processor p1, Processor p2, bool includeTag)
 {
     if (p1 == null)
     {
         throw new ArgumentNullException();
     }
     if (p2 == null)
     {
         throw new ArgumentNullException();
     }
     if (includeTag && char.ToUpper(p1.Tag[0]) != char.ToUpper(p2.Tag[0]))
     {
         return(false);
     }
     for (int i = 0; i < p1.Width; i++)
     {
         for (int j = 0; j < p1.Height; j++)
         {
             if (p1[i, j] != p2[i, j])
             {
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #5
0
 public Processor this[int index]
 {
     get
     {
         Processor p = _processorContainer[index];
         return(ProcessorHandler.RenameProcessor(p, _stringQuery[p.Tag[0]].ToString()));
     }
 }
예제 #6
0
        /// <summary>
        ///     Распознаёт указанную карту в соответствии с указанным шаблоном.
        ///     В случае нахождения результатов, возвращает карту, составленную из тех карт, названия которых были указаны в
        ///     параметре matrix, в противном случае возвращает значение <see langword="null" />.
        /// </summary>
        /// <param name="proc">
        ///     Карта, которую требуется распознать. Её размеры должны соответствовать значению свойств
        ///     <see cref="ProcessorWidth" /> и <see cref="ProcessorHeight" />.
        /// </param>
        /// <param name="matrix">
        ///     Шаблон распознавания. Его размеры (по ширине и высоте) равны размерам изначального массива
        ///     <see cref="ProcessorContainer" />, подаваемого на вход конструктора.
        ///     Эти размеры вычисляются как <see cref="ProcessorWidth" /> <see langword="/" /> <see cref="MapWidth" /> и
        ///     <see cref="ProcessorHeight" /> <see langword="/" /> <see cref="MapHeight" />.
        /// </param>
        /// <returns>
        ///     В случае нахождения результатов возвращает карту, составленную из тех карт, названия которых были указаны в
        ///     параметре matrix, в противном случае возвращает значение <see langword="null" />.
        /// </returns>
        public virtual Processor Push(Processor proc, char[,] matrix)
        {
            if (proc == null)
            {
                throw new ArgumentNullException(nameof(proc), $"{nameof(Push)}: Распознаваемая карта равна null.");
            }
            if (proc.Width != ProcessorWidth)
            {
                throw new ArgumentException(
                          $"{nameof(Push)}: Распознаваемая карта не соответствует по ширине: ({proc.Width}) против ({ProcessorWidth}).",
                          nameof(proc));
            }
            if (proc.Height != ProcessorHeight)
            {
                throw new ArgumentException(
                          $"{nameof(Push)}: Распознаваемая карта не соответствует по высоте: ({proc.Height}) против ({ProcessorHeight}).",
                          nameof(proc));
            }
            if (matrix == null)
            {
                throw new ArgumentNullException(nameof(matrix),
                                                $"{nameof(Push)}: Шаблон распознавания отсутствует (null).");
            }
            if (matrix.GetLength(0) * MapWidth != proc.Width)
            {
                throw new ArgumentException(
                          $"{nameof(Push)}: Шаблон распознавания не соответствует входной карте по ширине: ({matrix.GetLength(0) * MapWidth}) против ({proc.Width}).",
                          nameof(matrix));
            }
            if (matrix.GetLength(1) * MapHeight != proc.Height)
            {
                throw new ArgumentException(
                          $"{nameof(Push)}: Шаблон распознавания не соответствует входной карте по высоте: ({matrix.GetLength(1) * MapHeight}) против ({proc.Height}).",
                          nameof(matrix));
            }
            if (IsNull(matrix))
            {
                throw new ArgumentException(
                          $"{nameof(Push)}: Какой-либо элемент шаблона распознавания равен пробелу и ему подобному.",
                          nameof(matrix));
            }
            if (!ResearchByPieces(proc, matrix))
            {
                return(null);
            }
            int mx = _processorContainers.GetLength(0);
            int my = _processorContainers.GetLength(1);

            Processor[,] processors = new Processor[mx, my];
            for (int y = 0; y < my; y++)
            {
                for (int x = 0; x < mx; x++)
                {
                    processors[x, y] = GetMapByName(matrix[x, y]);
                }
            }
            return(new Processor(MapCreator(processors), proc.Tag));
        }
예제 #7
0
 /// <summary>
 ///     Получает заданную часть указанной карты.
 ///     Часть эта по размерам соответствует полям <see cref="MapWidth" /> и <see cref="MapHeight" />.
 /// </summary>
 /// <param name="processor">Карта, часть которой необходимо получить.</param>
 /// <param name="x">Координата X необходимой части карты.</param>
 /// <param name="y">Координата Y необходимой части карты.</param>
 /// <returns>Возвращает указанную часть карты в виде массива <see cref="SignValue" />.</returns>
 protected SignValue[,] GetMapPiece(Processor processor, int x, int y)
 {
     SignValue[,] sv = new SignValue[MapWidth, MapHeight];
     for (int cy = y, y1 = 0, my = y + MapHeight; cy < my; cy++, y1++)
     {
         for (int cx = x, x1 = 0, mx = x + MapWidth; cx < mx; cx++, x1++)
         {
             sv[x1, y1] = processor[cx, cy];
         }
     }
     return(sv);
 }
예제 #8
0
        /// <summary>
        ///     Определяет, содержит ли текущий экземпляр <see cref="DynamicReflex" /> карту с подобным содержимым или нет.
        ///     В случае нахождения карты с совпадающим содержимым, метод возвращает значение <see langword="null" />, в противном
        ///     случае -
        ///     массив данных, сведения о котором указаны в параметре <see cref="Registered" />.
        /// </summary>
        /// <param name="processor">Карта, из которой необходимо получить целевую карту.</param>
        /// <param name="registered">Сведения о получаемой карте.</param>
        /// <returns>
        ///     В случае нахождения карты с совпадающим содержимым, метод возвращает значение <see langword="null" />, в противном
        ///     случае -
        ///     массив данных, сведения о котором указаны в параметре <see cref="Registered" />.
        /// </returns>
        static Processor GetProcessorFromField(Processor processor, Registered registered)
        {
            SignValue[,] values = new SignValue[registered.Region.Width, registered.Region.Height];
            for (int y = registered.Y, y1 = 0; y < registered.Bottom; y++, y1++)
            {
                for (int x = registered.X, x1 = 0; x < registered.Right; x++, x1++)
                {
                    values[x1, y1] = processor[x, y];
                }
            }

            return(new Processor(values, registered.Register.SelectedProcessor.Tag));
        }
예제 #9
0
        Processor GetUniqueProcessor(Processor p)
        {
            if (!_hashProcs.Contains(p.Tag))
            {
                return(p);
            }
            string tTag = p.Tag;

            do
            {
                tTag += '0';
            } while (_hashProcs.Contains(tTag));
            _hashProcs.Add(tTag);
            return(RenameProcessor(p, tTag));
        }
예제 #10
0
 IEnumerable <Processor> GetNewProcessors(Reflex start, Reflex finish)
 {
     if (start == null)
     {
         throw new ArgumentNullException();
     }
     if (finish == null)
     {
         throw new ArgumentNullException();
     }
     for (int k = start.Count; k < finish.Count; ++k)
     {
         Processor p = finish[k];
         yield return(ProcessorHandler.RenameProcessor(p, _stringQuery[p.Tag[0]].ToString()));
     }
 }
예제 #11
0
        void CheckProcessorSizes(Processor p)
        {
            if (p == null)
            {
                throw new ArgumentNullException();
            }
            Processor t = FirstProcessor;

            if (t == null)
            {
                return;
            }
            if (t.Size != p.Size)
            {
                throw new ArgumentException();
            }
        }
예제 #12
0
        /// <summary>
        ///     Инициализирует текущий экземпляр <see cref="DynamicReflex" /> картами из указанного экземпляра
        ///     <see cref="ProcessorContainer" />.
        ///     Карты предназначены для вызова <see cref="DynamicParser.Processor.GetEqual(ProcessorContainer)" />.
        ///     Этот список невозможно изменить вручную, в процессе работы с классом.
        /// </summary>
        /// <param name="processors">
        ///     Карты, которые необходимо добавить в текущий экземпляр <see cref="DynamicReflex" />.
        ///     С помощью них будет проводиться поиск запрашиваемых данных.
        /// </param>
        public DynamicReflex(ProcessorContainer processors)
        {
            if (processors == null)
            {
                throw new ArgumentNullException(nameof(processors), $"{nameof(DynamicReflex)}: Карты должны быть добавлены в контекст (null).");
            }

            Processor[] procs = new Processor[processors.Count];

            for (int k = 0; k < procs.Length; k++)
            {
                Processor p = processors[k];
                _setChars.Add(char.ToUpper(p.Tag[0]));
                procs[k] = p;
            }

            _seaProcessors = new ProcessorContainer(procs);
        }
예제 #13
0
        bool ResearchByPieces(Processor proc, char[,] matrix)
        {
            string             lastErrorText = null;
            ParallelLoopResult result        = Parallel.For(0, _processorContainers.Length, (k, state) =>
            {
                try
                {
                    int mx = _processorContainers.GetLength(0);
                    int x  = k % mx, y = k / mx;
                    SignValue[,] mapPiece = GetMapPiece(proc, x * MapWidth, y * MapHeight);
                    if (state.IsStopped)
                    {
                        return;
                    }
                    Processor processor = new Processor(mapPiece, proc.Tag);
                    if (state.IsStopped)
                    {
                        return;
                    }
                    SearchResults searchResults = processor.GetEqual(_processorContainers[x, y]);
                    if (state.IsStopped)
                    {
                        return;
                    }
                    if (!searchResults.FindRelation(matrix[x, y].ToString()))
                    {
                        state.Stop();
                    }
                }
                catch (Exception ex)
                {
                    state.Stop();
                    lastErrorText = ex.Message;
                }
            });

            if (lastErrorText != null)
            {
                throw new Exception(lastErrorText);
            }

            return(result.IsCompleted);
        }
예제 #14
0
 /// <summary>
 ///     Добавляет карты в коллекцию, проверяя их на предмет совпадающих значений свойств <see cref="Processor.Tag" />.
 ///     Добавление производится в общую коллекцию для ускорения поиска.
 /// </summary>
 /// <param name="pc">Коллекция добавляемых карт.</param>
 protected void CopyProcessorContainer(ProcessorContainer pc)
 {
     if (pc == null)
     {
         throw new ArgumentNullException(nameof(pc),
                                         $"{nameof(CopyProcessorContainer)}: Коллекция добавляемых карт отсутствует (null).");
     }
     for (int k = 0; k < pc.Count; k++)
     {
         Processor p   = pc[k];
         char      tag = char.ToUpper(p.Tag[0]);
         if (_processors.ContainsKey(tag))
         {
             throw new ArgumentException(
                       $"{nameof(CopyProcessorContainer)}: Обнаружены повторяющиеся карты: карта с таким названием ({tag}) уже была добавлена.",
                       nameof(pc));
         }
         _processors[tag] = p;
     }
 }
예제 #15
0
        /// <summary>
        ///     Объединяет указанные карты в единую карту в соответствии с расположением карт в указанном массиве.
        ///     При этом важно, чтобы все указанные карты были одного размера.
        ///     Карты со значением <see langword="null" /> должны отсутствовать.
        /// </summary>
        /// <param name="processors">Карты, которые необходимо объединить.</param>
        /// <returns>Возвращает итоговую карту в виде массива <see cref="SignValue" />.</returns>
        protected SignValue[,] MapCreator(Processor[,] processors)
        {
            int mx = ProcessorWidth, my = ProcessorHeight;

            SignValue[,] sv = new SignValue[mx, my];
            for (int y = 0, pry = 0; y < my; y += MapHeight, pry++)
            {
                for (int x = 0, prx = 0; x < mx; x += MapWidth, prx++)
                {
                    Processor p = processors[prx, pry];
                    for (int cy = y, pryy = 0, py = y + MapHeight; cy < py; cy++, pryy++)
                    {
                        for (int cx = x, prxx = 0, px = x + MapWidth; cx < px; cx++, prxx++)
                        {
                            sv[cx, cy] = p[prxx, pryy];
                        }
                    }
                }
            }
            return(sv);
        }
예제 #16
0
        public bool Add(Processor p)
        {
            int hash = CRCIntCalc.GetHash(p);

            if (_dicProcsWithTag.TryGetValue(hash, out List <Processor> prcs))
            {
                if (prcs.Any(prc => ProcessorCompare(prc, p)))
                {
                    return(false);
                }
                prcs.Add(GetUniqueProcessor(p));
                AddProcessorName(p.Tag[0]);
                ++Count;
                IsEmpty = false;
                return(true);
            }
            _dicProcsWithTag.Add(hash, new List <Processor> {
                GetUniqueProcessor(p)
            });
            AddProcessorName(p.Tag[0]);
            ++Count;
            IsEmpty = false;
            return(true);
        }
        public void PHTest()
        {
            ProcessorHandler ph = new ProcessorHandler();

            Assert.AreEqual(string.Empty, ph.ToString());
            Assert.AreEqual(0, ph.Processors.ToArray().Length);

            ph.Add(new Processor(new[] { new SignValue(2) }, "A"));

            List <Processor> procs = CheckProcessorHandler1(ph);

            procs.Add(new Processor(new[] { new SignValue(2000) }, "w"));
            CheckProcessorHandler1(ph);

            ph.Add(new Processor(new[] { new SignValue(3) }, "b"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(2, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual("AB", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(4) }, "C"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(2) }, "A"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(3) }, "b"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(4) }, "C"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(2) }, "A1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(3) }, "b1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(4) }, "C1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(2) }, "a1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(3) }, "B1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(4) }, "c1"));

            CheckProcessorHandler2(ph);

            ph.Add(new Processor(new[] { new SignValue(13) }, "b1"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(4, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual("ABCB", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(14) }, "B1"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(5, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual("ABCBB", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(15) }, "B"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(6, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual("ABCBBB", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(16) }, "b"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(7, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual(new SignValue(16), procs[6][0, 0]);
            Assert.AreEqual("b00", procs[6].Tag);
            Assert.AreEqual("ABCBBBB", ph.ToString());

            bool bex = false;

            try
            {
                SignValue[,] prc = new SignValue[2, 1];
                prc[0, 0]        = new SignValue(16);
                prc[1, 0]        = new SignValue(100);
                ph.Add(new Processor(prc, "b"));
            }
            catch (Exception ex)
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.AreEqual("Добавляемая карта отличается по размерам от первой карты, добавленной в коллекцию. Требуется: 1, 1. Фактически: 2, 1.", ex.Message);
                bex = true;
            }

            Assert.AreEqual(true, bex);

            bex = false;
            try
            {
                SignValue[,] prc = new SignValue[1, 2];
                prc[0, 0]        = new SignValue(16);
                prc[0, 1]        = new SignValue(100);
                ph.Add(new Processor(prc, "b"));
            }
            catch (Exception ex)
            {
                Assert.AreEqual(typeof(ArgumentException), ex.GetType());
                Assert.AreEqual("Добавляемая карта отличается по размерам от первой карты, добавленной в коллекцию. Требуется: 1, 1. Фактически: 1, 2.", ex.Message);
                bex = true;
            }

            Assert.AreEqual(true, bex);

            ph.Add(new Processor(new[] { new SignValue(3) }, "r"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(8, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual(new SignValue(16), procs[6][0, 0]);
            Assert.AreEqual("b00", procs[6].Tag);
            Assert.AreEqual(new SignValue(3), procs[7][0, 0]);
            Assert.AreEqual("r", procs[7].Tag);
            Assert.AreEqual("ABCBBBBR", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(2) }, "v1"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(9, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual(new SignValue(16), procs[6][0, 0]);
            Assert.AreEqual("b00", procs[6].Tag);
            Assert.AreEqual(new SignValue(3), procs[7][0, 0]);
            Assert.AreEqual("r", procs[7].Tag);
            Assert.AreEqual(new SignValue(2), procs[8][0, 0]);
            Assert.AreEqual("v1", procs[8].Tag);
            Assert.AreEqual("ABCBBBBRV", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(8418982) }, "q"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(10, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual(new SignValue(16), procs[6][0, 0]);
            Assert.AreEqual("b00", procs[6].Tag);
            Assert.AreEqual(new SignValue(3), procs[7][0, 0]);
            Assert.AreEqual("r", procs[7].Tag);
            Assert.AreEqual(new SignValue(2), procs[8][0, 0]);
            Assert.AreEqual("v1", procs[8].Tag);
            Assert.AreEqual(new SignValue(8418982), procs[9][0, 0]);
            Assert.AreEqual("q", procs[9].Tag);
            Assert.AreEqual("ABCBBBBRVQ", ph.ToString());

            ph.Add(new Processor(new[] { new SignValue(12451893) }, "q"));

            procs = ph.Processors.ToList();
            Assert.AreNotEqual(null, procs);
            CheckSize(procs);
            Assert.AreEqual(11, procs.Count);
            Assert.AreEqual(new SignValue(2), procs[0][0, 0]);
            Assert.AreEqual("A", procs[0].Tag);
            Assert.AreEqual(new SignValue(3), procs[1][0, 0]);
            Assert.AreEqual("b", procs[1].Tag);
            Assert.AreEqual(new SignValue(4), procs[2][0, 0]);
            Assert.AreEqual("C", procs[2].Tag);
            Assert.AreEqual(new SignValue(13), procs[3][0, 0]);
            Assert.AreEqual("b1", procs[3].Tag);
            Assert.AreEqual(new SignValue(14), procs[4][0, 0]);
            Assert.AreEqual("B10", procs[4].Tag);
            Assert.AreEqual(new SignValue(15), procs[5][0, 0]);
            Assert.AreEqual("B0", procs[5].Tag);
            Assert.AreEqual(new SignValue(16), procs[6][0, 0]);
            Assert.AreEqual("b00", procs[6].Tag);
            Assert.AreEqual(new SignValue(3), procs[7][0, 0]);
            Assert.AreEqual("r", procs[7].Tag);
            Assert.AreEqual(new SignValue(2), procs[8][0, 0]);
            Assert.AreEqual("v1", procs[8].Tag);
            Assert.AreEqual(new SignValue(8418982), procs[9][0, 0]);
            Assert.AreEqual("q", procs[9].Tag);
            Assert.AreEqual(new SignValue(12451893), procs[10][0, 0]);
            Assert.AreEqual("q0", procs[10].Tag);
            Assert.AreEqual("ABCBBBBRVQQ", ph.ToString());

            Processor renameProcessor2 = ProcessorHandler.ChangeProcessorTag(new Processor(new[] { SignValue.MaxValue }, "mmM"), "zZz");

            Assert.AreNotEqual(null, renameProcessor2);
            Assert.AreEqual("zZz", renameProcessor2.Tag);
            Assert.AreEqual(SignValue.MaxValue, renameProcessor2[0, 0]);
            Assert.AreEqual(1, renameProcessor2.Width);
            Assert.AreEqual(1, renameProcessor2.Height);

            Processor renameProcessor3 = ProcessorHandler.ChangeProcessorTag(new Processor(new[] { SignValue.MaxValue }, "mmM"), "mmM");

            Assert.AreNotEqual(null, renameProcessor3);
            Assert.AreEqual("mmM", renameProcessor3.Tag);
            Assert.AreEqual(SignValue.MaxValue, renameProcessor3[0, 0]);
            Assert.AreEqual(1, renameProcessor3.Width);
            Assert.AreEqual(1, renameProcessor3.Height);
        }