Example #1
0
        /// <summary>
        /// Генерирует карту с указанным новым значением свойства <see cref="Processor.Tag"/>.
        /// В случае, если новое и старое значения свойства <see cref="Processor.Tag"/> совпадают (с учётом регистра), то возвращается та же карта, которая была подана на вход.
        /// </summary>
        /// <param name="processor">Карта, значение свойства <see cref="Processor.Tag"/> которой требуется изменить.</param>
        /// <param name="newTag">Новое значение свойства <see cref="Processor.Tag"/>. Не может быть пустым.</param>
        /// <returns>Карта с новым значением свойства <see cref="Processor.Tag"/>.</returns>
        public static Processor ChangeProcessorTag(Processor processor, string newTag)
        {
            if (processor == null)
            {
                throw new ArgumentNullException(nameof(processor), $@"{nameof(ChangeProcessorTag)}: карта равна null.");
            }
            if (processor.Tag == newTag)
            {
                return(processor);
            }
            if (string.IsNullOrWhiteSpace(newTag))
            {
                throw new ArgumentException($"{nameof(ChangeProcessorTag)}: \"{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));
        }
Example #2
0
 /// <summary>
 ///     Получает хеш заданной карты.
 ///     Карта не может быть равна <see langword="null" />.
 /// </summary>
 /// <param name="p">Карта, для которой необходимо вычислить значение хеша.</param>
 /// <returns>Возвращает хеш заданной карты.</returns>
 internal static int GetHash(Processor p)
 {
     if (p is null)
     {
         throw new ArgumentNullException(nameof(p), $@"Функция {nameof(GetHash)}.");
     }
     return(GetHash(GetInts(p)));
 }
Example #3
0
 /// <summary>
 ///     Получает значения элементов карты построчно.
 /// </summary>
 /// <param name="p">Карта, с которой необходимо получить значения элементов.</param>
 /// <returns>Возвращает значения элементов карты построчно.</returns>
 static IEnumerable <int> GetInts(Processor p)
 {
     if (p is null)
     {
         throw new ArgumentNullException(nameof(p), $@"Функция {nameof(GetInts)}.");
     }
     for (int j = 0; j < p.Height; j++)
     {
         for (int i = 0; i < p.Width; i++)
         {
             yield return(p[i, j].Value);
         }
     }
 }
Example #4
0
        /// <summary>
        /// Проверяет пригодность карты вхождения в текущую коллекцию. В том числе, карта не должна быть <see langword="null" />, иначе выдаётся исключение <see cref="ArgumentNullException"/>.
        /// В случае, если размер карты не совпадёт с размерами уже добавленных карт, выдаётся исключение <see cref="ArgumentException"/>.
        /// В случае, если коллекция пуста, проверка проходит с любым размером проверяемой карты.
        /// </summary>
        /// <param name="p">Проверяемая карта.</param>
        void CheckProcessorSizes(Processor p)
        {
            if (p == null)
            {
                throw new ArgumentNullException(nameof(p), @"Добавляемая карта не может быть равна null.");
            }
            Processor t = _processors.FirstOrDefault();

            if (t == null)
            {
                return;
            }
            if (t.Size != p.Size)
            {
                throw new ArgumentException($"Добавляемая карта отличается по размерам от первой карты, добавленной в коллекцию. Требуется: {t.Width}, {t.Height}. Фактически: {p.Width}, {p.Height}.");
            }
        }
Example #5
0
 /// <summary>
 /// Сравнивает указанные карты.
 /// Сравнение производится как по содержимому, так и по первым буквам значения свойста <see cref="Processor.Tag"/>, без учёта регистра.
 /// Если карты различаются только по первой букве значения свойства <see cref="Processor.Tag"/>, они считаются разными.
 /// </summary>
 /// <param name="p1">Первая карта.</param>
 /// <param name="p2">Вторая карта.</param>
 /// <returns>
 /// В случае равенства карт по всем признакам, возвращается значение <see langword="true" />, в противном случае - <see langword="false" />.
 /// </returns>
 static bool ProcessorCompare(Processor p1, Processor p2)
 {
     if (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);
 }
Example #6
0
        /// <summary>
        /// В случае, если карта с таким же <see cref="Processor.Tag"/> уже существует в коллекции, генерирует новую карту с таким же значением поля <see cref="Processor.Tag"/>, к которому добавлен символ '0'.
        /// В противном случае, возвращается та же карта, которая была подана на вход. Регистр символов сохраняется.
        /// Проверка ведётся без учёта регистра.
        /// </summary>
        /// <param name="p">Проверяемая карта.</param>
        /// <returns>
        /// В случае отсутствия карты с таким же значением свойства <see cref="Processor.Tag"/>, возвращает ту же карту, которая была подана на вход.
        /// В противном случае, генерирует новую карту с таким же значением поля <see cref="Processor.Tag"/>, к которому добавлен символ '0'.
        /// </returns>
        Processor GetProcessorWithUniqueTag(Processor p)
        {
            string tTag = p.Tag.ToUpper();

            if (_hashProcs.Add(tTag))
            {
                return(p);
            }

            StringBuilder sb = new StringBuilder(p.Tag, 1024);

            do
            {
                tTag += '0';
                sb.Append('0');
            } while (!_hashProcs.Add(tTag));

            return(ChangeProcessorTag(p, sb.ToString()));
        }
Example #7
0
        /// <summary>
        /// Добавляет карту в коллекцию, проверяя её на соответствие по размерам, содержимому и свойству <see cref="Processor.Tag"/>.
        /// Если карта с таким же содержимым и первой буквой (без учёта регистра) в свойстве <see cref="Processor.Tag"/>, уже присутствует в коллекции, вызов будет игнорирован.
        /// </summary>
        /// <param name="p">Добавляемая карта.</param>
        public void Add(Processor p)
        {
            CheckProcessorSizes(p);

            int hash = HashCreator.GetHash(p);

            if (_dicProcsWithTag.TryGetValue(hash, out List <Processor> prcs))
            {
                if (prcs.Any(prc => ProcessorCompare(prc, p)))
                {
                    return;
                }
                Processor up = GetProcessorWithUniqueTag(p);
                prcs.Add(up);
                _processors.Add(up);
                return;
            }
            Processor np = GetProcessorWithUniqueTag(p);

            _dicProcsWithTag.Add(hash, new List <Processor> {
                np
            });
            _processors.Add(np);
        }