Code:
// Gocart Race by Joseph Larson Ver 18-Mar-2008
#include <curses.h>
#include <time.h>
#define XSIZE 79
#define YSIZE 24
#define SPEED 50
char track[] = "3)1+?!*?&1+?!(1@!`3!!O*~}$tlv!0O'p0x!,?)pnw&3+7*plw&3+7*plw.3-"
"3`1,q,r.3-3`1,v+7Py.7*{&7,3`1,~1/3\"7*~o/3\"7*~o/3#?)~o/3`z'~O/3hz'~O/3`y%~70"
"3!!!-3!-1!'3!.7!'?!.O!(q!0O";
/*int car[4] = {ACS_UARROW, ACS_RARROW, ACS_DARROW, ACS_LARROW};*/
int car[4];
char buf[YSIZE][XSIZE];
int init() { // Setup Curses the way we want it.
initscr ();
if ((LINES < YSIZE) || (COLS < XSIZE)) {
endwin();
return (1);
}
raw (); nodelay(stdscr,1); noecho(); curs_set(0); nonl(); keypad(stdscr,1);
start_color();
init_pair (1, COLOR_RED, COLOR_WHITE); // Track
init_pair (2, COLOR_BLACK, COLOR_YELLOW);// Finish
init_pair (3, COLOR_BLUE, COLOR_WHITE); // Car
init_pair (4, COLOR_RED, COLOR_BLACK); // Red Light
init_pair (5, COLOR_YELLOW, COLOR_BLACK); // Yellow Light
init_pair (6, COLOR_GREEN, COLOR_BLACK); // Green Light
car[0] = ACS_UARROW;
car[1] = ACS_RARROW;
car[2] = ACS_DARROW;
car[3] = ACS_LARROW;
return 0;
}
void draw_track () {
int x, y, c, pl, cur, tr;
for (x = 0; x <= XSIZE ; x++) mvaddch(0, x, ACS_BOARD|COLOR_PAIR(1));
c = pl = 0; cur = track[0] - 33;
for (y = 1; y < YSIZE; y++) {
mvaddch (y, 0, ACS_BOARD|COLOR_PAIR(1));
for (x = 1; x < XSIZE; x++) {
if (pl == 6) {cur = track[++c] - 33; pl = 0;}
if (cur < 15) {cur++; tr = 0;}
else if (cur > 78) {cur--; tr = 1;}
else tr = ((cur - 15) & (1 << pl++));
buf[y][x] = !tr;
tr = (tr) ? ACS_BOARD : ' ';
mvaddch (y, x, tr | COLOR_PAIR (1));
refresh();
}
mvaddch (y, XSIZE, ACS_BOARD|COLOR_PAIR (1));
}
for (x = 0; x <= XSIZE; x++) mvaddch(YSIZE, x, ACS_BOARD|COLOR_PAIR(1));
for (y = 1; y <= 3; y++) mvaddch(y, 37, ACS_DIAMOND|COLOR_PAIR(2));
}
void play () {
int x, y, ch, dir;
double secs;
/*clock_t*/ time_t start, timer;
draw_track ();
x = 41, y = 2; dir = 1;
mvaddch (y, x, car[dir]|COLOR_PAIR(3));
refresh ();
for (ch = 0; ch < 3; ch++)
mvaddch(0, 38 + ch, ACS_DIAMOND|COLOR_PAIR(4 + ch));
refresh();
for (ch = 0; ch < 3; ch++) {
napms (1000);
mvaddch(0, 38 + ch, ACS_DIAMOND|COLOR_PAIR(4 + ch)|A_BOLD); refresh();
beep();
if (ch < 2) mvaddch(0, 38 + ch, ACS_DIAMOND|COLOR_PAIR(4 + ch));
}
time(&start);
do {
time(&timer);
/*secs = (double)(timer - start) / CLOCKS_PER_SEC;*/
secs = difftime(timer, start);
mvprintw (YSIZE - 1, 37, "%.2f", secs);
mvaddch (y, x, ' '|COLOR_PAIR(1));
ch = getch();
switch (ch) {
case KEY_UP : dir = 0; break;
case KEY_RIGHT : dir = 1; break;
case KEY_DOWN : dir = 2; break;
case KEY_LEFT : dir = 3; break;
}
switch (dir) {
case 0 : y--; break;
case 1 : x++; break;
case 2 : y++; break;
case 3 : x--; break;
}
mvaddch (y, x, car[dir]|COLOR_PAIR(3));
refresh ();
napms (SPEED);
} while (buf[y][x]);
if ((x == 37) && (y >= 1) && (y <= 3)) mvaddstr (10, 35, "You WIN!");
else mvaddstr (10, 36, "CRASH!");
mvaddstr (12, 34, "Total Time:");
mvprintw (13, 37, "%.2f", secs);
}
int main () {
if (init()) return 0;
else {
play();
}
mvaddstr(15, 27, "Press any key to quit...");
while (getch() == ERR);
endwin();
return 0;
}
Modified lines are indicated with blue, of course. I didn't make only one key exit, though.