русский
Germany.ruForen → Архив Досок→ Programmierung

Задачи для начинающих

15.02.21 09:59
Re: Задачи для начинающих
 
Программист коренной житель
in Antwort anly 14.02.21 18:46

жно. только обернуть в класс. и дёргать его.но чтобы ниже приведенное получить надо поработать

Прости конечно, но это самое ужасное режение из всех возможных.

Его минусы:

1) оно не масштабируемое.

2) оно сложно тестируемо.


Предлагаю подойти к решению задачи с другой стороны:

1) надо признать, что мы тут говорим о состояниях, а не о каких-то алгоритмах. Состояний у светофора не так много:

+----+----------------+---------------+----------------+------------------+------------------+
| Nr | машины Красный | машины Желтый | машины Зеленый | пешеходы Красный | пешеходы Зеленый |
+----+----------------+---------------+----------------+------------------+------------------+
| 1  |      1         |      0        |       0        |         0        |         1        |
| 2  |      1         |      0        |       0        |         1        |         0        |
| 3  |      0         |      1        |       0        |         1        |         0        |
| 4  |      0         |      0        |       1        |         1        |         0        |
+----+----------------+---------------+----------------+------------------+------------------+

Если я какое-то состояние упустил, то его можно добавить :)

Итак, делаем интерфейс описывающий состояния светофора:

public enum CarLight
{
  Red,
  Yellow,
  Green
}
public enum PedestrianLight
{
  Red,
  Green
}
public interface ITrafficLight
{
  CarLight CarLight { get; }
  PedestrianLight PedestrianLight { get; }
}
public class TrafficLight : ITrafficLight
{
  public CarLight CarLight { get; set: }
  public PedestrianLight PedestrianLight { get; set; }
}


2) Вспоминаем, что у нас есть кнопка и описываем ее интерфейсом:

public interface ITrafficLightButton
{
   bool IsPressed { get; }
   void Reset ();
}


3) Теперь можем описать состояния:

public interface ITrafficLightState
{
  ITrafficLight TrafficLight { get; }
  void Wait ();
}
public class TrafficLightState : ITrafficLightState
{
  private int _delay;
  public ITrafficLight TrafficLight { get; private set; }
  public <span class="redactor-invisible-space"></span>TrafficLightState (ITrafficLight trafficLight, int delay)
  {
     // тут проверить параметры
     TrafficLight = trafficLight;
     _delay = delay;
  }
  public virtual void Wait ()
  {
    Thread.Sleep (_delay);
  }
}
public class TrafficLightWaitForPedestrianState : TrafficLightState
{
  private ITrafficLightButton _button;
  public TrafficLightWaitForPedestrian (ITrafficLightButton button, ITrafficLight trafficLight, int delay)
    : base (trafficLight, delay)
  {
    if (button == null)
      throw new ArgumentNullException ("button must be initialized");<span class="redactor-invisible-space"></span>
    _button = button;
  }
  public override void Wait ()
  {
    while (_button.IsPressed == false)
      Thread.Sleep (1000);
    base.Wait ();
  }
}
public class TrafficLightResetButtonState : TrafficLightState
{
  private ITrafficLightButton _button;
  public TrafficLightWaitForPedestrian (ITrafficLightButton button, ITrafficLight trafficLight, int delay)
    : base (trafficLight, delay)
  {
    if (button == null)
      throw new ArgumentNullException ("button must be initialized");<span class="redactor-invisible-space"></span>
    _button = button;
  }
  public override void Wait ()
  {
    _button.Reset ();
    base.Wait ();
  }
}


4) Теперь нам нужен зацикленный контейнер:

public class CircularList<T> : IEnumerable<T>, IEnumerator<T>
{
  private List<T> _list = new List<T>();
...
  public void Add (T item)
  {
    _list.Add(item);
  }
...
  #region имплементация IEnumerable<T>
...
  #endregion
  #region имплементация IEnumerator<T>
...
  #endregion
}


5) Ну и теперь самое интересное - код светофора:


В конструкторе светофора инициализуруем состояния:

ITrafficLightButton button = new TrafficLightButton();
CircularList<ITrafficLightState> states = new CircularList<ITrafficLightState>();
states.Add (new TrafficLightWaitForPedestrianState(button, new TrafficLight() { CarLight = CarLight.Green, PedestrianLight = PedestrianLight.Red }, 5000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Yellow, PedestrianLight = PedestrianLight.Red }, 3000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Red }, 2000 );
states.Add (new TrafficLightResetButtonState(button, new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Green}, 15000 );
states.Add (new TrafficLightState(new TrafficLight() { CarLight = CarLight.Red, PedestrianLight = PedestrianLight.Red }, 1000 );


А вот и так этот светофор работает:

foreach (ITrafficLightState trafficLightState in states)
{
  TurnTrafficLights(trafficLightState.TrafficLight);
  trafficLightState.Wait ();
}

Вот собственно говоря и все :)


 

Sprung zu