Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЗ по ОС.doc
Скачиваний:
30
Добавлен:
15.06.2014
Размер:
77.82 Кб
Скачать

3 Программный код приложения

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <time.h>

typedef struct Car { // Абстрактная структура, представляющая авто

int x; // Положение автомобиля по x

int y; // Положение автомобиля по y

int color;

} Car;

const int CAR_TRAFFIC = 5; // Кол-во авто, двигающися на одной полосе

const int CAR_DISTANCE = 4; // Дистанция между машинами

const int MIN_SPEED = 10000; // Минимальная скорость

const int MAX_SPEED = 100000; // Максимальная скорость

const int CAR_WIDTH = 4; // Размер машин

const int debug = 0; // Константа для отладки

const int HSTRIPE_RIGHT_Y = 10; // Расположение попутной горизонт. полосы по y

const int HSTRIPE_LEFT_Y = 13; // Расположение встречной горизонт. полосы по y

const int HLINE_Y = 12; // Расположение линий разметки горизонт-x полос

const int VSTRIPE_DOWN_X = 41; // Расположение встречной вертикал. полосы по x

const int VSTRIPE_UP_X = 35; // Расположение попутной вертикал полосы по x

const int VLINE_X = 40; // Расположение линий разметки вертикал-x полос

char grass[] = ",;.',.**"; // Символы, заменяющие траву

pthread_mutex_t hmtx; // Переменная мьютекса

//----------------------------------------------------------

// ГРАФИКА

//----------------------------------------------------------

/*

* Отрисовка фона

*/

void drawBackground()

{

int i, currentChar, flowerColor;

printf("\033[2J"); //Очистка экрана

for ( i = 0; i < 24*80; i++){

currentChar = rand()%8; // Случайный символ травы

if ( grass[currentChar] == '*' ) // Проверка если это цветок

{

switch (currentChar) {

case 6: { printf("\033[0;33;42m"); break; }

case 7: { printf("\033[0;31;42m"); break; }

}

}

else

printf("\033[1;32;42m");

printf("%c", grass[currentChar]);

}

}

/*

* Отрисовка данных работы

*/

void drawCopyright()

{

int i, currentChar, flowerColor;

printf("\033[0;30;42m");

printf("\033[19;47H");

printf("Курсовой проект");

printf("\033[20;47H");

printf("По дисциплине:Операционные системы");

printf("\033[21;47H");

printf("Вариант 25");

printf("\033[22;47H");

printf("Выполнил: Визигин Денис ИВТ-338");

}

/*

* Отрисовка горизонтальных полос дорожного движения т.е. встречной и попутной

* @param offsetY - сдвиг по y, от которого начинается отрисовка

*/

void redrawHStripe(int offsetY)

{

int i, j;

printf("\033[%d;1H\033[1;37;40m", offsetY); // Сдвигаем положение рисования на offsetY

for ( i = 0; i < 2; i++ ){

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

printf(" ");

printf("\n");

}

}

/*

* Отрисовка горизонтальных разделительных линий

* @param offsetY - сдвиг по y, от которого начинается отрисовка

*/

void redrawHLines(int offsetY)

{

int i, j;

printf("\033[%d;1H\033[1;37;40m", offsetY);

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

if ( (j%2 != 0) && ((j < 33) || (j > 45)) )

printf("–");

else

printf(" ");

}

/*

* Отрисовка вертикальных полос дорожного движения т.е. встречной и попутной

* @param offsetX - сдвиг по x, от которого начинается отрисовка

*/

void redrawVStripe(int offsetX)

{

int i;

for ( i = 1; i <= 24; i++ ){

printf("\033[%d;%dH\033[1;37;40m", i, offsetX);

printf(" ");

}

}

/*

* Отрисовка горизонтальных разделительных линий

* @param offsetY - сдвиг по y, от которого начинается отрисовка

*/

void redrawVLines(int offsetX)

