Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

Подписываем
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Предоплата всего
Подписываем
Федеральное агентство по образованию
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО
ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ «ОМСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Кафедра «Информатика и вычислительная техника»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
К КУРСОВОЙ РАБОТЕ
по дисциплине «Операционные системы»
Разработка многопоточной программного приложения для операционной системы Windows
подпись, дата
Исполнитель
подпись, дата
Омск 2009
Отчет 22 с., 1 ч., 1 рис., 1 табл., 1 источ.
ЛИФТ, НИТЬ, СЕМАФОР, ПАРАЛЛЕЛЬНЫЕ ПРОЦЕССЫ, WINDOWS
Предметом исследований является возможность программирования параллельных процессов на примере задачи «о двух лифтах».
Цель реализация задачи «о двух лифтах».
В процессе работы была создана программа, реализующая задачу «о двух лифтах» на языке С в операционной системе Windows.
Степень внедрения может быть использована в качестве учебного материала о реализации параллельных процессов.
В результате была произведена программная реализация задачи «о двух лифтах».
Содержание
[0.1] Руководитель [0.2] А.Н. Флоренсов [0.3] студент группы ИВТ-346 О.И. Бочевич [1] Реферат
[2]
[3] [4] 2 Теоретический анализ
[5]
[6] |
Данная курсовая работа по дисциплине «Операционные системы» посвящена разработке программы.
Цель курсового проекта написать программу удовлетворяющую требованиям задания, описанного в пункте 1.
В процессе разработки программы необходимо решить следующие задачи:
создание нитей-лифтов;
создание нитей-людей;
возможность параллельной работы каждой нити в отдельности;
Первый раздел посвящен описанию поставленной задачи. Второй посвящен теоретическому анализу поставленной задачи. Третий раздел посвящен общему и детальному ходу выполнения программы.
Разработать для ОС Windows многопоточную программную имитацию работы лифтов. Два лифта в различных концах здания обслуживают 6 этажей. Фиксированное число N потенциальных пассажиров двигаются независимо друг от друга по этажам или временно уходят из здания на первом этаже. Через случайное время пассажир подходит к одному из лифтов на том этаже, где он вышел из него, и дожидается появления лифта, ожидая, если оказывается необходимым, в очереди, и входит в лифт для подъема или спуска на случайно вычисляемый этаж. Грузоподъемность лифта 3 человека. После выхода из лифта пассажиры с различной скоростью движутся по этажу. Программа должна перед началом работы вводить значение числа N. Поведение модели должно отображаться на экране в текстовом режиме с помощью символов. Поведение пассажиров должно имитироваться с помощью отдельных нитей. Для правильного взаимодействия использовать семафоры.
Задача о двух лифтах является задачей с параллельными процессами, когда необходимо чтобы каждый человек, заходящий в здание, вызывал лифт, оказывался в очереди, заходил в лифт, приезжал на этаж и ходил по этажу и далее ехал на следующий этаж.
Возможное расположение людей в здании показано на рисунке 1.
Рисунок 1 Возможное расположение людей в здании
3 Описание разработанной системы
3.1 Обоснование и выбор технического обеспечения
Для реализации данной задачи был выбран язык программирования С, т.к. именно этот язык удовлетворяет всем указанным в задаче требованиям.
3.2 Общий ход выполнения программы
Сначала появляются на экране:
1. здание с двумя лифтами
2. запрос на ввод кол-ва людей;
После этого введенное количество людей приходят в здание через парадный вход. Люди подходят к лифтам, вызывают их и становятся в очередь при необходимости.
На случайном этаже выходят люди и начинают ходить с разной скоростью по нему, затем, находившись, заново идут к лифту и вызывают его, едут на другой этаж. Лифты приезжают на тот этаж, где количество желающих больше, чем на другом этаже.
3.3 Детальный ход выполнения программы
void setClosed(int x, int c); - Установить значение закрыто
void taskComplete(int x); - Установить значение задания как выполнено
void runTask(int x); - Выполнить задание
int cheklift(int x); - Проверка лифта x. 0 - пустой, 2 - полный, 1 не то и не другое
int goLift(int x); - Передвижение лифта туда, где его ждут
DWORD WINAPI Chel(); - Подпрограмма для нитей-"людей"
DWORD WINAPI LiftListiner(); -Подпрограмма для обработки лифтов
Переменные для первого лифта:
int consist1[4] = {0, 0, 0, 0}; - состояние лифта
int onTask1 = 0; - Хранит в себе значение 1 - лифт на задании, 0 - простаивает
int isClosed1 = 1; - 1 - Лифт закрыт. 0 Открыт
int current1 = 1; - этаж, где лифт
int m1[6] = {0, 0, 0, 0, 0, 0};- Массив, хранит кол-во желающих лифта на этажах. Что бы знать куда ехать
int task1[6] = {0, 0, 0, 0, 0, 0}; - Массив, хранит номера этажей, на которые нужно приехать
HANDLE hQueue1[7][15]; - хендлы очередей людей к лифту на каждом этаже.
Для второго лифта аналогично, но другие индексы.
Очереди:
if (fLift == 1) {
for (i = 13; i >= 0; i--) //устанавливаем очередь перед лифтом
{
WaitForSingleObject(hQueue1[currentH][i], INFINITE); //Ждем освобождения места впереди
pos = goLeft(pos, 1); //Двигаемся по очереди влево
ReleaseMutex(hQueue1[currentH][i + 1]); //Освобождаем место за собой
}
} else {
for (i = 23; i >= 0; i--) //устанавливаем очередь перед лифтом
{
WaitForSingleObject(hQueue2[currentH][i], INFINITE); //Ждем освобождения места впереди
pos = goRight(pos, 1); //Двигаемся по очереди влево
ReleaseMutex(hQueue2[currentH][i + 1]); //Освобождаем место за собой
}
}
Для людей:
DWORD WINAPI Chel() {
int MySpeed = rand() % 60 + 40; //Случайная скорость передвижения человека
//Общее начало:
int num = 0, i, r;
int currentH = 1; //Исходный этаж
COORD pos; //координаты персонажа
COORD target; //координаты того, куда идти
//Начальные координаты появления людей
pos.X = 28;
pos.Y = 58;
Осуществляется проверка пустой, или нет, лифт
int cheklift(int x) {
if (x == 1) {
//Если лифт полный
if ((consist1[1] == 1) && (consist1[2] == 1) && (consist1[3] == 1)) {
return 2;
}
//Если лифт пустой
if ((consist1[1] == 0) && (consist1[2] == 0) && (consist1[3] == 0)) {
return 0;
} else //Если не пустой и не полный
return 1;
} else {
//Если лифт полный
if ((consist2[1] == 1) && (consist2[2] == 1) && (consist2[3] == 1)) {
return 2;
}
//Если лифт пустой
if ((consist2[1] == 0) && (consist2[2] == 0) && (consist2[3] == 0)) {
return 0;
} else //Если не пустой и не полный
return 1;
}
return -1;
}
3.4 Применение программы
Данная программа может применяться в учебных целях. Так как решаемая задача является базовой при изучении параллельного выполнения процессов, то можно с помощью нее показывать элементы параллельного выполнения нескольких процессов (нитей).
Была разработана программа реализующая базовую задачу о двух лифтах.
Поставленная задача была решена полностью.
Данная программа может быть с успехом применена для обучения применению параллельных процессов (нитей).
1 Флоренсов, А. Н. Операционные системы для программиста: учеб. Пособие. Омск. : Из-во ОмГТУ, 2005. 240 с.
Приложение А
(обязательное)
Код программы
В листинге 1 показан весь код программы.
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<process.h>
#include<string.h>
#include<math.h>
COORD goLeft(COORD pk, int dx); //Движение чела влево на dx клеток
COORD goRight(COORD pk, int dx); //Движение чела влево на dx клеток
COORD randomWalk(COORD k, int Speed); //Функция случайного передвижения человека
COORD walk(COORD k, int Speed); //Функция прогулки человека из дома
COORD goXY(COORD start, COORD end, int Speed); //Движение чела в ХУ
void go();
void setClosed(int x, int c); //Установить значение закрыто
void taskComplete(int x); //Установить значение задания как выполнено
void runTask(int x); //Выолнить задание
void closeOn(short lift, int h);
void openOn(short lift, int h);
void printM(int x); //Печатает М
int cheklift(int x); //Проверка лифта x. 0 - пустой, 2 - полный, 1 не то и не другое
void goLift(int x); //Передвижение лифта туда, где его ждут
void printHome();
void printLifts();
// дескриптор семафора
HANDLE hSemaphore;
// имя семафора
const char lpSemaphoreName[] = "MySemaphore";
DWORD WINAPI Chel(); //подпрограмма для нитей-"людей"
DWORD WINAPI LiftListiner(); //Подпрограмма для обработки лифтов
DWORD n;
//Переменные для первого лифта
int consist1[4] = { 0, 0, 0, 0 }; //состояние лифта
int onTask1 = 0; //Хранит в себе значение 1 - лифт на задании, 0 - простаивает
int isClosed1 = 1; //1 - Лифт закрыт. 0 Открыт
int current1 = 1; //этаж, где лифт
int m1[6] = { 0, 0, 0, 0, 0, 0 }; //Массив, хранит кол-во желающих лифта на этажах. Что бы знать куда ехать
int task1[6] = { 0, 0, 0, 0, 0, 0 }; //Массив, хранит номера этажей, на которые нужно приехать
HANDLE hQueue1[7][15]; //хендлы очередей людей к лифту на каждом этаже
//Переменные для второго лифта
int consist2[4] = { 0, 0, 0, 0 }; //состояние лифта
int onTask2 = 0; //Хранит в себе значение 1 - лифт на задании, 0 - простаивает
int isClosed2 = 1; //1 - Лифт закрыт. 0 Открыт
int current2 = 1; //этаж, где лифт
int m2[7] = { 0, 0, 0, 0, 0, 0, 0 }; //Массив, хранит кол-во желающих лифта на этажах. Что бы знать куда ехать
int task2[7] = { 0, 0, 0, 0, 0, 0, 0 }; //Массив, хранит номера этажей, на которые нужно приехать
HANDLE hQueue2[7][15]; //хендлы очередей людей к лифту на каждом этаже
COORD p;
int maxWidth = 60;
int maxHight = 60;
HANDLE LiftEvent1, LiftEvent2, Semaphore, hout, hPeoples[10]; //хэндлы нитей-"людей"
int main() {
hout = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консоли
printHome();
printLifts();
go();
return 0;
}
void go() {
int i = 0;
int N;
DWORD kl;
isClosed2 = 1;
isClosed1 = 1;
//Да будут же лифты пустыми!
for (i = 0; i < 4; i++) {
consist2[i] = 0;
consist1[i] = 0;
}
for (i = 0; i < 6; i++) {
m2[i] = 0;
m1[i] = 0;
}
//Начальное положение лифтов
current2 = 1;
current1 = 1;
do {
int j;
COORD k;
//Пишем надпись
k.X = 40;
k.Y = 1;
SetConsoleCursorPosition(hout, k);
printf(" Vvedite chislo lydey do 10 ");
scanf("%d", &N);
//Создаем семафоры для всех этажей
for (j = 0; j < 10; j++)
for (i = 0; i < N + 1; i++) //создание семафора очереди
{
hQueue2[j][i] = CreateMutex(NULL, NULL, NULL);
hQueue1[j][i] = CreateMutex(NULL, NULL, NULL);
}
for (i = 0; i < N; i++) //запуск нитей-"людей"
{
hPeoples[i] = CreateThread(NULL, 4096, Chel, NULL, NULL, &kl);
Sleep(500);
}
LiftEvent2 = CreateThread(NULL, 4096, LiftListiner, NULL, NULL, &kl);
LiftEvent1 = CreateThread(NULL, 4096, LiftListiner, NULL, NULL, &kl);
//printf("dddD!");
getch();
} while (N > 0); //для бесконечной работы проги
}
DWORD NumRead;
//Лифт, который может вызываться
int y = 0;
DWORD WINAPI LiftListiner() {
y++;
if (y == 1) { //Проверка какой лифт слушать
while (1 == 1) {
if (cheklift(1) == 0) {//Если пустой
goLift(1); //Идти по вызову
onTask1 = 0;
}
if (cheklift(1) == 2) {//Если полный
runTask(1); //Идти по заданию
onTask1 = 1; //Типа на задании
}
if (cheklift(1) == 1) { //Если не полный и не пустой
runTask(1); //Всё равно идти по заданию
onTask1 = 1;
}
}
} else {
while (1 == 1) {
if (cheklift(2) == 0) {//Если пустой
goLift(2); //Идти по вызову
onTask1 = 0;
}
if (cheklift(2) == 2) {//Если полный
runTask(2); //Идти по заданию
onTask2 = 1; //Типа на задании
}
if (cheklift(2) == 1) { //Если не полный и не пустой
runTask(2); //Всё равно идти по заданию
onTask2 = 1;
}
}
}
}
//Модель поведения человека
int h;
DWORD WINAPI Chel() {
//printf("Go");
int MySpeed = rand() % 60 + 40; //Случайная скорость передживежения человека
//Общее начало:
int num = 0, i, r;
int currentH = 1; //Исходный этаж
COORD pos; //координаты персонажа
COORD target; //координаты того, куда идти
//Начальные координаты появления людей
pos.X = 28;
pos.Y = 58;
RESTART: num = 5;
h++;
//Типа выбираем этаж
srand((int) time(NULL) + h);
do {
r = rand() % 5 + 1; //Генерируем,
} while ((r == currentH) || (r == 0)); //Что бы он был не тот, на котором мы сейчас
//выбираем лифт
int fLift = h % 2;
//int fLift = 2;
target.X = 25;
target.Y = 56 - currentH * 8;
pos = goXY(pos, target, MySpeed);
//Типа вызываем лифт
if (fLift == 1)
m1[currentH]++;
else
m2[currentH]++;
// printM(fLift);
//ОЧЕРЕДЬ
if (fLift == 1) {
for (i = 13; i >= 0; i--) //устанавливаем очередь перед лифтом
{
WaitForSingleObject(hQueue1[currentH][i], INFINITE); //Ждем освобождения места впереди
pos = goLeft(pos, 1); //Двигаемся по очереди влево
ReleaseMutex(hQueue1[currentH][i + 1]); //Освобождаем место за собой
}
} else {
for (i = 23; i >= 0; i--) //устанавливаем очередь перед лифтом
{
WaitForSingleObject(hQueue2[currentH][i], INFINITE); //Ждем освобождения места впереди
pos = goRight(pos, 1); //Двигаемся по очереди влево
ReleaseMutex(hQueue2[currentH][i + 1]); //Освобождаем место за собой
}
}
int start;
if (fLift == 1) {
start = 4;
} else {
start = 53;
}
// создаем семафор
hSemaphore = CreateSemaphore(NULL, 1, 6, lpSemaphoreName);
while (1 == 1) //Ждем, когда приедет лифт
{
if (fLift == 1) { //Если первый лифт
//Если лифт на моем этаже
if (currentH == current1) {
//и не закрытый
if (isClosed1 == 0) {
//Да ещё и свободный...
if (consist1[1] == 0) {
num = 1;
target.X = start + num;
target.Y = pos.Y - 3;
consist1[num] = 1;
break;
}
if (consist1[2] == 0) {
num = 2;
target.X = start + num;
target.Y = pos.Y - 2;
consist1[num] = 1;
break;
}
if (consist1[3] == 0) {
num = 3;
target.X = start + num;
target.Y = pos.Y - 3;
consist1[num] = 1;
break;
}
}
}
} else { //Если второй лифт... быдло код, зато работает..
//Если лифт на моем этаже
if (currentH == current2) {
//и не закрытый
if (isClosed2 == 0) {
//Да ещё и свободный...
if (consist2[1] == 0) {
num = 1;
target.X = start + num;
target.Y = pos.Y - 3;
consist2[num] = 1;
break;
}
if (consist2[2] == 0) {
num = 2;
target.X = start + num;
target.Y = pos.Y - 2;
consist2[num] = 1;
break;
}
if (consist2[3] == 0) {
num = 3;
target.X = start + num;
target.Y = pos.Y - 3;
consist2[num] = 1;
break;
}
}
}
}
}
if (fLift == 1) {
m1[currentH]--;
ReleaseMutex(hQueue1[currentH][0]); //освобождаем последнее место в очреди
} else {
m2[currentH]--;
ReleaseMutex(hQueue2[currentH][0]); //освобождаем последнее место в очреди
}
// printM(fLift);
//заходим в лифт
pos = goXY(pos, target, MySpeed);
//Нажимаем на кнопку r в лифте
if (fLift == 1)
task1[num - 1] = r;
else
task2[num - 1] = r;
//Закрываем семофор
CloseHandle(hSemaphore);
//и спим ^____^
Sleep(300);
boolean tr = 0;
while (1 == 1) //Ждем, когда приедет лифт
{
if (fLift == 1) {
if (isClosed1 == 0) {
if (r == current1) {
Sleep(150);
pos.X = start + num;
pos.Y = 58 - current1 * 8;
target.X = 4 + num;
currentH = current1;
target.Y = pos.Y + 6;
pos = goXY(pos, target, MySpeed);
task1[num - 1] = 0;
consist1[num] = 0;
break;
} else {
Sleep(150);
if ((currentH != current1) && (tr == 1)) {
tr = 0;
pos.X = start + num;
pos.Y = 58 - current1 * 8;
WriteConsoleOutputCharacter(hout, "*", 1, pos, &n);
}
}
} else
tr = 1;
} else {
if (isClosed2 == 0) {
if (r == current2) {
Sleep(150);
pos.X = start + num;
pos.Y = 58 - current2 * 8;
target.X = 4 + num;
currentH = current2;
target.Y = pos.Y + 7;
pos = goXY(pos, target, MySpeed);
task2[num - 1] = 0;
consist2[num] = 0;
break;
} else {
Sleep(150);
if ((currentH != current2) && (tr == 1)) {
tr = 0;
pos.X = start + num;
pos.Y = 58 - current2 * 8;
WriteConsoleOutputCharacter(hout, "*", 1, pos, &n);
}
}
} else
tr = 1;
}
}
if (currentH != 1) {
pos = randomWalk(pos, MySpeed); //Бурогозим на этаже
Sleep(1000); //Отдышимся
} else {
pos = walk(pos, MySpeed);
}
//Надо смыться, после бурогоза!
goto RESTART;
return (0);
}
void taskComplete(int x) {
int i = 0;
if (x == 1) {
for (i = 0; i < 10; i++) {
task1[i] = 0;
}
onTask1 = 0;
} else {
for (i = 0; i < 10; i++) {
task2[i] = 0;
}
onTask2 = 0;
}
}
void runTask(int x) {
int i;
int step;
int tmp = 0;
//Итак, поехали!
for (i = 0; i < 3; i++) {
if (x == 1) {
if (task1[i] != 0) { //Если задание не 0,
if (current1 > task1[i]) { //если лифт выше
step = -1; //едим вниз
} else { //иначе:
step = 1; //едем вверх
}
while (current1 != task1[i]) {//пока не достигнем искомый этаж
current1 += step; //двигаемся к нему
Sleep(1000); //С этой скоростью
}
//Здесть мы как бы достигли уже этаж
openOn(x, current1);
Sleep(4000);
closeOn(x, current1);
Sleep(200);
closeOn(x, current1);
}
tmp = i;
} else {
if (task2[i] != 0) { //Если задание не 0,
if (current2 > task2[i]) { //если лифт выше
step = -1; //едим вниз
} else { //иначе:
step = 1; //едем вверх
}
while (current2 != task2[i]) {//пока не достигнем искомый этаж
current2 += step; //двигаемся к нему
Sleep(1000); //С этой скоростью
}
//Здесть мы как бы достигли уже этаж
openOn(x, current2);
Sleep(4000);
closeOn(x, current2);
Sleep(200);
closeOn(x, current2);
}
tmp = i;
}
}
//onTask = 0;
//taskComplete();
}
//Проверяем, пустой ли лифт
int cheklift(int x) {
if (x == 1) {
//Если лифт полный
if ((consist1[1] == 1) && (consist1[2] == 1) && (consist1[3] == 1)) {
return 2;
}
//Если лифт пустой
if ((consist1[1] == 0) && (consist1[2] == 0) && (consist1[3] == 0)) {
return 0;
} else
//Если не пустой и не полный
return 1;
} else {
//Если лифт полный
if ((consist2[1] == 1) && (consist2[2] == 1) && (consist2[3] == 1)) {
return 2;
}
//Если лифт пустой
if ((consist2[1] == 0) && (consist2[2] == 0) && (consist2[3] == 0)) {
return 0;
} else
//Если не пустой и не полный
return 1;
}
return -1;
}
//Отправить лифт по вызову
void goLift(int x) {
if (x == 1) {
closeOn(x, current1);
int max = -1;
int imax = 0;
int i = 0;
//Найдем этаж, где больше всго людей хотят лифт
for (i = 1; i < 7; i++) {
if (m1[i] > max) {
max = m1[i];
imax = i;
}
}
if (imax == 0) {
int wait = abs(current1 - imax);
Sleep(1000 * wait);
current1 = 0;
} else {
int wait = abs(current1 - imax);
Sleep(500 * wait);
// printf("\n imax = %d",imax);
openOn(x, imax);
current1 = imax;
Sleep(4000);
closeOn(x, imax);
}
} else {
closeOn(x, current2);
int max = -1;
int imax = 0;
int i = 0;
//Найдем этаж, где больше всго людей хотят лифт
for (i = 1; i < 7; i++) {
if (m2[i] > max) {
max = m2[i];
imax = i;
}
}
if (imax == 0) {
int wait = abs(current2 - imax);
Sleep(1000 * wait);
openOn(x, imax);
current2 = 0;
Sleep(4000);
closeOn(x, imax);
} else {
int wait = abs(current2 - imax);
Sleep(500 * wait);
// printf("\n imax = %d",imax);
openOn(x, imax);
current2 = imax;
Sleep(4000);
closeOn(x, imax);
}
}
}
//Установить закрытость дверей
void setClosed(int x, int c) {
if (x == 1)
isClosed1 = c;
else
isClosed2 = c;
}
//Печатаем M - т.е. сколько людей хотят лифта на каждом этаже
/*********************VLEVO*********************/
//Процедура рисования движущегося влево К
//pk-текущие координаты, dx-кол-во шагов
COORD goLeft(COORD pk, int dx) {
HANDLE hout1 = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консоли
int d = 0;
while (d != dx) {
d++;
WriteConsoleOutputCharacter(hout1, " ", 1, pk, &NumRead);
pk.X--;
WriteConsoleOutputCharacter(hout1, "*", 1, pk, &NumRead);
Sleep(100);
}
return pk; //возврат новых координат студента}
COORD goRight(COORD pk, int dx) {
HANDLE hout1 = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консоли
int d = 0;
char *c = 1;
while (d != dx) {
d++;
WriteConsoleOutputCharacter(hout1, " ", 1, pk, &NumRead);
pk.X++;
WriteConsoleOutputCharacter(hout1, "*", 1, pk, &NumRead);
Sleep(100);
}
return pk; //возврат новых координат студента
}
//Рисуем дом
void printHome(COORD k) {
int i = 0;
//Рисуем 6 этажей
for (i = 1; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 9;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 13;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 17;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 21;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 25;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 29;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 33;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 37;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 41;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 45;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 49;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 53;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
for (i = 0; i < maxWidth; i++) //Рисуем стены
{
k.X = i;
k.Y = 57;
WriteConsoleOutputCharacter(hout, "_", 1, k, NULL);
}
//Рисуем вертикальные стены:
for (i = 10; i < maxHight - 2; i++) {
k.X = 0;
k.Y = i; //Рисуем стены
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
for (i = 10; i < maxHight - 2; i++) {
k.X = maxWidth;
k.Y = i; //Рисуем стены
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//Рисуем парадный вход
for (i = 26; i < 30; i++) {
k.X = i;
k.Y = maxHight - 3; //проход в стене
WriteConsoleOutputCharacter(hout, " ", 1, k, NULL);
}
k.X = 25;
k.Y = maxHight - 2;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 30;
k.Y = maxHight - 2;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//Случайно бегаем
COORD randomWalk(COORD k, int MySpeed) {
int count = rand() % 60;
COORD target = k;
int v = 1;
int timer = (int) time(NULL);
target.Y = k.Y;
while ((int) time(NULL) - timer < count) {
target.X = target.X + rand() % 40 * v;
if (target.X < 4) target.X = 4;
if (target.X > 59) target.X = 59;
k = goXY(k, target, MySpeed);
v = -v;
}
return k;
}
//Выходим погулять
COORD walk(COORD k, int MySpeed) {
DWORD n;
int wait = rand() % 60;
int timer = (int) time(NULL);
COORD target;
target.X = 27;
target.Y = 60;
k = goXY(k, target, MySpeed);
WriteConsoleOutputCharacter(hout, " ", 1, k, &n);
while ((int) time(NULL) - timer < wait) {
}
k.X = 28;
k.Y = 58;
target.X = 25;
target.Y = 54;
k = goXY(k, target, MySpeed);
target.X = 27;
target.Y = 60;
WriteConsoleOutputCharacter(hout, " ", 1, target, &n);
return k;
}
//Закрываем лифт. h - верхняя координата. w - левая координата
void closeLift(int w, int h) {
COORD k;
HANDLE hout1 = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консоли
DWORD NumRead2;
k.X = w;
k.Y = h;
WriteConsoleOutputCharacter(hout1, " | ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, "CLOSE", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, "__|__", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
}
//Открываем лифт. h - верхняя координата. w - левая координата
void openLift(int w, int h) {
COORD k;
HANDLE hout1 = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консоли
DWORD NumRead2;
k.X = w;
k.Y = h;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
k.Y++;
WriteConsoleOutputCharacter(hout1, " ", 5, k, &NumRead2);
Sleep(100); //Осторожно, двери открываются))
}
//Открывем лифт. lift - номер лифта. h - этаж
void openOn(short lift, int h) {
int x;
if (lift == 1)
x = 4;
else
x = maxWidth - 8;
switch (h) {
case 1:
openLift(x, 50);
break;
case 2:
openLift(x, 42);
break;
case 3:
openLift(x, 34);
break;
case 4:
openLift(x, 26);
break;
case 5:
openLift(x, 18);
break;
case 6:
openLift(x, 10);
break;
}
setClosed(lift, 0);
}
//Открывем лифт. lift - номер лифта. h - этаж
void closeOn(short lift, int h) {
int x;
if (lift == 1)
x = 4;
else
x = maxWidth - 8;
setClosed(lift, 1);
switch (h) {
case 1:
closeLift(x, 50);
break;
case 2:
closeLift(x, 42);
break;
case 3:
closeLift(x, 34);
break;
case 4:
closeLift(x, 26);
break;
case 5:
closeLift(x, 18);
break;
case 6:
closeLift(x, 10);
break;
}
}
void printLifts() {
COORD k;
int i = 0;
//Рисуем лифтЫ:
//Поседний этаж
for (i = 10; i < 14; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//5ый этаж
for (i = 18; i < 22; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//4ый этаж
for (i = 26; i < 30; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//3ый этаж
for (i = 34; i < 38; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//2ый этаж
for (i = 42; i < 46; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//1ый этаж
for (i = 50; i < 54; i++) {
k.Y = i;
k.X = 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 3;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
k.X = maxWidth - 9;
WriteConsoleOutputCharacter(hout, "|", 1, k, NULL);
}
//Закрываем все лифты
for (i = 1; i <= 6; i++) {
closeOn(1, i);
closeOn(2, i); }}
//Перемещение человека со start в end
COORD goXY(COORD start, COORD end, int MySpeed) {
HANDLE hout1 = GetStdHandle(STD_OUTPUT_HANDLE); //хэндл экрана консолиa
DWORD NumRead;
DWORD NumRead2;
WriteConsoleOutputCharacter(hout1, "*", 1, start, &NumRead2);
while ((start.X != end.X) || (start.Y != end.Y)) {
COORD tmp = start;
COORD target = start;
char c;
WriteConsoleOutputCharacter(hout1, " ", 1, start, &NumRead);
if (start.X > end.X) //Если надо влево, то
{
target.X--;
ReadConsoleOutputCharacter(hout1, &c, 1, target, &NumRead);
if (c == 32) {
start.X--;
target = start;
} else target = start;
}
if (start.X < end.X) //Если надо вправо, то
{
target.X++;
ReadConsoleOutputCharacter(hout1, &c, 1, target, &NumRead);
if (c == 32) {
start.X++;
target = start;
} else target = start;
}
if (start.Y > end.Y) //Если надо вниз, то
{
target.Y--;
ReadConsoleOutputCharacter(hout1, &c, 1, target, &NumRead);
if (c == 32) {
start.Y--;
target = start;
} else target = start;
}
if (start.Y < end.Y) //Если надо вверх, то
{
target.Y++;
ReadConsoleOutputCharacter(hout1, &c, 1, target, &NumRead);
if (c == 32) {
start.Y++;
target = start;
} else target = start;
}
if ((start.X == tmp.X) && (start.Y == tmp.Y)) break;
WriteConsoleOutputCharacter(hout1, "*", 1, start, &NumRead2);
Sleep(MySpeed);
}
WriteConsoleOutputCharacter(hout1, "*", 1, start, &NumRead2);
return start;
}
Листинг 1 код программы