shithub: schnek

Download patch

ref: 948904886f31aa2203ab43ba5eae52e296ee2642
author: glenda <[email protected]>
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