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

trains

.cpp
Скачиваний:
21
Добавлен:
15.06.2014
Размер:
7.54 Кб
Скачать
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define GetRandom(min, max) ((rand() % (int)(((max) + 1) - (min))) + (min))

struct way{				//текущий маршрут: из города begin в город end
	char begin, end;	//со скоростью speed
	int speed;
};
struct position{		//текущая позиция поезда на железной дороге
	char way, offset;	//way - номер участка, offset - положение на этом участке
};
way ways[7];			//7 поездов - 7 маршрутов
position positions[7];	//и 7 позиций на Ж/Д
char nOnMiddle = 0,		//количество поездов, едущих по среднему участку
	direction = 0;		//направление, в котором поезда едут по среднему участку
HANDLE hSemaphore, hstdout;
bool bStop = 0;			//переменная служит для остановки программы

/*
Процедура drawWay - прорисовка одного участка железной дороги
Параметры:
		х - позиция начала прорисовки по горизонтали
		y - позиция начала прорисовки по вертикали
*/
void drawWay(char x, char y)
{
	char buffer[17];
	COORD coord;
	int actLen = 1;	
	for (int i = 0; i < 17; i++) buffer[i] = 210;
	coord.X = x;
	coord.Y = y;
	WriteConsoleOutputCharacter(hstdout, buffer, 17, coord, (LPDWORD)actLen);
	coord.Y = y + 1; coord.X = x;
	for (int i = 0; i < 17; i++) buffer[i] = 211;
	coord.X = x; coord.Y = y + 1;
	WriteConsoleOutputCharacter(hstdout, buffer, 17, coord, (LPDWORD)actLen);
}

/*
Процедура drawTrains - прорисовка железной дороги и всех поездов.
Информация для рисования поездов берется из массива positions.
*/
void drawTrains()
{
	char buffer[10];
	COORD coord;
	int actLen = 1;
	//Очищаем место для Ж/Д
	coord.X = 3; coord.Y = 5;
	WriteConsoleOutputCharacter(hstdout, "                                                            ", 60, coord, (LPDWORD)actLen);
	coord.Y = 6;
	WriteConsoleOutputCharacter(hstdout, "                                                            ", 60, coord, (LPDWORD)actLen);
	coord.Y = 7;
	WriteConsoleOutputCharacter(hstdout, "                                                            ", 60, coord, (LPDWORD)actLen);
	coord.Y = 9;
	WriteConsoleOutputCharacter(hstdout, "                                                            ", 60, coord, (LPDWORD)actLen);
	drawWay(7, 6);				
	drawWay(24, 7);				
	drawWay(7, 8);				
	drawWay(41, 6);				
	drawWay(41, 8);
	strcpy(buffer, "######");	//квадрат из решеток обозначает город
	coord.X = 1;
	coord.Y = 10;
	WriteConsoleOutputCharacter(hstdout, "Gorod A", 7, coord, (LPDWORD)actLen);
	coord.Y = 6;
	for (char f = 0; f < 4; f++)
	{
		WriteConsoleOutputCharacter(hstdout, buffer, 6, coord, (LPDWORD)actLen);
		coord.Y++;
	}
	coord.X = 58;
	coord.Y = 10;
	WriteConsoleOutputCharacter(hstdout, "Gorod B", 7, coord, (LPDWORD)actLen);
	coord.Y = 6;
	for (char f = 0; f < 4; f++)
	{
		WriteConsoleOutputCharacter(hstdout, buffer, 6, coord, (LPDWORD)actLen);
		coord.Y++;
	}
	for (char f = 0; f < 7; f++) buffer[f] = 49 + f;//заполняем массив номерами поездов
	for (int j = 0; j < 7; j++)
	{
		//определяем координаты поезда
		if (positions[j].way == 0) {coord.X = 6 + positions[j].offset; coord.Y = 5;}	
		if (positions[j].way == 1) {coord.X = 6 + positions[j].offset; coord.Y = 7;}	
		if (positions[j].way == 2) {coord.X = 42 + positions[j].offset; coord.Y = 5;}	
		if (positions[j].way == 3) {coord.X = 42 + positions[j].offset; coord.Y = 7;}	
		if (positions[j].way == 4) {coord.X = 24 + positions[j].offset; coord.Y = 6;}	
		//рисуем его номер...
		WriteConsoleOutputCharacter(hstdout, &buffer[j], 1, coord, (LPDWORD)actLen);
		coord.Y++;
		//и сам поезд
		WriteConsoleOutputCharacter(hstdout, "@", 1, coord, (LPDWORD)actLen);
		coord.Y++;
		WriteConsoleOutputCharacter(hstdout, "@", 1, coord, (LPDWORD)actLen);
	}
}

