示例#1
0
        public static TariffMetroCommandCalculateInterval First(this TariffMetro tariff)
        {
            TariffMetroCommand cmd = tariff.Commands.FirstOrDefault();

            if (cmd == null)
            {
                return(null);
            }

            while (cmd.Type == TariffMetroCommandType.Goto)
            {
                cmd = tariff.Goto(cmd);
            }

            return((TariffMetroCommandCalculateInterval)cmd);
        }
        private DateTime GetNextEndTime(TariffMetro tariff, TariffMetroCommandCalculateInterval currentCommand, ref DateTime dtEstimatedDate)
        {
            //TimeSpan t1 = currentCommand.StartTime; //t1 = t_интN
            TariffMetroCommandCalculateInterval nextCommand = tariff.Next(currentCommand); //U_к = U_к + 1

            //TimeSpan t2 = nextCommand.StartTime; //t2 = t_интN+1
            var endTime = dtEstimatedDate.Add(nextCommand.StartTime); //t_интNкон = t_опл/дата + t_интN+1

            if (nextCommand.StartTime > currentCommand.StartTime)
            {
                return(endTime);
            }
            endTime         += TimeSpan.FromDays(1); //t_интNкон = t_интNкон + 24ч
            dtEstimatedDate += TimeSpan.FromDays(1); //t_опл/дата = t_опл/дата + 24ч

            return(endTime);
        }
 public TariffMetro(TariffMetro tariffMetro)
     : base(tariffMetro)
 {
     commands = new List <TariffMetroCommand>(tariffMetro.Commands);
 }
        /// <summary>
        /// Создаёт тариф метро из указанного файла
        /// </summary>
        public static Tariff LoadFromFile(string fileName)
        {
            //check file exists
            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException("Файл не найден", fileName);
            }

            //read valid entries
            IEnumerable <string> entries = File.ReadAllLines(fileName, Encoding.Default)
                                           .Where(s => ((s.Length > 3) && (s[0] == CommandStartSign)));

            //create commands and properties
            Dictionary <int, TariffMetroCommand> commands = new Dictionary <int, TariffMetroCommand>();
            Dictionary <char, int> properties             = PropertyNames.ToDictionary(p => p, p => (int)PropertyDefaultValue);

            //parse entries
            foreach (string e in entries)
            {
                //split entry
                string[] sa = SplitEntry(e);

                //get entry name
                char name = sa[0].ToUpper()[1];

                //entry is command?
                if (Char.IsDigit(name))
                {
                    var n = (int)Char.GetNumericValue(name);
                    TariffMetroCommand cmd = ParseCommand(sa);

                    //stop parsing at end command
                    if (cmd.Type == TariffMetroCommandType.End)
                    {
                        break;
                    }

                    cmd.ID = n;
                    commands.Add(n, cmd);
                    continue;
                }

                //entry is property?
                if (!properties.ContainsKey(name))
                {
                    continue;
                }
                properties[name] = ParseProperty(name, sa);
            }

            //check command sequence
            int[] ids = commands.Keys.OrderBy(k => k).ToArray();
            if (commands.Count > 1)
            {
                int firstId = ids[0];
                for (int i = 1; i < ids.Length; i++)
                {
                    if ((ids[i] - ids[i - 1]) > 1)
                    {
                        throw new InvalidDataException("Неверная последовательность команд");
                    }
                }
            }

            //check goto command destinations
            if (commands.Values
                .Where(c => c.Type == TariffMetroCommandType.Goto)
                .Cast <TariffMetroCommandGoto>()
                .Any(g => !ids.Contains(g.Destination)))
            {
                throw new InvalidDataException("Не найдено назначение команды перехода");
            }

            //check cyclic goto (1 level)
            if (commands.Values
                .Where(c => c.Type == TariffMetroCommandType.Goto)
                .Cast <TariffMetroCommandGoto>()
                .Any(g =>
            {
                TariffMetroCommand g2 = commands[g.Destination];
                if (g2.Type != TariffMetroCommandType.Goto)
                {
                    return(false);
                }

                return(((TariffMetroCommandGoto)g2).Destination == g.ID);
            }))
            {
                throw new InvalidDataException("Обнаружен циклический переход");
            }

            //check properties
            if (properties.Values.Any(v => v == PropertyDefaultValue))
            {
                throw new InvalidDataException("Не найдены все свойства");
            }

            //create tariff
            var tariff = new TariffMetro();
            int id     = properties['C'];

            id       += (properties['B'] << 8);
            id       += (properties['A'] << 16);
            tariff.ID = id;

            tariff.PaymentDiscrete      = ConvertMoney(properties['D']);
            tariff.FreeTimeAtStart      = TimeSpan.FromSeconds(properties['E']);
            tariff.FreeTimeAfterPayment = TimeSpan.FromSeconds(properties['F']);

            for (int i = 0; i < ids.Length; i++)
            {
                tariff.AddCommand(commands[i]);
            }

            return(tariff);
        }
示例#5
0
        private static TariffMetroCommand Goto(this TariffMetro tariff, TariffMetroCommand command)
        {
            var g = command as TariffMetroCommandGoto;

            return(g == null ? command : tariff.Commands.FirstOrDefault(c => c.ID == g.Destination));
        }