|
CS256 - Fundamentals of Structured Programming
|
Displaying ./code/snek/snek.c
#include <curses.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <string.h>
typedef enum { NONE, UP, DOWN, LEFT, RIGHT } dir_t;
#define TIMEOUT 80
int score = 0;
int tx, ty, tv;
int tailx[10000];
int taily[10000];
int tlen = 0, head = 0, tail = 0;
int R(int a, int b)
{
int diff = (a < b? b-a : a-b)+1;
int min = a < b? a : b;
return min + (rand()%diff);
}
void startup(void)
{
initscr();
cbreak();
nodelay(stdscr, TRUE);
noecho();
keypad(stdscr, TRUE);
start_color();
curs_set(0);
border(ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER);
srand(time(0) + getpid());
}
void shutdown(void)
{
curs_set(1);
echo();
nocbreak();
endwin();
}
void drawscore(void)
{
mvprintw(0, 10, " Score: %d ", score);
}
void placetarget(void)
{
chtype ch;
do {
tx = R(1, COLS-2);
ty = R(1, LINES-2);
ch = mvinch(ty,tx) & A_CHARTEXT;
} while (ch != ' ');
tv = R(1, 9);
mvprintw(ty, tx, "%d", tv);
}
void addtail(int x, int y)
{
tailx[tlen] = x;
taily[tlen] = y;
tlen++;
mvaddch(y, x, 'o');
}
void eattarget(void)
{
score = score + tv;
drawscore();
mvaddch(ty, tx, ' ');
for(int i=tlen-1; i >= tail; i--) {
tailx[i+tv] = tailx[i];
taily[i+tv] = taily[i];
}
tlen = tlen + tv;
if (head > tail) head = head + tv;
tail = tail + tv;
placetarget();
}
void die()
{
char *diemsg = "You've hit something and died.";
mvprintw(LINES/2, COLS/2 - strlen(diemsg)/2, "%s", diemsg);
nodelay(stdscr, FALSE);
getch();
shutdown();
exit(0);
}
int main(void)
{
startup();
int x = 9, y = LINES/2;
dir_t dir = NONE;
int timeout = 0;
drawscore();
placetarget();
for(x=3; x < 9; x++) addtail(x, y);
addtail(x, y);
mvaddch(y, x, '@');
move(y, x);
head = tlen-1;
tail = 0;
while(1) {
int ch = getch();
if (ch != ERR) timeout = TIMEOUT;
usleep(10000);
timeout++;
if (timeout > TIMEOUT) {
if (ch == 'q' || ch == 'Q') break;
if (ch == KEY_UP || ch == 'w') dir = UP;
if (ch == KEY_DOWN || ch == 's') dir = DOWN;
if (ch == KEY_LEFT || ch == 'a') dir = LEFT;
if (ch == KEY_RIGHT || ch == 'd') dir = RIGHT;
if (dir == NONE) continue;
if (dir == UP) y--;
if (dir == DOWN) y++;
if (dir == LEFT) x--;
if (dir == RIGHT) x++;
timeout = 0;
if (y == ty && x == tx) {
eattarget();
} else {
chtype ch = mvinch(y,x) & A_CHARTEXT;
if (ch != ' ' || y == 0) die();
}
mvaddch(y, x, '@');
mvaddch(taily[head],tailx[head], 'o');
mvaddch(taily[tail],tailx[tail], ' ');
int newhead = (head + 1) % tlen;
if (newhead == tail)
tail = (tail + 1) % tlen;
head = newhead;
tailx[head] = x;
taily[head] = y;
move(y, x);
refresh();
}
}
shutdown();
return 0;
}
|