ref: 948904886f31aa2203ab43ba5eae52e296ee2642
author: glenda <glenda@9front.local>
date: Sun Aug 1 15:24:11 EDT 2021
initial release
--- /dev/null
+++ b/README.md
@@ -1,0 +1,25 @@
+# schnek
+
+schnek - chase down decaying food before your starve.
+
+## Description
+
+schnek chases down decaying food and grows or shrinks while doing
+so. Avoid running into walls or yourself while racking up tallies
+for number of moves, food eaten and maximum length of schnek.
+
+## Usage
+
+`schnek`
+
+movement keys: hjkl
+pause: p
+quit: q
+
+## Installing
+
+Clone, run `mk install`.
+
+## Credits
+
+Originally written as `snake` by John Floren who borrowed code from `clock`
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,11 @@
+</$objtype/mkfile
+
+TARG=schnek
+MAN=/sys/man/1
+BIN=/$objtype/bin/games
+OFILES=\
+ schnek.$O\
+
+</sys/src/cmd/mkone
+
+install:V: $MAN/$TARG
--- /dev/null
+++ b/schnek.c
@@ -1,0 +1,269 @@
+#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 + ntruerand(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++;
+ /* newfood(); */
+ 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(void) {
+ Event e;
+ int key, inputk;
+ for(;;) {
+ key = event(&e);
+ inputk = e.kbdc;
+ /* print("here\n"); */
+ if (key == Ekeyboard) {
+ switch (inputk) {
+ case 'p':
+ /* print("here\n"); */
+ /* break; */
+ return;
+ case 'q':
+ endgame();
+ break;
+ }
+ }
+ }
+ /* return; */
+}
+
+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();
+ 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();
+ }
+ }
+ }
+}
--- /dev/null
+++ b/schnek.man
@@ -1,0 +1,20 @@
+.TH SCHNEK 1
+.SH NAME
+schnek \- chase down decaying food before you starve.
+.SH SYNOPSIS
+.B schnek
+.SH DESCRIPTION
+.I schnek
+chases down decaying food and grows or shrinks while doing so.
+Avoid running into walls or yourself while racking up tallies
+for number of moves, food eaten and maximum length of schnek.
+.PP
+hjkl moves the schnek around, p for pause and q for quit.
+.PP
+.SH CREDITS
+Originally written as
+.B snake
+by John Floren who based it on
+.B clock.
+.PP
+.EE