Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Архив3 / Kursach(33) / 09. ТСПП (дод Г)

.docx
Скачиваний:
20
Добавлен:
07.08.2013
Размер:
35.98 Кб
Скачать

Додаток Д

Лістинги

Program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

using Elevator;

namespace consoleApp

{

class Program // Клас Program

{

static void Main(string[] args)

{

Building theBuilding = new Building(); //Створюємо будинок

Console.SetCursorPosition(1, 24);

Console.WriteLine(); //Переводим на строчку вниз, щоб потім не скакати

while (true)

{

theBuilding.master_tick(); //таймер

theBuilding.record_floor_reqs();

} } }}

ClassLibrary1.dll

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Elevator

{

public enum Direction { UP = 0, DOWN = 1, STOP = 2 }

public class Building

{

public static void clear_line()

{

for (int i = 0; i < 79; i++) Console.Write(" ");

}

private bool[,] floor_request; //Масив запитів поверхів

Elevator[] car_list; //Кабінки - ліфти

//Конструктор

public Building()

{

Console.Clear(); // Очистка екрану

car_list = new Elevator[4]; // Обявлення масиву 4х ліфтів

floor_request = new bool[2, 20]; // 2 направлення 20 поверхів

for (int i = 0; i < 4; i++) створити ліфти

{

car_list[i] = new Elevator(this, i); //Клас Elevator

}

for (int i = 0; i < 20; i++) // Для кожного поверху

{

Console.SetCursorPosition(3, 20 - i); // виводим номер поверху на екран

Console.Write((i + 1));

if (i < 10) Console.Write(" ");

floor_request[(int)Direction.UP, i] = false; // Запитів ще не було

floor_request[(int)Direction.DOWN, i] = false;

}

}

public void master_tick() // Метроном

{

int j;

show_floor_reqs(); // Вивести запити поверхів

for (j = 0; j < 4; j++) // Для кожного ліфта

{

Elevator el = (Elevator)car_list[j];

el.car_tick1(); // Куди поїде кожен ліфт?

}

for (j = 0; j < 4; j++)

{

Elevator el = (Elevator)car_list[j];

el.car_tick2(); Реальний запуск кожного ліфта

}

}

public bool get_floor_req(Direction dir, int floor) // Перевірка того, чи є запити

{

return floor_request[(int)dir, floor];

}

public void set_floor_req(Direction dir, int floor, bool updown) // Встановити запит

{

floor_request[(int)dir, floor] = updown;

}

public int get_cars_floor(int carNo) // Найти кабінку

{

return car_list[carNo].get_floor();

}

public Direction get_cars_dir(int carNo) // Визначення направлення

{

return car_list[carNo].get_direction();

}

public void show_floor_reqs() Вивід запитів

{

for (int j = 0; j < 20; j++)

{

Console.SetCursorPosition(7, 20 - j);

if (floor_request[(int)Direction.UP, j]) Console.Write("^"); // стрілка вверх

else Console.Write(" ");

Console.SetCursorPosition(7 + 3, 20 - j);

if (floor_request[(int)Direction.DOWN, j]) Console.Write("v"); // стрілка вниз

else Console.Write(" ");

}

}

public void record_floor_reqs() // Получення запитів з поверху

{ // так як натиснення кнопок у ліфті на поверсі

char[] ustring = new char[80];

int iFloor;

char chDirection;

Console.SetCursorPosition(1, 22); // низ екрану

Console.Write("Введiть \"!\" для визову лiфта або ENTER для продовження: ");

string en = Console.ReadLine(); //очікування вводу

if (en != "!") return; //якщо не ! то ввод відміняється

Console.SetCursorPosition(1, 22);

Building.clear_line();

Console.SetCursorPosition(1, 22);

Console.Write("На якому ви етажi? ");

iFloor = int.Parse(Console.ReadLine()); //// получити поверх

Console.Write("В якому направленнi будете рухатись(u/d): ");

string dir = Console.ReadLine(); // получити направлення

chDirection = dir[0]; // получити символ

if (chDirection == 'u') floor_request[(int)Direction.UP, iFloor - 1] = true; // запит вверх

if (chDirection == 'd') floor_request[(int)Direction.DOWN, iFloor - 1] = true; // запит вниз

Console.SetCursorPosition(1, 22); // стерти старий текст

Building.clear_line();

Console.SetCursorPosition(1, 23);

Building.clear_line();

Console.SetCursorPosition(1, 24);

Building.clear_line();

}

}

} // Закінчення класу Building

