Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2016, 18:14   #11
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

да проще всего иметь что-то вроде TimedAction, которое отнимает тики от счетчика внутри себя.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.06.2016, 15:31   #12
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Пепел Феникса, так и попробовал сделать, но что-то пошло не так.
Попробовал создать класс колекции а-ля SortedList, но с учетом того, что ключ может быть одинаковым (правильнее наверное было построить на паре "ключ-значение"). Вот он:
Код:
public class SortedAction
    {
        private List<int> times;
        private List<Person> persons;
        public int Count { get { return times.Count; } }
        public bool IsEmpty { get { return (times.Count == 0 && persons.Count==0); } }
        public Tuple<int,Person> this[int i]
        {
            get
            {
                return new Tuple<int,Person>(times[i], persons[i]);
            }
        }

        public SortedAction()
        {
            times = new List<int>();
            persons = new List<Person>();

        }
        public void Add(int time, Person who)
        {
            if (times.Count == 0 || (times.Count > 0 ? time > times[times.Count - 1] : false))
            {
                times.Add(time);
                persons.Add(who);
            }
            else
            {
                if (persons.Contains(who)) Remove(who);
                for (int i = 0; i < times.Count; i++)
                {
                    if (time < times[i])
                    {
                        times.Insert(i, time);
                        persons.Insert(i, who);
                        break;
                    }
                    else if (time==times[i])
                    {
                        if (who is Player)
                        {
                            if (persons[i] is Mob)
                            {
                                times.Insert(i, time);
                                persons.Insert(i, who);
                                break;
                            }
                            continue;
                        }
                        if (i==times.Count-1)
                        {
                            times.Add(time);
                            persons.Add(who);
                            break;
                        }
                    }
                }
            }
        }
        public void Remove(int index)
        {
            times.RemoveAt(index);
            persons.RemoveAt(index);
        }
        public void Remove(Person who)
        {
            int i = persons.IndexOf(who);
            times.RemoveAt(i);
            persons.RemoveAt(i);
        }
        public void TimeMinus (int ms)
        {
            for (int i = 0; i < times.Count; i++)
                times[i] -= ms;
        }
    }
Класс локации. В нем реализовал таймер из System.Timers:
Код:
public class Location
    {
        bool Enabled;
        bool t1;
        int ticks;
        private SortedAction LocLife;
        List<Mob> mobList;
        Timer LocTime;
        public Location()
        {
            Enabled = true;
            ticks = 0;
            t1 = false;
            LocLife = new SortedAction();
            mobList = new List<Mob>();
            LocTime = new Timer();
            LocTime.Elapsed += Tick;
        }
        public void Start()
        {
            for (int i=0; i<5; i++)
            {
                mobList.Add(new Mob(i, Activity.Lox, this));
            }
            LocTime.AutoReset = true;
            LocTime.Interval = 1;
            LocTime.Enabled = true;
        }
        public void Life()
        {
            while (LocTime.Enabled)
            {
                foreach (Mob mob in mobList)
                {
                    mob.Thinking();
                }
            }
        }
        
        public void AddAction(int time, Mob who)
        {
            LocLife.Add(time, who);
        }

        private void Tick(object sender, ElapsedEventArgs e)
        {
            if (LocLife.IsEmpty) ticks = 0;
            else
            {
                ticks++;
                if (ticks >= LocLife[0].Item1)
                {
                    while (!LocLife.IsEmpty && ticks >= LocLife[0].Item1)
                    {
                        LocLife[0].Item2.Do();
                        LocLife.Remove(0);
                    }
                    LocLife.TimeMinus(ticks);
                    ticks = 0;
                }
            }
        }
    }
Ну и собственно моб. Основные действующие лица. На данный момент реализация проста. Существует чисто ради проверки.
Код:
public class Mob: Person
    {
        public int raz;
        Activity Poved;
        Location loc;
        bool act;
        public Mob(int id, Activity poved, Location loc)
        {
            Id = id;
            Poved = poved;
            type = Types.Mob;
            raz = 0;
            this.loc = loc;
            act = false;
        }
        public override void Thinking()
        {
            raz++;
            if (!act)
            {
                loc.AddAction(10, this);
                act = !act;
            }
                
        }
        public override void Do()
        {
            Console.WriteLine("{0} - {1}", Id,raz);
            raz = 0;
            act = !act;
        }
    }
