Написать автомат, который покажет сколько литров воды в ёмкости после каждого воздействия - C#
Формулировка задачи:
Не очень понимаю в автоматах требуется помощь. Задача звучит так: есть некая емкость и 2е трубы с вентелями, которые открывают или закрывают трубы. Через одну трубу вода втекает, через другую вытекает. Есть состояния у вентелей открыт/закрыт/открывается/закрывается. В открытом состоянии трубы пропускают 6 литров воды, в открывающемся/закрывающемся - 3 литра. Также есть 5 воздействий: 1. Открыть первую трубу. 2. Закрыть первую трубу. 3. Открыть вторую трубу. 4. Закрыть вторую трубу. 5. Ничего не делать. Требуется написать автомат, который покажет сколько литров воды в ёмкости после каждого воздействия. Начинаем с состояния обе трубы закрыты.
Решение задачи: «Написать автомат, который покажет сколько литров воды в ёмкости после каждого воздействия»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication176
{
class Program
{
static void Main(string[] args)
{
//создаем емкость
var tank = new Tank();
//добавляем две трубы
tank.Pipes.Add(new Pipe() { Name = "Труба 1", Direction = PipeDirection.Incoming });
tank.Pipes.Add(new Pipe() { Name = "Труба 2", Direction = PipeDirection.Outcouming });
//
var cmd = "";
do
{
//обновялем состояние емкости
tank.Update();
//выводим состояние емкости
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(tank);
Console.ResetColor();
//обновляем состояние труб
tank.UpdatePipes();
//подсказка
Console.WriteLine("1 Открыть первую трубу\r\n2 Закрыть первую трубу\r\n3 Открыть вторую трубу\r\n4 Закрыть вторую трубу\r\n5 Ничего не делать\r\n9 Выход");
//читаем управляющее воздействие
cmd = Console.ReadLine();
switch (cmd)
{
case "1": tank.Pipes[0].SetState(PipeState.Opened); break;
case "2": tank.Pipes[0].SetState(PipeState.Closed); break;
case "3": tank.Pipes[1].SetState(PipeState.Opened); break;
case "4": tank.Pipes[1].SetState(PipeState.Closed); break;
}
} while (cmd != "9");
}
}
class Tank
{
public string Name { get; set; }
public float Capacity { get; set; }
public float CurrentVolume { get; set; }
public List<Pipe> Pipes { get; private set; }
public Tank()
{
Name = "Емкость";
Pipes = new List<Pipe>();
Capacity = 100;
}
public void Update()
{
foreach(var pipe in Pipes)
CurrentVolume += pipe.Bandwidth*(int)pipe.Direction;
if (CurrentVolume > Capacity)
CurrentVolume = Capacity;
if (CurrentVolume < 0)
CurrentVolume = 0;
}
public void UpdatePipes()
{
foreach (var pipe in Pipes)
pipe.GoToNextState();
}
public override string ToString()
{
var sb = new StringBuilder();
foreach(var pipe in Pipes)
sb.AppendFormat("{0}: {1}\r\n", pipe.Name, pipe.State);
return string.Format("Текущий объем жидкости в {0}: {1:G}\r\n{2}", Name, CurrentVolume, sb);
}
}
class Pipe
{
public string Name { get; set; }
public PipeState State { get; private set;}
public Dictionary<PipeState, float> Bandwidthes { get; private set; }
public float Bandwidth{ get{ return Bandwidthes[State];} }
public PipeDirection Direction { get; set;}
public Pipe()
{
Bandwidthes = new Dictionary<PipeState,float>();
Bandwidthes[PipeState.Closed] = 0;
Bandwidthes[PipeState.Opened] = 6;
Bandwidthes[PipeState.Opening] = Bandwidthes[PipeState.Closing] = 3;
Direction = PipeDirection.Incoming;
}
public void SetState(PipeState newState)
{
switch(newState)
{
case PipeState.Opened:
if(State != PipeState.Opened) State = PipeState.Opening;
break;
case PipeState.Closed:
if(State != PipeState.Closed) State = PipeState.Closing;
break;
default:
State = newState;
break;
}
}
public void GoToNextState()
{
switch(State)
{
case PipeState.Opening: State = PipeState.Opened; break;
case PipeState.Closing: State = PipeState.Closed; break;
}
}
}
enum PipeState
{
Closed = 0,
Opening = 1,
Closing = 2,
Opened = 3
}
enum PipeDirection : int
{
Incoming = 1,
Outcouming = -1
}
}