633 lines
23 KiB
C
633 lines
23 KiB
C
// os45park.c - Jurassic Park 10/24/2013
|
|
// ***********************************************************************
|
|
// ** DISCLAMER ** DISCLAMER ** DISCLAMER ** DISCLAMER ** DISCLAMER **
|
|
// ** **
|
|
// ** The code given here is the basis for the CS345 projects. **
|
|
// ** It comes "as is" and "unwarranted." As such, when you use part **
|
|
// ** or all of the code, it becomes "yours" and you are responsible to **
|
|
// ** understand any algorithm or method presented. Likewise, any **
|
|
// ** errors or problems become your responsibility to fix. **
|
|
// ** **
|
|
// ** NOTES: **
|
|
// ** -Comments beginning with "// ??" may require some implementation. **
|
|
// ** -Tab stops are set at every 3 spaces. **
|
|
// ** -The function API's in "OS345.h" should not be altered. **
|
|
// ** **
|
|
// ** DISCLAMER ** DISCLAMER ** DISCLAMER ** DISCLAMER ** DISCLAMER **
|
|
// ***********************************************************************
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include "park.h"
|
|
|
|
JPARK myPark;
|
|
pthread_mutex_t parkMutex; // mutex park variable access
|
|
pthread_mutex_t moveCars;
|
|
pthread_mutex_t fillSeat[NUM_CARS]; // (signal) seat ready to fill
|
|
pthread_mutex_t seatFilled[NUM_CARS]; // (wait) passenger seated
|
|
pthread_mutex_t rideOver[NUM_CARS]; // (signal) ride over
|
|
|
|
void *jurassicTask(void *args)
|
|
{
|
|
int i, j, k;
|
|
char buf[32];
|
|
int c[NUM_CARS];
|
|
// initial car locations
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
myPark.cars[i].location = 33 - i;
|
|
myPark.cars[i].passengers = 0;
|
|
}
|
|
// drivers are all asleep
|
|
for (i = 0; i < NUM_DRIVERS; i++)
|
|
{
|
|
myPark.drivers[i] = 0;
|
|
}
|
|
// initialize other park variables
|
|
myPark.numOutsidePark = 0;
|
|
// # trying to enter park
|
|
myPark.numTicketsAvailable = MAX_TICKETS;
|
|
// T=#
|
|
myPark.numInPark = 0;
|
|
// P=#
|
|
myPark.numRidesTaken = 0;
|
|
// S=#
|
|
myPark.numInTicketLine = 0;
|
|
// Ticket line
|
|
myPark.numInMuseumLine = 0;
|
|
// Museum line
|
|
myPark.numInMuseum = 0;
|
|
// # in museum
|
|
myPark.numInCarLine = 0;
|
|
// Ride line
|
|
myPark.numInCars = 0;
|
|
// # in cars
|
|
myPark.numInGiftLine = 0;
|
|
// Gift shop line
|
|
myPark.numInGiftShop = 0;
|
|
// # in gift shop
|
|
myPark.numExitedPark = 0;
|
|
// # exited park
|
|
|
|
// create move car signal semaphore
|
|
pthread_mutex_init(&moveCars, NULL);
|
|
pthread_mutex_lock(&moveCars);
|
|
|
|
// initialize communication semaphores
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
pthread_mutex_init(&fillSeat[i], NULL);
|
|
pthread_mutex_lock(&fillSeat[i]);
|
|
|
|
pthread_mutex_init(&seatFilled[i], NULL);
|
|
pthread_mutex_lock(&seatFilled[i]);
|
|
|
|
pthread_mutex_init(&rideOver[i], NULL);
|
|
pthread_mutex_lock(&rideOver[i]);
|
|
}
|
|
// start display park task
|
|
pthread_t displayTask;
|
|
pthread_create(&displayTask, NULL, jurassicDisplayTask, NULL);
|
|
|
|
// OK, let's get the park going...
|
|
pthread_mutex_init(&parkMutex, NULL);
|
|
begin = 1;
|
|
|
|
// start lost visitor task
|
|
pthread_t lostTask;
|
|
pthread_create(&lostTask, NULL, lostVisitorTask, NULL);
|
|
|
|
// wait to move cars
|
|
do
|
|
{
|
|
// wait for signal to move cars
|
|
ParkDebug("WAIT(moveCars)");
|
|
pthread_mutex_lock(&moveCars);
|
|
|
|
// order car locations
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
c[i] = i;
|
|
}
|
|
// sort car positions
|
|
for (i = 0; i < (NUM_CARS - 1); i++)
|
|
{
|
|
for (j = i + 1; j < NUM_CARS; j++)
|
|
{
|
|
if (myPark.cars[c[i]].location < myPark.cars[c[j]].location)
|
|
{
|
|
k = c[i];
|
|
c[i] = c[j];
|
|
c[j] = k;
|
|
}
|
|
}
|
|
}
|
|
// move each car if possible (or load or unload)
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
// move car (-1=location occupied, 0=moved, 1=no move)
|
|
if (makeMove(c[i]))
|
|
{
|
|
// check if car is loading
|
|
if ((myPark.cars[c[i]].location == 33) && (myPark.cars[c[i]].passengers < NUM_SEATS) &&
|
|
(myPark.numInCarLine))
|
|
{
|
|
// need a passenger
|
|
sprintf(buf, "SIGNAL(fillSeat[%d])", c[i]);
|
|
ParkDebug(buf);
|
|
pthread_mutex_unlock(&fillSeat[c[i]]);
|
|
// seat open
|
|
sprintf(buf, "WAIT(seatFilled[%d])", c[i]);
|
|
ParkDebug(buf);
|
|
pthread_mutex_lock(&seatFilled[c[i]]);
|
|
// passenger in seat
|
|
myPark.cars[c[i]].passengers++;
|
|
}
|
|
// check if car is unloading
|
|
if ((myPark.cars[c[i]].location == 30) && (myPark.cars[c[i]].passengers > 0))
|
|
{
|
|
// empty each seat until car is empty
|
|
myPark.numRidesTaken++;
|
|
|
|
// if car empty, signal ride over
|
|
if (--myPark.cars[c[i]].passengers == 0)
|
|
{
|
|
sprintf(buf, "SIGNAL(rideOver[%d])", c[i]);
|
|
ParkDebug(buf);
|
|
pthread_mutex_unlock(&rideOver[c[i]]);
|
|
}
|
|
}
|
|
// sanity check
|
|
if ((myPark.cars[0].location == myPark.cars[1].location) ||
|
|
(myPark.cars[0].location == myPark.cars[2].location) ||
|
|
(myPark.cars[0].location == myPark.cars[3].location) ||
|
|
(myPark.cars[1].location == myPark.cars[2].location) ||
|
|
(myPark.cars[1].location == myPark.cars[3].location) ||
|
|
(myPark.cars[2].location == myPark.cars[3].location))
|
|
{
|
|
printf("\nProblem:");
|
|
for (k = 0; k < NUM_CARS; k++)
|
|
printf(" %d", myPark.cars[k].location);
|
|
k = getchar();
|
|
}
|
|
}
|
|
}
|
|
} while (myPark.numExitedPark < NUM_VISITORS);
|
|
// park done
|
|
printf("\nJurassic Park is shutting down for the evening!!");
|
|
return NULL;
|
|
} // end
|
|
|
|
//***********************************************************************
|
|
// Move car in Jurassic Park (if possible)
|
|
//
|
|
// return -1 if location occupied
|
|
// 0 if move ok
|
|
// 1 if no move
|
|
//
|
|
int makeMove(int car)
|
|
{
|
|
int i, j;
|
|
int moved;
|
|
switch (j = myPark.cars[car].location)
|
|
{
|
|
// at cross roads 1
|
|
case 7: {
|
|
j = (rand() % 2) ? 24 : 8;
|
|
break;
|
|
}
|
|
// at cross roads 2
|
|
case 20: {
|
|
// take shorter route if no one in line
|
|
if (myPark.numInCarLine == 0)
|
|
{
|
|
j = 28;
|
|
}
|
|
else
|
|
{
|
|
j = (rand() % 3) ? 28 : 21;
|
|
}
|
|
break;
|
|
}
|
|
// bridge loop
|
|
case 23: {
|
|
j = 1;
|
|
break;
|
|
}
|
|
// bridge short route
|
|
case 27: {
|
|
j = 20;
|
|
break;
|
|
}
|
|
// exit car
|
|
case 30: {
|
|
if (myPark.cars[car].passengers == 0)
|
|
{
|
|
j++;
|
|
}
|
|
break;
|
|
}
|
|
// loading car
|
|
case 33: {
|
|
// if there is someone in car and noone is in line, proceed
|
|
// if ((myPark.cars[car].passengers == NUM_SEATS) ||
|
|
// ((myPark.numInCarLine == 0) && myPark.cars[car].passengers))
|
|
// if car is full, proceed into park
|
|
if (myPark.cars[car].passengers == NUM_SEATS)
|
|
{
|
|
j = 0;
|
|
}
|
|
break;
|
|
}
|
|
// all other moves
|
|
default: {
|
|
j++;
|
|
break;
|
|
}
|
|
}
|
|
// check to see if position is taken
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
if (i != car)
|
|
{
|
|
|
|
if (myPark.cars[i].location == j)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
// return 0 if car moved
|
|
moved = (myPark.cars[car].location == j);
|
|
// make move
|
|
myPark.cars[car].location = j;
|
|
return moved;
|
|
}
|
|
// ***********************************************************************
|
|
// ***********************************************************************
|
|
// jurassic task
|
|
// ***********************************************************************
|
|
void *jurassicDisplayTask(void *args)
|
|
{
|
|
// wait for park to get initialized...
|
|
|
|
while (!begin)
|
|
{
|
|
}
|
|
|
|
// display park every second
|
|
do
|
|
{
|
|
JPARK currentPark;
|
|
// update every second
|
|
sleep(1);
|
|
// take snapshot of park
|
|
pthread_mutex_lock(&parkMutex);
|
|
currentPark = myPark;
|
|
pthread_mutex_unlock(&parkMutex);
|
|
// draw current park
|
|
drawPark(¤tPark);
|
|
// signal for cars to move
|
|
pthread_mutex_unlock(&moveCars);
|
|
|
|
} while (myPark.numExitedPark < NUM_VISITORS);
|
|
// park done
|
|
pthread_mutex_unlock(&moveCars);
|
|
printf("\nThank you for visiting Jurassic Park!!");
|
|
return NULL;
|
|
} // end
|
|
//***********************************************************************
|
|
// Draw Jurassic Park
|
|
// 1 2 3 4 5 6 7
|
|
// 01234567890123456789012345678901234567890123456789012345678901234567890
|
|
// _______________________________________________________ 0
|
|
// Entrance / ++++++++++++++++++++++++++++++++++++++++++| 1
|
|
// - +o0o-o1o-o2o-o3o-o4o-o5o-o6o +| 2
|
|
// ## - /+ / \ +| 3
|
|
// / o + o ************ o +| 4
|
|
// |******** ##>>33 + 23 *Cntrl Room* 7 +| 5
|
|
// |*Ticket* o + o * A=# D1=# * o +| 6
|
|
// |*Booth * 32 + | * B=# D2=# * / \ +| 7
|
|
// |* T=# * ## o + o * C=# D3=# * o o8o-o9o +| 8
|
|
// |* P=## * 31 + 22 * D=# D4=# * 24 \ +| 9
|
|
// |* S=# * o + o ************ o o +| 10
|
|
// |******** ##<<30 + \ / 10 +| 11
|
|
// | o + o21-o20-o27-o26-o25 o +| 12
|
|
// | \+ / \ | +| 13
|
|
// | +o29-o28 o o +| 14
|
|
// | +++++++++++ 19 11 +| 15
|
|
// | + o o +| 16
|
|
// | ## ## + \ / +| 17
|
|
// | ******\ /****\ /******** + o O\ o +| 18
|
|
// | * * * + 18 \/|||\___ 12 +| 19
|
|
// \ * Gifts * Museum * + o x x o +| 20
|
|
// - * # * ## * + \ / +| 21
|
|
// ## - * * * + o17-o16-o15-o14-o13 +| 22
|
|
// \ ************************ ++++++++++++++++++++++++++++++++| 23
|
|
//
|
|
char *myTime(char *svtime)
|
|
{
|
|
time_t cTime; // current time
|
|
|
|
time(&cTime); // read current time
|
|
strcpy(svtime, asctime(localtime(&cTime)));
|
|
svtime[strlen(svtime) - 1] = 0; // eliminate nl at end
|
|
return svtime;
|
|
} // end myTime
|
|
|
|
#define D1Upper 13
|
|
#define D1Left 45
|
|
#define D1Lower 18
|
|
#define D1Right 53
|
|
#define D2Upper 4
|
|
#define D2Left 53
|
|
#define D2Lower 13
|
|
#define D2Right 57
|
|
void drawPark(JPARK *park)
|
|
{
|
|
static int direction1 = D1Left;
|
|
static int dy1 = D1Lower;
|
|
static int direction2 = D2Left;
|
|
static int dy2 = D1Lower - 9;
|
|
int i, j;
|
|
char svtime[64]; // ascii current time
|
|
char driver[] = {'T', 'z', 'A', 'B', 'C', 'D'};
|
|
char buf[32];
|
|
char pk[25][80];
|
|
static int cp[34][3] = {
|
|
{2, 29, 0}, {2, 33, 0}, {2, 37, 0}, {2, 41, 0}, // 0-6
|
|
{2, 45, 0}, {2, 49, 0}, {2, 53, 0}, {4, 57, 1}, // 7
|
|
{8, 59, 0}, {8, 63, 0}, // 8-9
|
|
{10, 67, 1}, {14, 67, 1}, {18, 65, 1}, // 10-12
|
|
{22, 61, 0}, {22, 57, 0}, {22, 53, 0}, // 13-17
|
|
{22, 49, 0}, {22, 45, 0}, {18, 43, 1}, {14, 41, 1}, // 18-19
|
|
{12, 37, 0}, {12, 33, 0}, {8, 31, 1}, {4, 31, 1}, // 20-23
|
|
{8, 55, 3}, // 24
|
|
{12, 49, 0}, {12, 45, 0}, {12, 41, 0}, // 25-27
|
|
{14, 33, 0}, {14, 29, 0}, // 28-29
|
|
{10, 26, 1}, {8, 26, 1}, {6, 26, 1}, {4, 26, 1}, // 30-33
|
|
};
|
|
strcpy(&pk[0][0], " ___Jurassic Park_______________________________________");
|
|
strcpy(&pk[1][0], " Entrance / ++++++++++++++++++++++++++++++++++++++++++|");
|
|
strcpy(&pk[2][0], " - +--------------------------- +|");
|
|
strcpy(&pk[3][0], " # - /+ / \\ +|");
|
|
strcpy(&pk[4][0], " / | + | ************ | +|");
|
|
strcpy(&pk[5][0], " |******** # >>| + | *Cntrl Room* | +|");
|
|
strcpy(&pk[6][0], " |*Ticket* | + | * A=# D1=# * | +|");
|
|
strcpy(&pk[7][0], " |*Booth * | + | * B=# D2=# * / \\ +|");
|
|
strcpy(&pk[8][0], " |* T=# * # | + | * C=# D3=# * / ------- +|");
|
|
strcpy(&pk[9][0], " |* P=# * | + | * D=# D4=# * / \\ +|");
|
|
strcpy(&pk[10][0], " |* S=# * | + | ************ / | +|");
|
|
strcpy(&pk[11][0], " |******** <<| + \\ / | +|");
|
|
strcpy(&pk[12][0], " | | + ------------------- | +|");
|
|
strcpy(&pk[13][0], " | \\+ / \\ | +|");
|
|
strcpy(&pk[14][0], " | +------- | | +|");
|
|
strcpy(&pk[15][0], " | +++++++++++ | | +|");
|
|
strcpy(&pk[16][0], " | + | | +|");
|
|
strcpy(&pk[17][0], " | # # + \\ / +|");
|
|
strcpy(&pk[18][0], " | ******\\ /****\\ /******** + | | +|");
|
|
strcpy(&pk[19][0], " | * * * + | | +|");
|
|
strcpy(&pk[20][0], " \\ * Gifts * Museum * + | | +|");
|
|
strcpy(&pk[21][0], " - * * * + \\ / +|");
|
|
strcpy(&pk[22][0], " # - * * * + ------------------- +|");
|
|
strcpy(&pk[23][0], " \\ ************************ ++++++++++++++++++++++++++++++++|");
|
|
strcpy(&pk[24][0], " Exit \\_____________________________________________________________|");
|
|
// output time
|
|
sprintf(buf, "%s", myTime(svtime));
|
|
memcpy(&pk[0][strlen(pk[0]) - strlen(buf)], buf, strlen(buf));
|
|
|
|
// out number waiting to get into park
|
|
sprintf(buf, "%d", park->numOutsidePark);
|
|
memcpy(&pk[3][12 - strlen(buf)], buf, strlen(buf));
|
|
|
|
// T=#, out number of tickets available
|
|
sprintf(buf, "%d ", park->numTicketsAvailable);
|
|
memcpy(&pk[8][8], buf, strlen(buf));
|
|
|
|
// P=#, out number in park (not to exceed OSHA requirements)
|
|
sprintf(buf, "%d ", park->numInPark);
|
|
memcpy(&pk[9][8], buf, strlen(buf));
|
|
|
|
// S=#, output guests completing ride
|
|
sprintf(buf, "%d", park->numRidesTaken);
|
|
memcpy(&pk[10][8], buf, strlen(buf));
|
|
|
|
// out number in ticket line
|
|
sprintf(buf, "%d ", park->numInTicketLine);
|
|
memcpy(&pk[8][13], buf, strlen(buf));
|
|
|
|
// out number in gift shop line
|
|
sprintf(buf, "%d", park->numInGiftLine);
|
|
memcpy(&pk[17][21 - strlen(buf)], buf, strlen(buf));
|
|
|
|
// out number in museum line
|
|
sprintf(buf, "%d", park->numInMuseumLine);
|
|
memcpy(&pk[17][28 - strlen(buf)], buf, strlen(buf));
|
|
|
|
// out number in car line
|
|
sprintf(buf, "%d", park->numInCarLine);
|
|
memcpy(&pk[5][23 - strlen(buf)], buf, strlen(buf));
|
|
|
|
// out number in gift shop
|
|
sprintf(buf, "%d ", park->numInGiftShop);
|
|
memcpy(&pk[21][17], buf, strlen(buf));
|
|
|
|
// out number in museum
|
|
sprintf(buf, "%d ", park->numInMuseum);
|
|
memcpy(&pk[21][29], buf, strlen(buf));
|
|
|
|
// out number exited park
|
|
sprintf(buf, "%d", park->numExitedPark);
|
|
memcpy(&pk[22][5 - strlen(buf)], buf, strlen(buf));
|
|
|
|
// cars
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
sprintf(buf, "%d", park->cars[i].passengers);
|
|
memcpy(&pk[6 + i][42 - strlen(buf)], buf, strlen(buf));
|
|
}
|
|
// drivers
|
|
for (i = 0; i < NUM_DRIVERS; i++)
|
|
{
|
|
pk[6 + i][46] = driver[park->drivers[i] + 1];
|
|
}
|
|
// output cars
|
|
for (i = 0; i < NUM_CARS; i++)
|
|
{
|
|
// draw car
|
|
j = park->cars[i].location;
|
|
switch (cp[j][2])
|
|
{
|
|
// horizontal
|
|
case 0: {
|
|
pk[cp[j][0]][cp[j][1] + 0] = 'o';
|
|
pk[cp[j][0]][cp[j][1] + 1] = 'A' + i;
|
|
pk[cp[j][0]][cp[j][1] + 2] = 'o';
|
|
break;
|
|
}
|
|
// vertical
|
|
case 1: {
|
|
pk[cp[j][0] + 0][cp[j][1]] = 'o';
|
|
// pk[cp[j][0]+1][cp[j][1]] = 'A'+i;
|
|
// if ((park->cars[i].passengers > 0) && (park->cars[i].passengers < NUM_SEATS))
|
|
if ((park->cars[i].passengers > 0) && ((j == 30) || (j == 33)))
|
|
{
|
|
pk[cp[j][0] + 1][cp[j][1]] = '0' + park->cars[i].passengers;
|
|
}
|
|
else
|
|
pk[cp[j][0] + 1][cp[j][1]] = 'A' + i;
|
|
|
|
pk[cp[j][0] + 2][cp[j][1]] = 'o';
|
|
break;
|
|
}
|
|
case 2: {
|
|
pk[cp[j][0] + 0][cp[j][1] + 0] = 'o';
|
|
pk[cp[j][0] + 1][cp[j][1] + 1] = 'A' + i;
|
|
pk[cp[j][0] + 2][cp[j][1] + 2] = 'o';
|
|
break;
|
|
}
|
|
case 3: {
|
|
pk[cp[j][0] + 0][cp[j][1] - 0] = 'o';
|
|
pk[cp[j][0] + 1][cp[j][1] - 1] = 'A' + i;
|
|
pk[cp[j][0] + 2][cp[j][1] - 2] = 'o';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// move dinosaur #1
|
|
dy1 = dy1 + (rand() % 3) - 1;
|
|
|
|
if (dy1 < D1Upper)
|
|
dy1 = D1Upper;
|
|
|
|
if (dy1 > D1Lower)
|
|
dy1 = D1Lower;
|
|
|
|
if (direction1 > 0)
|
|
{
|
|
memcpy(&pk[dy1 + 0][direction1 + 4], "... /O", 7);
|
|
memcpy(&pk[dy1 + 1][direction1 + 0], "___/|||\\/", 9);
|
|
memcpy(&pk[dy1 + 2][direction1 + 3], "x x", 5);
|
|
if (++direction1 > D1Right)
|
|
direction1 = -direction1;
|
|
}
|
|
else
|
|
{
|
|
if ((rand() % 3) == 1)
|
|
{
|
|
memcpy(&pk[dy1 + 0][-direction1 + 4], "...", 3);
|
|
memcpy(&pk[dy1 + 1][-direction1 + 1], "__/|||\\___", 10);
|
|
memcpy(&pk[dy1 + 2][-direction1 + 0], "O x x", 8);
|
|
}
|
|
else
|
|
{
|
|
memcpy(&pk[dy1 + 0][-direction1 + 0], "O\\ ...", 7);
|
|
memcpy(&pk[dy1 + 1][-direction1 + 2], "\\/|||\\___", 9);
|
|
memcpy(&pk[dy1 + 2][-direction1 + 3], "x x", 5);
|
|
}
|
|
if (++direction1 > -D1Left)
|
|
direction1 = -direction1;
|
|
}
|
|
// move dinosaur #2
|
|
dy2 = dy2 + (rand() % 3) - 1;
|
|
if (dy2 < D2Upper)
|
|
dy2 = D2Upper;
|
|
|
|
if (dy2 > D2Lower)
|
|
dy2 = D2Lower;
|
|
|
|
dy2 = (dy2 + 9) >= dy1 ? dy1 - 9 : dy2;
|
|
|
|
if (direction2 > 0)
|
|
{
|
|
memcpy(&pk[dy2 + 0][direction2 + 7], "_", 1);
|
|
memcpy(&pk[dy2 + 1][direction2 + 6], "/o\\", 3);
|
|
memcpy(&pk[dy2 + 2][direction2 + 4], "</ _<", 5);
|
|
memcpy(&pk[dy2 + 3][direction2 + 3], "</ /", 4);
|
|
memcpy(&pk[dy2 + 4][direction2 + 2], "</ ==x", 6);
|
|
memcpy(&pk[dy2 + 5][direction2 + 3], "/ \\", 4);
|
|
memcpy(&pk[dy2 + 6][direction2 + 2], "//)__)", 6);
|
|
memcpy(&pk[dy2 + 7][direction2 + 0], "<<< \\_ \\_", 9);
|
|
if (++direction2 > D2Right)
|
|
direction2 = -direction2;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&pk[dy2 + 0][-direction2 + 1], "_", 1);
|
|
memcpy(&pk[dy2 + 1][-direction2 + 0], "/o\\", 3);
|
|
memcpy(&pk[dy2 + 2][-direction2 + 0], ">_ \\>", 5);
|
|
memcpy(&pk[dy2 + 3][-direction2 + 2], "\\ \\>", 4);
|
|
memcpy(&pk[dy2 + 4][-direction2 + 1], "x== \\>", 6);
|
|
memcpy(&pk[dy2 + 5][-direction2 + 2], "/ \\", 4);
|
|
memcpy(&pk[dy2 + 6][-direction2 + 1], "(__(\\\\", 6);
|
|
memcpy(&pk[dy2 + 7][-direction2 + 0], "_/ _/ >>>", 9);
|
|
if (++direction2 > -D2Left)
|
|
direction2 = -direction2;
|
|
}
|
|
// draw park
|
|
system("clear");
|
|
|
|
printf("\n");
|
|
for (i = 0; i < 25; i++)
|
|
printf("\n%s", &pk[i][0]);
|
|
printf("\n");
|
|
|
|
// driver in only one place at a time
|
|
for (i = 0; i < (NUM_DRIVERS - 1); i++)
|
|
{
|
|
if (park->drivers[i] != 0)
|
|
{
|
|
for (j = i + 1; j < NUM_DRIVERS; j++)
|
|
{
|
|
assert("Driver Error" && (park->drivers[i] != park->drivers[j]));
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
} // end drawPark
|
|
// ***********************************************************************
|
|
// ***********************************************************************
|
|
// lostVisitor task
|
|
// ***********************************************************************
|
|
void *lostVisitorTask(void *args)
|
|
{
|
|
int inPark;
|
|
while (myPark.numExitedPark < NUM_VISITORS)
|
|
{
|
|
// number in park
|
|
pthread_mutex_lock(&parkMutex);
|
|
inPark = myPark.numInTicketLine + myPark.numInMuseumLine + myPark.numInMuseum + myPark.numInCarLine +
|
|
myPark.numInCars + myPark.numInGiftLine + myPark.numInGiftShop;
|
|
|
|
if (inPark != myPark.numInPark)
|
|
{
|
|
printf("\nSomeone is lost!!!");
|
|
printf("\nThere are %d visitors in the park,", myPark.numInPark);
|
|
printf("\nbut I can only find %d of them!\n", inPark);
|
|
printf("\n numInPark=%d", myPark.numInPark);
|
|
printf("\n inPark=%d", inPark);
|
|
printf("\nnumInTicketLine=%d", myPark.numInTicketLine);
|
|
printf("\nnumInMuseumLine=%d", myPark.numInMuseumLine);
|
|
printf("\n numInMuseum=%d", myPark.numInMuseum);
|
|
printf("\n numInCarLine=%d", myPark.numInCarLine);
|
|
printf("\n numInCars=%d", myPark.numInCars);
|
|
printf("\n numInGiftLine=%d", myPark.numInGiftLine);
|
|
printf("\n numInGiftShop=%d", myPark.numInGiftShop);
|
|
printf("\n");
|
|
assert("Too few in Park!" && (inPark == myPark.numInPark));
|
|
}
|
|
pthread_mutex_unlock(&parkMutex);
|
|
}
|
|
return NULL;
|
|
} // end lostVisitorTask
|