В Main() создаю экземпляр локации, стартую ее и вызываю метод Life(). Но живет моя лока не долго. После первого цикла она крашуется в методе SortedAction.Remove(), поскольку пытается из пустой коллекции удалить какой-то элемент, хотя по идее, если коллеция пустая, он туда не должен заходить.
P.S. Если кому интересно, то приложил проект.
Вложения
Тип файла: rar Loca.rar (39.1 Кб, 11 просмотров)
max_prorok вне форума Ответить с цитированием
Старый 24.06.2016, 17:16   #13
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а зачем коллекция? моб может выполнять несколько действий одновременно?
или вам для последовательности?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.06.2016, 19:30   #14
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Для последовательности. Так сказать очередь.
Очередь сортируется по int-овой переменной, обозначающей задержку. Потом, когда таймер подсчитывает до нужного значения в этой int-овой переменной, то заставляет моба исполнить действие, удаляет его из очереди, и отнимает у оставшихся в очереди время, которое уже прошло.
Хотя в одном месте я махнулся...
Когда я добавляю событие, то надо к нему еще приплюсовывать текущее время задержки.

Может имеет смысл добавлять и удалять действия так же в таймере. Допустим, сначала сохранять время и моба в какой-нибудь List<Tuple<int, Mob>, а потом из него в таймера закидывать в очередь?

Последний раз редактировалось max_prorok; 24.06.2016 в 19:35.
max_prorok вне форума Ответить с цитированием
Старый 24.06.2016, 19:41   #15
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

у вас просто последовательность, какая сортировка то?
вы же не выполняете всегда самое короткое действие?
и да, Tuple вам не нужен.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 24.06.2016, 20:15   #16
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Почему? Я их сортирую на этапе добавления в коллекцию

Последний раз редактировалось max_prorok; 24.06.2016 в 22:31.
max_prorok вне форума Ответить с цитированием
Старый 25.06.2016, 05:35   #17
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

я и говорю, зачем сортировка?
у вас очередь действий или они все идут одновременно?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.06.2016, 09:55   #18
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Очередь действий.
Это просто у меня пример рассмотрен такой, когда в одно и тоже время допустим должно произойти несколько событий. Например, так получилось что в одно и тоже время, один моб переходит на соседнюю клетку, у другого закончился задержка после удара, а третий закончил каст спела.
max_prorok вне форума Ответить с цитированием
Старый 27.06.2016, 12:17   #19
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

так, вы очередь действий храните в мире выходит.
вам в любом случае очередь тут не сильно важна, просто список, что кончилось удаляете(или помечаете)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.06.2016, 12:26   #20
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Я просто думал, это делать именно в виде сортировке в самом начале, чтобы в обработчике таймера код занимал как можно меньше времени. А то пока он найдет в коллекции нужную строчку, то пройдет больше времени, чем выберет просто первую. Не исключаю, что вы правы. Попробую тогда написать попроще, через Dictionary<Mob,int>.
Или же все-таки использовать List<>, дабы время не тратить на перевод в хэш-код? Хотя на данном этапе пожалуй лучше об этом не думать. Оптимизацию оставить на потом
max_prorok вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Снова я и снова геморрой, только уже с многопоточностью FleXik Общие вопросы Delphi 26 07.07.2013 16:48
Неблокирующий сокет Си проблема с закрытием, проблема с закрытием сокетов в цикле mnx_vol C/C++ Сетевое программирование 0 06.11.2012 13:57
нужно разобраться с многопоточностью с ThRead Object Толян1 C++ Builder 1 16.07.2012 09:52
Проблема с многопоточностью Kapitan4ik Работа с сетью в Delphi 3 29.02.2012 21:46