{

int i;

for ( i = 1; i <= 24; i++ ){

printf("\033[%d;%dH\033[1;37;40m", i, offsetX);

printf("|");

}

}

//----------------------------------------------------------

// ПЕРЕРИСОВКА ДОРОГ

//----------------------------------------------------------

/*

* Отрисовка горизонтальной дороги

*/

void drawHorizontalRoad()

{

redrawHStripe(HSTRIPE_RIGHT_Y);

redrawHStripe(HSTRIPE_LEFT_Y);

redrawHLines(HLINE_Y);

fflush(stdout);

}

/*

* Отрисовка вертикальной дороги

*/

void drawVerticalRoad()

{

redrawVStripe(VSTRIPE_UP_X);

redrawVStripe(VSTRIPE_DOWN_X);

redrawVLines(VLINE_X);

fflush(stdout);

}

//----------------------------------------------------------

// ПЕРЕРИСОВКА МАШИН

//----------------------------------------------------------

/*

* Отрисовка горизонтальной машины

*/

void drawHCar(struct Car car, int road)

{

int i;

printf("\033[%d;1H", car.y);

printf("\033[1;37;%dm", car.color);

if ( road == 0 ){

if ( car.x + CAR_WIDTH <= 80 ){

printf("\033[%dC", car.x);

printf(" | ");

}

}

else{

if ( car.x - CAR_WIDTH >= 0 ){

printf("\033[%dC", (car.x - CAR_WIDTH));

printf(" | ");

}

}

fflush(stdout);

}

/*

* Отрисовка вертикальной машины

*/

void drawVCar(struct Car car, int road)

{

int i;

printf("\033[1;%dH", car.x);

printf("\033[1;37;%dm", car.color);

if (road == 0) {

if ( car.y < 25 ){

printf("\033[%dB", car.y);

for ( i = 0; i < CAR_WIDTH - 1; i++){

if ( i != 1)

printf(" ");

else

printf("––");

printf("\033[2D\033[1B");

}

}

}

else

{

if ( car.y - CAR_WIDTH > 0 ){

printf("\033[%dB", car.y - CAR_WIDTH);

for ( i = 0; i < CAR_WIDTH - 1; i++){

if ( i != 1)

printf(" ");

else

printf("––");

printf("\033[2D\033[1B");

}

}

}

fflush(stdout);

}

//----------------------------------------------------------

// АВТОМОБИЛЬНЫЕ ПОТОКИ

//----------------------------------------------------------

/*

* Нить отвечающая за поток с левой стороны экрана

*/

void* hTrafficLeft(void* arg)

{

int speed, nextCar, i; // Скорость и машина с которой необходимо начинать отрисовку

int onCrossway, crosswayCar; // Логическое значение машины на перекрёстки и числовое

struct Car cars[CAR_TRAFFIC]; // Структура машин

for ( i = 0; i < CAR_TRAFFIC; i++ ){

cars[i].x = 1;

cars[i].y = 13;

cars[i].color = rand()%(47 - 41 + 1) + 41;

}

nextCar = 1; // Следующая машина которая выедет из-за пределов экрана - 1

onCrossway = 0;

crosswayCar = -1;

while (1)

{

speed = rand() % (MAX_SPEED - MIN_SPEED + 1) + MIN_SPEED; //Случ. скорость

redrawHStripe(HSTRIPE_LEFT_Y); //Отрисовка полосы движения

if (!onCrossway) { // Есть ли машина на перекрёстке

for ( i = nextCar - 1; i >= 0; i-- ){

drawHCar(cars[i], 0); // Отрисовка горизонтальной машины

cars[i].x++; // Положение машины

// Определение въехали ли машина на перекрёсток

if ( cars[i].x > (34-CAR_WIDTH) && cars[i].x < (46-CAR_WIDTH) ) {

pthread_mutex_lock(&hmtx);

onCrossway = 1; //true

crosswayCar = i;

}

}

}

else { // Машина на перекрёстке

for ( i = 0; i < nextCar; i++ ) {

drawHCar(cars[i], 0);//Отрисовка машин если они не достигли перекрёстка

if ( (cars[crosswayCar + 1].x < (34 - CAR_WIDTH) && i != crosswayCar) || ( i < crosswayCar ) )

cars[i].x++;

}

cars[crosswayCar].x++; // Движение машины, которая на перекрёстке

// Проверка выхода за пределы экрана

if ( cars[crosswayCar].x >= 80 ) {

pthread_mutex_unlock(&hmtx);

onCrossway = 0;

crosswayCar = -1;

}

}

usleep(speed);

// Машина с которой нужно начинать отсчёт

if ( nextCar < CAR_TRAFFIC )

if ( cars[nextCar-1].x - (CAR_DISTANCE + CAR_WIDTH) >= cars[nextCar].x )

nextCar++;

if (cars[CAR_TRAFFIC-1].x > 80) break;

}

pthread_exit(0);

}

