Задачи для начинающих
тут чуть нагляднее и на клаву реагирует
в соответствии с диаграммой
машинам включится сразу желтый, если они уже ездили минимум 10 секунд.
иначе желтый включится когда они поездят хотя бы 10 сеунд (отсчет от включения зелёного).
еще когда машинам красный, кнопка игнорируется.
----
да еще на всяк случай: на диаграмме желтый горит 1 секунду, а в файле что у тебя что в прошлом посте послал - 2 секунды.
Хорошо что спросил, потому как у меня совсем другой.
"Кнопка работает, только когда красный машинам и просто уменьшает время его горения на какое-то время", но нет защиты от постоянных нажатий.
Потому как если нажал после красного, то смысла в этом нет - и так будет зеленый.
еще когда машинам красный, кнопка игнорируется.
вот это не доходит отчего
Но в принципе, у нас получается пока два кардинально разных подхода к решению: используя задержку после изменения состояния и измена состояния после отрезка времени.
У каждого есть свои достоинства и недостатки, особенно когда влезает еще и кнопочка. /Имея в виду исполнение программы под виндовс/
Под определенный алгоритм работы кнопки еще как то можно настроить систему, но вот интересно было бы сделать, что бы менять алгоритм работы кнопки достаточно просто не влезая в состояния.
тут я не понимаю чего там не доходит.еще когда машинам красный, кнопка игнорируется.вот это не доходит отчего
У меня логика такая: если машинам красный, то в это время людям зелёный. И людям следует дорогу переходить, а не на кнопку жать. Поэтому такие нажатия я считаю балавством и игнорирую.
Только если людям красный - только тогда кнопка воспринимается.
используя задержку после изменения состояниякак то неправильно звучит "задержка"...
У меня в алгоритме нет никаких задержек. Лучше сказать так: каждое состояние длится ограниченное время и они сменяют друг друга.
что бы менять алгоритм работы кнопки достаточно просто не влезая в состояния.скажи как кнопка должна работать и сделаем.
когда машинам красный, кнопка игнорируется.
А ты любишь выстрелить себе в колено :)
Можно ведь представить кнопку просто как триггер. Те если кнопка нажата, то через 10 секунд запускается смена состояний.
Предположим, что зелёный горит 10 секунд. На 8-й секунде к светофору подходит старушка и хочет сразу нажать кнопку. Зачем ей ждать 2 секунды пока не загорится красный?
Предположим, что зелёный горит 10 секунд. На 8-й секунде к светофору подходит старушка и хочет сразу нажать кнопку. Зачем ей ждать 2 секунды пока не загорится красный?если хочет пусть жмёт. Но какой смысл ей жать, если как раз сейчас ей горит зелёный. Ей идти надо.
Можно ведь представить кнопку просто как триггер. Те если кнопка нажата, то через 10 секунд запускается смена состояний.это плохо. например такая ситуация:
- загорелся зелёный для пешеходов
- подошел аболтус нажал на кнопку (запустил отсчет 10 сек) и перешел дорогу
- машинам уже зеленый, пешеходов нету, и тут прошли эти 10 сек.
нехорошо: никого из пешеходов нет, а машинам красный
Но какой смысл ей жать, если как раз сейчас ей горит зелёный. Ей идти надо.
Она вежливая бабушка и знает, что на переход дороги ей надо 9 секунд, те она гарантированно не успеет перейти дорогу на зелёный. Она знает правила, что ей должны дать возможность завершить переход, но тк она вежливая бабушка, она не хочет, чтобы машины ждали на свой зелёный :)
странное объяснение :) абалтус может нажать кнопку и на красной фазе , а потом пойти в другую сторону :)
Плюс использования кнопки как триггера (ну или как флага) заключается в том, что можно выкинуть всю логику, которая завязана на кнопке :) а мы знаем, что чем меньше логики, тем меньше ошибок :) Я уж не говорю о том, что пешеходы не отжимают кнопку светофора ;
Только если людям красный - только тогда кнопка воспринимается.
Точно, это я фигню спорол именно так постоянно и делаю
скажи как кнопка должна работать и сделаем
Дело не в этом. Кнопке нужно слишком много данных и заранее неизвестно каких.
Я хочу иметь отдельный класс для логики кнопки, а не размазывать всё по остальному коду.
Она вежливая бабушка и знает, что на переход дороги ей надо 9 секунд,тут от вежливости ничего не зависит. Если бабушка подошла к светофору за 2 секунды до отключения зелёного, то на светофоре не написано что 2 секунды осталось, поэтому бабушка даже об это не узнает, а пойдет через дорогу.
абалтус может нажать кнопку и на красной фазе , а потом пойти в другую сторону :)красной фазе чего? ежели он нажмет когда машинам красный - то флаг ему в руки, все его потуги пойдут в игнор.
Плюс использования кнопки как триггераоборудование не было оговорено, что в кнопке тригер сидит.
программа расчитана на тупое замыкание контактов.
Я уж не говорю о том, что пешеходы не отжимают кнопку светофора ;это программой предусмотренно.
Дело не в этом. Кнопке нужно слишком много данных и заранее неизвестно каких. Я хочу иметь отдельный класс для логики кнопки, а не размазывать всё по остальному коду.понятно: ты не знаешь как кнопка работает, но знаешь что она в классе.

