/* hw4.c */ /* * Mike Wilson * curses frogger * December, 1997 */ #include #include #include #include #include #include #define sec(x) ((x) * 1000000) /* to microseconds */ #define random(mx) ((float) (mx) * rand () / (RAND_MAX + 1.0)) #define LOG_NUM 20 /* LOG_NUM lines of logs */ #define WOOD_NUM 5 /* WOOD_NUM pieces of wood per line */ #define LINE_LENGTH 161 #define DEST_ROW 1 #define START_ROW DEST_ROW + LOG_NUM + 1 typedef enum { FROGGY, LOG } Entity; typedef enum { LEFT, RIGHT, UP, DOWN } Direction; typedef enum { PLAYING, WON, LOST, QUIT } FroggyState; typedef struct { int id; Direction dir; int row; int sleeptime; } Log; /* some globals */ FroggyState state; Log logs[LOG_NUM]; char lines[LOG_NUM+2][LINE_LENGTH]; pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER; void init_lines (int num_of_lines, int logs_per_line) { int i=0, j; const char walk[] = "||||||||"; const char wood[] = "==== "; while (i++ < logs_per_line) { strcat (lines[0], walk); strcat (lines[START_ROW - DEST_ROW], walk); for (j=1 ; j<=num_of_lines ; j++) strcat (lines[j], wood); } } inline void drawline (char *line, int row) { move (row, 0); printw (line); } void rotate_line (char *theline, Direction dir) { char tmpline[LINE_LENGTH]; int len; len = strlen (theline); strcpy (tmpline, theline); if (dir == LEFT) { strncpy (theline, tmpline+1, len-1); theline[len-1] = tmpline[0]; } else { strncpy (theline+1, tmpline, len-1); theline[0] = tmpline[len-1]; } } #define DrawFroggy() move (froggy_row, froggy_column); printw ("%c", froggy); #define FroggyWake() move (froggy_row, froggy_column); printw ("%c", under_froggy); #define MoveFroggy(action) FroggyWake (); action; DrawFroggy (); #define LogMovement(dir) ((dir) == LEFT) ? -1 : 1 #define MoveLog(row, dir) rotate_line (lines[(row)-DEST_ROW], (dir)); \ drawline (lines[(row)-DEST_ROW], (row)); \ if (froggy_row == (row)) froggy_column += LogMovement (dir); \ DrawFroggy (); #define OutOfBounds(row, col) ((row)>START_ROW || (row)(strlen(lines[0])-1)) void display (Entity who, int d) { static int froggy_row = START_ROW, froggy_column = (WOOD_NUM * 4); const char froggy = 'O'; static char under_froggy; pthread_mutex_lock (&display_lock); if (who == LOG) { MoveLog (logs[d].row, logs[d].dir); } else /* FROGGY */ switch (d) { case UP: if (froggy_row != DEST_ROW) { MoveFroggy (froggy_row--); } else state = WON; break; case DOWN: if (froggy_row != START_ROW) { MoveFroggy (froggy_row++); } break; case LEFT: if (froggy_column != 0) { MoveFroggy (froggy_column--); } break; case RIGHT: if (froggy_column != strlen (lines[0])-1) { MoveFroggy (froggy_column++); } break; default: printf ("display: This shouldn't happen; d=%d\n", d); } under_froggy = lines[froggy_row - DEST_ROW][froggy_column]; if ((under_froggy == ' ') || OutOfBounds (froggy_row, froggy_column)) state = LOST; move (0,0); refresh (); pthread_mutex_unlock (&display_lock); } #undef DrawFroggy FroggyWake MoveFroggy LogMovement MoveLog Log make_log (int id, Direction dir, int row, int sleeptime) { Log log; log.id = id; log.dir = dir; log.row = row; log.sleeptime = sleeptime; return log; } void * logf (void *p) { Log *log; log = (Log *) p; while (state == PLAYING) { display (LOG, log->id); usleep (log->sleeptime); } return NULL; } int main () { pthread_t log_thread[LOG_NUM]; int i; Direction dir; char c; init_lines (LOG_NUM, WOOD_NUM); for (i=0 ; i