/*
Функция trainThreadProc - описывает поведение поезда на дороге(одна и та же для всех 7 нитей)
В качестве параметра передается номер поезда (начиная с нуля)
*/
unsigned __stdcall trainThreadProc(void *arg)
{
	char source = ways[(int)arg].begin;	//source - пункт отправления
	char dest,							//dest - пункт назначения
		i, 
		curDir,							//направление движения
		offset;							//единичное смещение (зависит от направления)
	while (bStop == 0)
	{
		Sleep(GetRandom(200, 3000));	//случайная задержка перед отправлением
		if (source < 2) dest = GetRandom (2, 3);	
		else dest = GetRandom (0, 1);					
		curDir = (dest > source)? 1 : 2;	//определяем направление
		ways[(int)arg].begin = source;	//записываем маршрут в массив,
		ways[(int)arg].end = dest;		//для синхронизации движения
		//задаем позицию поезда для прорисовки
		positions[(int)arg].way = source;
		if (curDir == 1){
			positions[(int)arg].offset = 0;
			offset = 2;
		}
		else{
			positions[(int)arg].offset = 17;
			offset = -2;
		}
		for (i = 0; i < 9; i++)
		{
			Sleep(ways[(int)arg].speed);
			positions[(int)arg].offset += offset;
		}
		//подъезжаем к среднему участку и ждем, пока он освободится или 
		//если по нему в том же направлении уже едут поезда, то едем за ними
		for (i = 0; i < 1; i++)
			if ((direction != 0)&&(curDir != direction))
			{
				Sleep(500);
				i = -1;
			};
		//если участок был свободен, указываем свое направление движения
     	if (direction == 0)
			direction = curDir;
		WaitForSingleObject(hSemaphore, INFINITE);
		nOnMiddle++;
		positions[(int)arg].way = 4;
		if (curDir == 1){
			positions[(int)arg].offset = 0;
			offset = 2;
		}
		else{
			positions[(int)arg].offset = 17;
			offset = -2;
		}
		for (i = 0; i < 8; i++)
		{
			Sleep(ways[(int)arg].speed);
			positions[(int)arg].offset += offset;
		}
		ReleaseSemaphore(hSemaphore, 1, NULL);
		nOnMiddle--;
		if (nOnMiddle == 0) direction = 0;//если участок освободился, сбрасываем направление
		positions[(int)arg].way = dest;
		if (curDir == 1){
			positions[(int)arg].offset = 0;
			offset = 2;
		}
		else{
			positions[(int)arg].offset = 17;
			offset = -2;
		}
		for (i = 0; i < 9; i++)
		{
			Sleep(ways[(int)arg].speed);
			positions[(int)arg].offset += offset;
		}		
		source = dest;		//указываем, в каком городе поезд стоит теперь
	}
    _endthreadex(0);
	return 0;
}
int main(int argc, char* argv[])
{
	HANDLE hthread1, hthread2, hthread3, hthread4, hthread5, hthread6, hthread7;
	unsigned int threadid1, threadid2, threadid3, threadid4, threadid5, threadid6, threadid7;

	hstdout=GetStdHandle(STD_OUTPUT_HANDLE);	//получаем хэндл стандартного вывода
	hSemaphore = CreateSemaphore(NULL, 7, 0, NULL);	//создаем семафор с макс. значением 7
	
	//случайным обазом расставляем поезда и назначаем им скорости 
	//(чем меньше число, тем больше скорость)
	for (int i = 0; i < 7; i++) {
		ways[i].begin = GetRandom(0, 3);
		ways[i].speed = GetRandom(200, 700);
	}
	//создаем 7 нитей
	hthread1 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)0,  0, &threadid1);
	hthread2 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)1,  0, &threadid2);
	hthread3 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)2,  0, &threadid3);
	hthread4 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)3,  0, &threadid4);
	hthread5 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)4,  0, &threadid5);
	hthread6 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)5,  0, &threadid6);
	hthread7 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)6,  0, &threadid7);
	while (true){
		drawTrains();
		Sleep(100);
	}
	return 0;
}

Соседние файлы в предмете Операционные системы