Мне как раз главнее знать как она работает, а реализация до лампочки.
Сегодня кнопка работает так, а завтра по другому.может быть. но я не могу себе представить как кнопка может работать по другому?! в программе ловится сигнал от кнопки, а как он был выработан - до лампочки
впрочем можно конечно себе представить, что сигнал будет выработан только после неких манипуляций с кнопкой, типа: два коротких, три длинных нажатия, а после второго длинного надо подпрыгнуть и оббежать вокруг столба, и проорать "кукареку".
Ты подобное имел ввиду, говоря что не знаешь как кнопка работает?
Начали мы с самой простой функции, но как оказалось, что в данной реализации дополнительную кнопку просто негде опрашивать. Извратиться конечно можно, но извращения нам ни к чему.
Так что функцию Delay /Задержка/ нужно как то убрать. Нужно ее просто преобразовать во что то, что не стоит тупо на месте. Можно просто проверять сколько прошло времени, но тогда потеряется последовательность состояний.
Какой выход? Увы только усложнять.
Давайте еще раз глянем на нашу функцию, что там можно увидеть?
Видим 4 состояния которые связаны между собой. Каждой состояние имеет определенный паттерн: инициализация при входе, задержка, некая работа перед выходом из состояния.
Так как классы мы уже начали изучать, то сразу виден некий базовый объект и наследуемые от него объекты которые будут определять инициализацию при входе в состояние и работу перед выходом. (Хотя в данном случае эта работа одинаковая для всех состояний)
internal class State { private readonly int _durationMs; private State _next; private int _startTime; public State(int durationMs) { _durationMs = durationMs; } public virtual void DoStateStep() { // do nothing here } public virtual void EnterState() { _startTime = Environment.TickCount; } public virtual void ExitState() { // do nothing here } public bool IsStateFinished() { return Environment.TickCount - _startTime >= _durationMs ; } public int DurationMs { get { return _durationMs; } } public State Next { get { return _next; } set { _next = value; } } }
Для сокращения места приведем только одно состояние, так как остальные состояния, будут отличаться всего одной функцией EnterState(), код которых берется из состояний 2,3,4
internal class AutoRedState : State { private readonly CombinedTrafficLight _trafficLight; public AutoRedState(CombinedTrafficLight trafficLight, int durationMs, State next = null) : base(durationMs, next) { _trafficLight = trafficLight; } public override void EnterState() { base.EnterState(); _trafficLight.DisableAutoTraffic(); _trafficLight.EnablePedestrianTraffic(); } public override void ExitState() { base.ExitState(); Program.TraceState(_trafficLight); } }
Еще будет интересно знать как выглядит основная функция.
private static void Main() { CombinedTrafficLight trafficLight = new CombinedTrafficLight(); InitTraceState(); //инициализация состояний ButtonSimulator button = new ButtonSimulator(); State redState = new AutoRedState(trafficLight, RedLightTimeMs); State yellowStateAfterRed = new AutoYellowAfterRedState(trafficLight, YellowLightTimeMs); State greenState = new AutoGreenState(trafficLight, GreenLightTimeMs, button); State yellowStateAfterGreen = new AutoYellowAfterGreenState(trafficLight, YellowLightTimeMs); redState.Next = yellowStateAfterRed; yellowStateAfterRed.Next = greenState; greenState.Next = yellowStateAfterGreen; yellowStateAfterGreen.Next = redState; // цикл перехода между состояниями State currentState = redState; currentState.EnterState(); while (true) { button.CheckButtonState(); currentState.DoStateStep(); if (currentState.IsStateFinished()) { currentState.ExitState(); button.ClearPressedState(); currentState = currentState.Next; if (currentState == null) { break; } currentState.EnterState(); } Thread.Sleep(100); } }
Вроде бы кода много добавили, но более запутанным, он по идее не стал. По крайней мере если надо изменить состояние - изменяем класс конкретного состояния.
Нужно добавить новое состояние, тоже происходит без проблем, не нужно исправлять много разных частей.
Ты подобное имел ввиду, говоря что не знаешь как кнопка работает?
Нет, мы же в разных мирах
Сегодня, хочу что нажатие кнопки сокращало зелёный машинам на какое то время.
Завтра, что бы следующее сокращение могло происходило только после одного полного цикла.
Послезавтра, что бы машины ездили не менее 15 секунд до срабатывания следующего запроса.
Через неделю может еще, что захочется. И каждый раз надо думать как "собрать" все условия и где это всё разместить.
Я загнал классы Программиста в яву и запустил. Работает. Кнопку прикрутил отдельным потоком, просто как реакцию на нажатие любой кнопки на клавиатуре. Все работает согласно его логике. Потом чуть изменил контроллер. Поменялась логика. Состояния , где пешеходам красный, просто крутятся в цикле. При достижении состояния, где пешеходу МОЖЕТ БЫТЬ включен зеленый, проверяется кнопка. И если она нажата, то включается состояние "красный-зеленый". Без кнопки "красный-красный". Код подправлен для логики одного светофора на перекрестке. Где переключение цикличное.