/*

* Нить отвечающая за поток с верхней стороны экрана

*/

void* vTrafficUp(void* arg)

{

int speed, nextCar, i;

int onCrossway, crosswayCar;

struct Car cars[CAR_TRAFFIC];

for ( i = 0; i < CAR_TRAFFIC; i++ ){

cars[i].x = 37;

cars[i].y = 1;

cars[i].color = rand()%(47 - 41 + 1) + 41;

}

nextCar = 1;

onCrossway = 0;

crosswayCar = -1;

while (1)

{

speed = rand() % (MAX_SPEED - MIN_SPEED + 1) + MIN_SPEED;

redrawVStripe(VSTRIPE_UP_X);

if (!onCrossway) {

for ( i = nextCar - 1; i >= 0; i-- ) {

drawVCar(cars[i], 0);

cars[i].y++;

if ( cars[i].y > (10 - CAR_WIDTH) && cars[i].y < (15 - CAR_WIDTH) ) {

if (debug) {

printf("\033[1;1H");

printf("Attempt to lock on traffic up by y = %d", cars[i].y);

}

pthread_mutex_lock(&hmtx);

onCrossway = 1;

crosswayCar = i;

}

}

}

else {

for ( i = 0; i < nextCar; i++ ) {

drawVCar(cars[i], 0);

if ( (cars[crosswayCar + 1].y < (10 - CAR_WIDTH) && i != crosswayCar) || ( i < crosswayCar ) )

cars[i].y++;

}

cars[crosswayCar].y++;

if ( cars[crosswayCar].y > 24 ) {

if (debug){

printf("\033[1;1H");

printf("Attempt to unlock on traffic up by y = %d", cars[crosswayCar].y);

}

pthread_mutex_unlock(&hmtx);

onCrossway = 0;

crosswayCar = -1;

}

}

usleep(speed);

if ( nextCar < CAR_TRAFFIC)

if ( cars[nextCar-1].y - CAR_DISTANCE - CAR_WIDTH >= cars[nextCar].y )

nextCar++;

if (cars[CAR_TRAFFIC-1].y > 25) break;

}

pthread_exit(0);

}

/*

* Нить отвечающая за поток с правой стороны экрана

*/

void* hTrafficRight(void* arg)

