#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#define SWIDTH 10 /* segment width */
typedef enum {
UP,
DOWN,
LEFT,
RIGHT
} Direction;
typedef
struct Snake {
Point p[50];
int length;
int head;
int tail;
Direction d;
} Snake;
Image *dots, *back, *snakecolor, *foodcolor;
struct Snake s; /* our hero */
Point food;
void
newfood(void) {
Point newfood;
Rectangle r = screen->r;
newfood.x = r.min.x + ntruerand(29)*10;
newfood.y = r.min.y + ntruerand(29)*10;
food = newfood;
}
void
redraw(Image *screen)
{
static Rectangle r;
Point pt;
Rectangle foo;
int i;
r = screen->r;
draw(screen, screen->r, back, nil, ZP);
foo = Rect(food.x, food.y, food.x + SWIDTH, food.y + SWIDTH);
draw(screen, foo, foodcolor, nil, ZP);
for (i = 0; i < s.length; i++) {
pt = s.p[s.head - i];
if (s.head - i < 0)
pt = s.p[50 + (s.head - i)];
foo = Rect(pt.x, pt.y, pt.x + SWIDTH, pt.y + SWIDTH);
draw(screen, foo, snakecolor, nil, ZP);
}
flushimage(display, 1);
}
void
movesnake(void) {
Rectangle r = screen->r;
Point head, pt;
int i;
if (s.length < 50) {
if (s.p[s.head].x == food.x && s.p[s.head].y == food.y) {
s.length++;
newfood();
} else {
s.tail++;
if (s.tail == 50)
s.tail = 0;
}
s.head++;
if (s.head == 50)
s.head = 0;
switch (s.d) {
case UP:
s.p[s.head] = subpt(s.p[s.head-1], Pt(0,SWIDTH));
if (s.head == 0)
s.p[0] = subpt(s.p[49], Pt(0,SWIDTH));
break;
case DOWN:
s.p[s.head] = addpt(s.p[s.head-1], Pt(0,SWIDTH));
if (s.head == 0)
s.p[0] = addpt(s.p[49], Pt(0,SWIDTH));
break;
case LEFT:
s.p[s.head] = subpt(s.p[s.head-1], Pt(SWIDTH,0));
if (s.head == 0)
s.p[0] = subpt(s.p[49], Pt(SWIDTH,0));
break;
case RIGHT:
s.p[s.head] = addpt(s.p[s.head-1], Pt(SWIDTH,0));
if (s.head == 0)
s.p[0] = addpt(s.p[49], Pt(SWIDTH,0));
break;
default:
print("wtf mate\n");
break;
}
head = s.p[s.head];
for (i = 1; i < s.length; i++) {
pt = s.p[s.head - i];
if (s.head - i < 0)
pt = s.p[50 + (s.head - i)];
if (head.x == pt.x && head.y == pt.y) {
print("You hit yourself! Score: %d\n", s.length);
exits(nil);
}
}
if ((head.x < r.min.x) || (head.x > r.max.x - 10) || (head.y < r.min.y) || (head.y > r.max.y - 10)) {
print("You hit a wall! Score: %d\n", s.length);
exits(nil);
}
}
redraw(screen);
}
void
eresized(int new)
{
if(new && getwindow(display, Refnone) < 0)
fprint(2,"can't reattach to window");
redraw(screen);
}
void
resize(int x, int y)
{
int fd;
fd = open("/dev/wctl", OWRITE);
if(fd >= 0){
fprint(fd, "resize -dx %d -dy %d", x, y);
close(fd);
}
}
void
main(int, char**)
{
Event e;
Mouse m;
Menu menu;
char *mstr[] = {"exit", 0};
int key, timer, inputk;
int t;
resize(300,300);
initdraw(0,0,"snake");
back = allocimagemix(display, DPalebluegreen, DWhite);
snakecolor = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGreen);
foodcolor = allocimage(display, Rect(0,0,1,1), RGB24, 1, DBlack);
food = addpt(screen->r.min, Pt(150, 60));
s.p[0] = addpt(screen->r.min, Pt(150,150));
s.length = 1;
s.d = UP;
s.head = 0;
s.tail = 0;
redraw(screen);
einit(Emouse | Ekeyboard);
t = (150);
timer = etimer(0, t);
menu.item = mstr;
menu.lasthit = 0;
for(;;) {
key = event(&e);
if(key == Emouse) {
m = e.mouse;
if(m.buttons & 4) {
if(emenuhit(3, &m, &menu) == 0) {
print("mouse exit\n");
exits(0);
}
}
} else if (key == Ekeyboard) {
inputk = e.kbdc;
switch (inputk) {
case 'h':
if (s.d != RIGHT)
s.d = LEFT;
break;
case 'j':
if (s.d != UP)
s.d = DOWN;
break;
case 'k':
if (s.d != DOWN)
s.d = UP;
break;
case 'l':
if (s.d != LEFT)
s.d = RIGHT;
break;
case 'q':
print("Quitter... your score: %d\n", s.length);
exits(nil);
break;
default:
break;
}
} else if(key == timer) {
movesnake();
}
}
}
|