ref: 3fe6dc0d8361f98d145d82af346814ddb7563e77
dir: /schnek.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> #define SWIDTH 10 /* segement width: size of food and schnek */ typedef enum { UP, DOWN, LEFT, RIGHT } Direction; typedef struct Schnek { Point p[50]; int length; int head; int tail; Direction d; } Schnek; Image *dots, *back, *schnekcolor, *foodcolor; struct Schnek s; /* our hero */ Point food; int starving=0; int moves=0; int eaten=0; int length=0; void newfood(void) { Point newfood; Rectangle r = screen->r; newfood.x = r.min.x + (14)*10; newfood.y = r.min.y + ntruerand(14)*10; food = newfood; } 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 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, schnekcolor, nil, ZP); } flushimage(display, 1); } void endgame(void) { print("Moves: %d\n", moves); print("Eaten: %d\n", eaten); print("Length: %d\n", length); resize(700,400); exits(0); } void moveschnek(void) { Rectangle r = screen->r; Point head, pt; int i; moves++; if (s.length < 50) { if (s.p[s.head].x == food.x && s.p[s.head].y == food.y) { s.length++; if(s.length > length){ length=s.length; } starving=0; eaten++; 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!\n"); endgame(); } } 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!\n"); endgame(); } } redraw(screen); } void eresized(int new) { if(new && getwindow(display, Refnone) < 0) fprint(2,"can't reattach to window"); redraw(screen); } void pause(int) { Event e; int key, inputk; for(;;) { key = event(&e); inputk = e.kbdc; if (key == Ekeyboard) { switch (inputk) { case 'p': return; case 'q': endgame(); break; } } } } void main(int, char**) { Event e; Mouse m; Menu menu; char *mstr[] = {"exit", 0}; int key, timer, inputk; int t; int counter=0; resize(200,200); initdraw(0,0,"schnek"); back = allocimagemix(display, DPalebluegreen, DWhite); schnekcolor = 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(90, 60)); s.p[0] = addpt(screen->r.min, Pt(90,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) { endgame(); } } } 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': endgame(); break; case 'p': pause(1); break; default: break; } } else if (key == timer) { moveschnek(); if (counter == 8) { newfood(); counter=0; } else { counter++; } if (starving == 36) { s.length--; starving=0; } else { starving++; } if (s.length == 0) { print("You've starved!\n"); endgame(); } } } }