{

int speed, nextCar, i;

int onCrossway, crosswayCar;

struct Car cars[CAR_TRAFFIC];

for ( i = 0; i < CAR_TRAFFIC; i++ ){

cars[i].x = 80;

cars[i].y = 11;

cars[i].color = rand()%(47 - 41 + 1) + 41;

}

nextCar = 1;

onCrossway = 0;

crosswayCar = -1;

while (1)

{

speed = rand() % (MAX_SPEED - MIN_SPEED + 1) + MIN_SPEED;

redrawHStripe(HSTRIPE_RIGHT_Y);

if (!onCrossway) {

for ( i = nextCar - 1; i >= 0; i-- ){

drawHCar(cars[i], 1);

cars[i].x--;

if ( cars[i].x > (34+CAR_WIDTH) && cars[i].x <= (46+CAR_WIDTH) ) {

pthread_mutex_lock(&hmtx);

onCrossway = 1;

crosswayCar = i;

}

}

}

else {

for ( i = 0; i < nextCar; i++ ) {

drawHCar(cars[i], 1);

if ( (cars[crosswayCar + 1].x >= (46 + CAR_WIDTH) && i != crosswayCar) || ( i < crosswayCar ) )

cars[i].x--;

}

cars[crosswayCar].x--;

if ( cars[crosswayCar].x <= 0 ) {

pthread_mutex_unlock(&hmtx);

onCrossway = 0;

crosswayCar = -1;

}

}

usleep(speed);

if ( nextCar < CAR_TRAFFIC )

if ( cars[nextCar-1].x + (CAR_DISTANCE + CAR_WIDTH) <= cars[nextCar].x )

nextCar++;

if (cars[CAR_TRAFFIC-1].x < 0) break;

}

pthread_exit(0);

}

/*

* Нить отвечающая за поток с нижней стороны экрана

*/

void* vTrafficDown(void* arg)

{

int speed, nextCar, i;

int onCrossway, crosswayCar;

struct Car cars[CAR_TRAFFIC];

for ( i = 0; i < CAR_TRAFFIC; i++ ){

cars[i].x = 43;

cars[i].y = 24;

cars[i].color = rand()%(47 - 41 + 1) + 41;

}

nextCar = 1;

onCrossway = 0;

crosswayCar = -1;

while (1)

{

speed = rand() % (MAX_SPEED - MIN_SPEED + 1) + MIN_SPEED;

redrawVStripe(VSTRIPE_DOWN_X);

if (!onCrossway) {

for ( i = nextCar - 1; i >= 0; i-- ) {

drawVCar(cars[i], 1);

cars[i].y--;

if ( cars[i].y > (10 + CAR_WIDTH) && cars[i].y < (15 + CAR_WIDTH) ) {

if (debug) {

printf("\033[1;1H");

printf("Attempt to lock on traffic up by y = %d", cars[i].y);

}

pthread_mutex_lock(&hmtx);

onCrossway = 1;

crosswayCar = i;

}

}

}

else {

for ( i = 0; i < nextCar; i++ ) {

drawVCar(cars[i], 1);

if ( (cars[crosswayCar + 1].y >= (15 + CAR_WIDTH) && i != crosswayCar) || ( i < crosswayCar ) )

cars[i].y--;

}

cars[crosswayCar].y--;

if ( cars[crosswayCar].y < 0 ) {

if (debug){

printf("\033[1;1H");

printf("Attempt to unlock on traffic up by y = %d", cars[crosswayCar].y);

}

pthread_mutex_unlock(&hmtx);

onCrossway = 0;

crosswayCar = -1;

}

}

usleep(speed);

if ( nextCar < CAR_TRAFFIC)

if ( cars[nextCar-1].y + (CAR_DISTANCE + CAR_WIDTH) < cars[nextCar].y )

nextCar++;

if (cars[CAR_TRAFFIC-1].y < 0) break;

}

pthread_exit(0);

}

int main(){

srand(time(0));

drawBackground();

drawCopyright();

drawVerticalRoad();

drawHorizontalRoad();

pthread_t ptHL, ptHR, ptVD, ptVU;

pthread_mutex_init(&hmtx, NULL);

pthread_create(&ptHL, NULL, (void*)hTrafficLeft, (void*)0);

pthread_create(&ptVU, NULL, (void*)vTrafficUp, (void*)1);

pthread_create(&ptHR, NULL, (void*)hTrafficRight,(void*)2);

pthread_create(&ptVD, NULL, (void*)vTrafficDown, (void*)3);

getchar();

return(0);

}

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