namespace Elevator // функціонал класу Elevator

{

public class Elevator

{

private Building ptrBuilding;

private int car_number;

private int current_floor;

private int old_floor;

private Direction current_dir;

private bool[] destination;

private int loading_timer;

private int unloading_timer;

public Elevator(Building ptrB, int nc) // конструктор

{

ptrBuilding = ptrB;

car_number = nc;

current_floor = 0; // почати з 0

old_floor = 0; // запам’ятати бивший поверх

destination = new bool[20];

current_dir = Direction.STOP; // спочатку стоїть на місці

for (int j = 0; j < 20; j++)

{

destination[j] = false; // пасажири ще не натискали кнопки

}

loading_timer = 0; // ще не почалась посадка

unloading_timer = 0; // ще не почалась висадка

}

public void car_tick1() // метроном 1 для кожного ліфта

{

car_display(); // кабінка

dests_display(); // кінцеві поверхи

if (loading_timer > 0) --loading_timer; //рахунок часу посадки

if (unloading_timer > 0) --unloading_timer; // рахунок часу висадки

decide(); // прийняття рішення

}

private void decide() // прийняття рішення

{

int j;

//флаги показують зверху чи знизу запроси чи назначення

bool destins_above, destins_below; //кінцеві пункти

bool requests_above = false, requests_below = false; // запити

int nearlest_higher_req = 0;

int nearlest_lower_req = 0;

bool car_between_up, car_between_dn;

bool car_opposite_up, car_opposite_dn;

int ofloor; // поверх

Direction odir; // направлення

// впевнитись чи ми не дуже високо чи низько

if ((current_floor == 20 - 1 && current_dir == Direction.UP) ||

(current_floor == 0 && current_dir == Direction.DOWN)) current_dir = Direction.STOP;

//якщо етаж назначення - цей, почати висадку

if (destination[current_floor] == true)

{

destination[current_floor] = false; // удалити це значення

if (unloading_timer == 0) // висадка

unloading_timer = 3;

return;

}

// провести посадку на борт

if (ptrBuilding.get_floor_req(Direction.UP, current_floor) && current_dir != Direction.DOWN)

{

current_dir = Direction.UP; // якщо була зупинка

ptrBuilding.set_floor_req(current_dir, current_floor, false);

if (loading_timer == 0) // посадка

loading_timer = 3;

return;

}

// посадити пасажирів

if (ptrBuilding.get_floor_req(Direction.DOWN, current_floor) && current_dir != Direction.UP)

{

current_dir = Direction.DOWN; // якщо була зупинка

// удалити ЗП в данному направленні

ptrBuilding.set_floor_req(current_dir, current_floor, false);

if (loading_timer == 0) // посадка

loading_timer = 3;

return;

}

// Перевірка інших назначень чи ЗП (запитів поверхів)

destins_above = false;

destins_below = false;

for (j = current_floor + 1; j < 20; j++) // перевірка верхніх поверсів

{

if (destination[j])

destins_above = true;

if (ptrBuilding.get_floor_req(Direction.UP, j) || ptrBuilding.get_floor_req(Direction.DOWN, j))

{

requests_above = true;

if (nearlest_higher_req == 0)

nearlest_higher_req = j;

}

}

for (j = current_floor - 1; j >= 0; j--) // перевірка нижніх поверхів

{

if (destination[j])

destins_below = true;

if (ptrBuilding.get_floor_req(Direction.UP, j) || ptrBuilding.get_floor_req(Direction.DOWN, j))

{

requests_below = true;

if (nearlest_lower_req == 0)11111111111111111111111111111111111111111111111

nearlest_lower_req = j;

} }

// якщо немає запитів - зупитись

if (!destins_above && !requests_above && !destins_below && !requests_below)

{ current_dir = Direction.STOP;

return;

}// Якщо є назначення – почати роботу

if (destins_above && (current_dir == Direction.STOP || current_dir == Direction.UP))

{ current_dir = Direction.UP;

return;

} if (destins_below && (current_dir == Direction.STOP || current_dir == Direction.DOWN))

{

current_dir = Direction.DOWN;

return;

}

// перевірка руху ліфта

car_between_dn = false;

car_between_up = false;

car_opposite_dn = false;

car_opposite_up = false;

for (j = 0; j < 4; j++) // перевіряєм кожний ліфт

{ if (j != car_number) // якщо це не наш ліфт

{ ofloor = ptrBuilding.get_cars_floor(j); // встановити його поверх

odir = ptrBuilding.get_cars_dir(j); // та направлення

// якщо їде вгору та ЗП вгорі

if ((odir == Direction.UP || odir == Direction.STOP) && requests_above)

}

if ((current_dir == Direction.UP || current_dir == Direction.STOP) &&

requests_above && !car_between_up && !car_opposite_dn)

{ current_dir = Direction.UP;

return;

}

if ((current_dir == Direction.DOWN || current_dir == Direction.STOP) &&

requests_below && !car_between_dn && !car_opposite_up)

{ current_dir = Direction.DOWN;

return; // зупинитись

}

current_dir = Direction.STOP;

} // Кінець метода decide

private void dests_display() // вевести кінцеві поверхи

{

for (int j = 0; j < 20; j++)

{

Console.SetCursorPosition(7 - 2 + (car_number + 1) * 7, 20 - j);

if (destination[j])

Console.Write("*"); // Зірочка – позначення поверху

else

Console.Write(" "); // пробіл

} }

private void car_display() // вивід образу ліфта

{

Console.SetCursorPosition(7 + (car_number + 1) * 7, 20 - old_floor);

Console.Write(" "); // стерти зі старої позиції

Console.SetCursorPosition(7 - 1 + (car_number + 1) * 7, 20 - current_floor);

switch (loading_timer) // завантаження ліфта

{ case 3:

Console.Write("\x01W W "); //ліфт з відкритими дверима

break; // мордочка зліва

case 2:

Console.Write(" W\x01W " ); // мордочка в дверях

get_distinations(); получити кінцевий поверх

break;

case 1:

Console.Write(" WWW "); закриті двері без мордочки

break;

case 0:

Console.Write(" WWW "); двері закриті

break;

} Console.SetCursorPosition(7 + (car_number + 1) * 7, 20 - current_floor);

switch (unloading_timer) // вигризка ліфта

{ case 3:

Console.Write("W\x01W "); // двері відкриті, мордочка в дверях

break;

case 2:

Console.Write("W W\x01"); // Двері відкриті мордочка справа

break;

case 1:

Console.Write("WWW "); // двері закриті мордочки немає

break;

case 0:

Console.Write("WWW "); двері закриті

break;

}

old_floor = current_floor; // приїхали

} public void car_tick2() // метроном 2 для кожного ліфта

{ move(); їдемо (якщо потрібно)

} private void move()

{ if (loading_timer > 0 || unloading_timer > 0) // якщо посадка чи висадка

return;

if (current_dir == Direction.UP) // якщо вверх - вверх

current_floor++;

else

if (current_dir == Direction.DOWN) // якщо вниз - вниз

current_floor--;

} public int get_floor() // получення данниго поверху

{ return current_floor;

} public Direction get_direction() // вилучення данного направлдення

{

return current_dir;

}

public void get_distinations() // зупинка

{

int dest_floor; // поверх назначення

Console.SetCursorPosition(1, 22); // получити запроси поверхів

Building.clear_line();

Console.SetCursorPosition(1, 22);

Console.Write("Лiфт " + (car_number + 1) + " зупинився на поверсi " + (current_floor + 1) +

"\n введiть номер поверху для назначення(або 0 для закiнчення вводу)");

for (int j = 1; j < 20; j++)

{

Console.SetCursorPosition(1, 24);

Console.Write("Етаж назначення" + j + ": ");

dest_floor = int.Parse(Console.ReadLine());

Console.SetCursorPosition(1, 24);

Building.clear_line(); // стерти стару стрічку

if (dest_floor == 0) // якщо немає більше запитів

{

//стерти 3 нижніх стрічки

Console.SetCursorPosition(1, 22);

Building.clear_line();

Console.SetCursorPosition(1, 23);

Building.clear_line();

Console.SetCursorPosition(1, 24);

Building.clear_line();

return;

} --dest_floor; // починати з 0 а не з 1

if (dest_floor == current_floor) // вибрати даний поверх

{

j--; // забути його

continue;

}

if (j == 1 && current_dir == Direction.STOP) // записати вибір

current_dir = (dest_floor < current_floor) ? Direction.DOWN : Direction.UP;

destination[dest_floor] = true;

dests_display(); вивести поверхи назначення

}

}

}

}

50

Соседние файлы в папке Kursach(33)