changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: add games/linden and games/turtle

changeset 7426: 513ef6e6c0c9
parent 7425: 1d6a49358dd8
child 7427: 1e3449536794
author: aiju
date: Sun, 03 Nov 2019 13:49:23 +0000
files: sys/games/lib/linden/sierpinski sys/games/lib/linden/tree sys/src/games/linden.c sys/src/games/turtle.c
description: add games/linden and games/turtle
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/games/lib/linden/sierpinski
     1.4@@ -0,0 +1,7 @@
     1.5+A
     1.6+A: B-A-B
     1.7+B: A+B+A
     1.8+A = 'draw 1'
     1.9+B = 'draw 1'
    1.10++ = 'turn -60'
    1.11+- = 'turn 60'
     2.1new file mode 100644
     2.2--- /dev/null
     2.3+++ b/sys/games/lib/linden/tree
     2.4@@ -0,0 +1,9 @@
     2.5+0
     2.6+1: 11
     2.7+0: 1[0]0
     2.8+0 = 'draw 0.2'
     2.9+1 = 'draw 0.4'
    2.10+[ = 'push
    2.11+turn -45'
    2.12+] = 'pop
    2.13+turn 45'
     3.1new file mode 100644
     3.2--- /dev/null
     3.3+++ b/sys/src/games/linden.c
     3.4@@ -0,0 +1,198 @@
     3.5+#include <u.h>
     3.6+#include <libc.h>
     3.7+#include <bio.h>
     3.8+#include <ctype.h>
     3.9+
    3.10+Biobuf *Bin;
    3.11+
    3.12+typedef struct Symbol Symbol;
    3.13+typedef struct SString SString;
    3.14+
    3.15+enum { TSTRING = -2 };
    3.16+
    3.17+struct Symbol {
    3.18+	Rune name;
    3.19+	SString *rule;
    3.20+	char *output;
    3.21+	Symbol *next;
    3.22+};
    3.23+
    3.24+struct SString {
    3.25+	int n;
    3.26+	Symbol **d;
    3.27+};
    3.28+#pragma varargck type "σ" SString*
    3.29+
    3.30+Symbol *syms;
    3.31+SString *sstring;
    3.32+char strbuf[1024];
    3.33+
    3.34+void *
    3.35+emalloc(ulong n)
    3.36+{
    3.37+	void *v;
    3.38+	
    3.39+	v = malloc(n);
    3.40+	if(v == nil) sysfatal("malloc: %r");
    3.41+	memset(v, 0, n);
    3.42+	setmalloctag(v, getcallerpc(&n));
    3.43+	return v;
    3.44+}
    3.45+
    3.46+void
    3.47+sstringaddsym(SString *a, Symbol *b)
    3.48+{
    3.49+	a->d = realloc(a->d, (a->n + 1) * sizeof(Symbol *));
    3.50+	a->d[a->n++] = b;
    3.51+}
    3.52+
    3.53+void
    3.54+sstringappend(SString *a, SString *b)
    3.55+{
    3.56+	a->d = realloc(a->d, (a->n + b->n) * sizeof(Symbol *));
    3.57+	memcpy(a->d + a->n, b->d, b->n * sizeof(Symbol *));
    3.58+	a->n += b->n;
    3.59+}
    3.60+
    3.61+Symbol *
    3.62+getsym(Rune name)
    3.63+{
    3.64+	Symbol **sp;
    3.65+	
    3.66+	for(sp = &syms; *sp != nil; sp = &(*sp)->next)
    3.67+		if(name == (*sp)->name)
    3.68+			return *sp;
    3.69+	*sp = emalloc(sizeof(Symbol));
    3.70+	(*sp)->name = name;
    3.71+	return *sp;
    3.72+}
    3.73+
    3.74+int peektok = -1;
    3.75+
    3.76+int
    3.77+lex(void)
    3.78+{
    3.79+	int c;
    3.80+	char *p;
    3.81+	
    3.82+	if(peektok >= 0){
    3.83+		c = peektok;
    3.84+		peektok = -1;
    3.85+		return c;
    3.86+	}
    3.87+	do
    3.88+		c = Bgetrune(Bin);
    3.89+	while(c >= 0 && c < 0x80 && isspace(c) && c != '\n');
    3.90+	if(c == '\''){
    3.91+		p = strbuf;
    3.92+		for(;;){
    3.93+			c = Bgetc(Bin);
    3.94+			if(c == '\'') break;
    3.95+			if(p < strbuf + sizeof(strbuf) - 1)
    3.96+				*p++ = c;
    3.97+		}
    3.98+		*p = 0;
    3.99+		return TSTRING;
   3.100+	}
   3.101+	return c;
   3.102+}
   3.103+
   3.104+int
   3.105+peek(void)
   3.106+{
   3.107+	if(peektok >= 0) return peektok;
   3.108+	return peektok = lex();
   3.109+}
   3.110+
   3.111+SString *
   3.112+symstring(void)
   3.113+{
   3.114+	int c;
   3.115+	SString *r;
   3.116+	
   3.117+	r = emalloc(sizeof(SString));
   3.118+	for(;;){
   3.119+		c = peek();
   3.120+		if(c == '\n' || c == ':')
   3.121+			break;
   3.122+		lex();
   3.123+		r->d = realloc(r->d, (r->n + 1) * sizeof(Symbol *));
   3.124+		r->d[r->n++] = getsym(c);
   3.125+	}
   3.126+	return r;
   3.127+}
   3.128+
   3.129+int
   3.130+fmtsstring(Fmt *f)
   3.131+{
   3.132+	SString *s;
   3.133+	int i;
   3.134+	
   3.135+	s = va_arg(f->args, SString *);
   3.136+	for(i = 0; i < s->n; i++)
   3.137+		fmtprint(f, "%C", s->d[i]->name);
   3.138+	return 0;
   3.139+}
   3.140+
   3.141+void
   3.142+syntax(void)
   3.143+{
   3.144+	sysfatal("syntax error");
   3.145+}
   3.146+
   3.147+void
   3.148+parse(void)
   3.149+{
   3.150+	Symbol *s;
   3.151+	int c;
   3.152+
   3.153+	sstring = symstring();
   3.154+	while(peek() > 0){
   3.155+		if(peek() == '\n') {lex(); continue;}
   3.156+		if(peek() == ':') syntax();
   3.157+		s = getsym(lex());
   3.158+		c = lex();
   3.159+		if(c == ':')
   3.160+			s->rule = symstring();
   3.161+		else if(c == '='){
   3.162+			if(lex() != TSTRING) syntax();
   3.163+			s->output = strdup(strbuf);
   3.164+		}else
   3.165+			syntax();
   3.166+		c = lex();
   3.167+		if(c != -1 && c != '\n') syntax();
   3.168+	}
   3.169+}
   3.170+
   3.171+SString *
   3.172+iterate(SString *in)
   3.173+{
   3.174+	SString *r;
   3.175+	int i;
   3.176+	
   3.177+	r = emalloc(sizeof(SString));
   3.178+	for(i = 0; i < in->n; i++)
   3.179+		if(in->d[i]->rule == nil)
   3.180+			sstringaddsym(r, in->d[i]);
   3.181+		else
   3.182+			sstringappend(r, in->d[i]->rule);
   3.183+	return r;
   3.184+}
   3.185+
   3.186+void
   3.187+main()
   3.188+{
   3.189+	int i, j;
   3.190+
   3.191+	fmtinstall(L'σ', fmtsstring);
   3.192+	Bin = Bfdopen(0, OREAD);
   3.193+	if(Bin == nil) sysfatal("Bfdopen: %r");
   3.194+	parse();
   3.195+	for(j = 0; j < 9; j++){
   3.196+		for(i = 0; i < sstring->n; i++)
   3.197+			if(sstring->d[i]->output != nil)
   3.198+				print("%s\n", sstring->d[i]->output);
   3.199+		print("end\n");
   3.200+		sstring = iterate(sstring);
   3.201+	}
   3.202+}
     4.1new file mode 100644
     4.2--- /dev/null
     4.3+++ b/sys/src/games/turtle.c
     4.4@@ -0,0 +1,199 @@
     4.5+#include <u.h>
     4.6+#include <libc.h>
     4.7+#include <bio.h>
     4.8+#include <draw.h>
     4.9+#include <event.h>
    4.10+#include <keyboard.h>
    4.11+
    4.12+Biobuf *bin;
    4.13+
    4.14+double px, py;
    4.15+double θ;
    4.16+
    4.17+double *stack;
    4.18+int sp;
    4.19+int stacksize;
    4.20+
    4.21+double *lines;
    4.22+int lp;
    4.23+int *frames;
    4.24+int fp;
    4.25+
    4.26+int curframe;
    4.27+
    4.28+double minx = -10, maxx = 10, miny = -10, maxy = 10;
    4.29+
    4.30+Point
    4.31+cvt(double x, double y)
    4.32+{
    4.33+	return Pt((x - minx) * Dx(screen->r) / (maxx - minx) + screen->r.min.x, (maxy - y) * Dy(screen->r) / (maxy - miny) + screen->r.min.y);
    4.34+}
    4.35+
    4.36+void
    4.37+opdraw(int, char **argv)
    4.38+{
    4.39+	double npx, npy, l;
    4.40+	
    4.41+	l = atof(argv[1]);
    4.42+	npx = px + sin(θ * PI / 180) * l;
    4.43+	npy = py + cos(θ * PI / 180) * l;
    4.44+	lines = realloc(lines, (lp + 4) * sizeof(double));
    4.45+	lines[lp++] = px;
    4.46+	lines[lp++] = py;
    4.47+	lines[lp++] = npx;
    4.48+	lines[lp++] = npy;
    4.49+	px = npx;
    4.50+	py = npy;
    4.51+}
    4.52+
    4.53+void
    4.54+opturn(int, char **argv)
    4.55+{
    4.56+	θ += atof(argv[1]);
    4.57+}
    4.58+
    4.59+void
    4.60+oppush(int, char **)
    4.61+{
    4.62+	if(sp + 3 > stacksize){
    4.63+		stack = realloc(stack, (stacksize + 3) * sizeof(double));
    4.64+		stacksize += 3;
    4.65+	}
    4.66+	stack[sp++] = px;
    4.67+	stack[sp++] = py;
    4.68+	stack[sp++] = θ;
    4.69+}
    4.70+
    4.71+void
    4.72+oppop(int, char **)
    4.73+{
    4.74+	if(sp == 0) sysfatal("stack underflow");
    4.75+	θ = stack[--sp];
    4.76+	py = stack[--sp];
    4.77+	px = stack[--sp];
    4.78+}
    4.79+
    4.80+void
    4.81+opend(int, char **)
    4.82+{
    4.83+	θ = 0;
    4.84+	px = 0;
    4.85+	py = 0;
    4.86+	frames = realloc(frames, (fp + 1) * sizeof(int));
    4.87+	frames[fp++] = lp;
    4.88+}
    4.89+
    4.90+typedef struct Cmd Cmd;
    4.91+struct Cmd {
    4.92+	char *name;
    4.93+	int nargs;
    4.94+	void (*op)(int, char**);
    4.95+};
    4.96+
    4.97+Cmd cmdtab[] = {
    4.98+	"draw", 1, opdraw,
    4.99+	"turn", 1, opturn,
   4.100+	"push", 0, oppush,
   4.101+	"pop", 0, oppop,
   4.102+	"end", 0, opend,
   4.103+};
   4.104+
   4.105+void
   4.106+runline(char *s)
   4.107+{
   4.108+	char *f[10];
   4.109+	int nf;
   4.110+	Cmd *p;
   4.111+	
   4.112+	nf = tokenize(s, f, nelem(f));
   4.113+	if(nf == 0) return;
   4.114+	for(p = cmdtab; p < cmdtab + nelem(cmdtab); p++)
   4.115+		if(strcmp(p->name, f[0]) == 0){
   4.116+			if(nf != p->nargs + 1 && p->nargs >= 0)
   4.117+				sysfatal("wrong number of arguments for %s", f[0]);
   4.118+			p->op(nf, f);
   4.119+			return;
   4.120+		}
   4.121+	sysfatal("unknown command %s", f[0]);
   4.122+}
   4.123+
   4.124+void
   4.125+redraw(void)
   4.126+{
   4.127+	int i;
   4.128+
   4.129+	minx = maxx = lines[frames[curframe]];
   4.130+	miny = maxy = lines[frames[curframe]+1];
   4.131+	
   4.132+	for(i = frames[curframe]; i < frames[curframe + 1]; i += 2){
   4.133+		if(lines[i] < minx) minx = lines[i];
   4.134+		if(lines[i] > maxx) maxx = lines[i];
   4.135+		if(lines[i+1] < miny) miny = lines[i+1];
   4.136+		if(lines[i+1] > maxy) maxy = lines[i+1];
   4.137+	}
   4.138+	maxx += (maxx - minx) * 0.05;
   4.139+	minx -= (maxx - minx) * 0.05;
   4.140+	maxy += (maxy - miny) * 0.05;
   4.141+	miny -= (maxy - miny) * 0.05;
   4.142+	if(minx == maxx){ minx -= 0.05; maxx += 0.05; }
   4.143+	if(miny == maxy){ miny -= 0.05; maxy += 0.05; }
   4.144+	draw(screen, screen->r, display->white, nil, ZP);
   4.145+	for(i = frames[curframe]; i < frames[curframe + 1]; i += 4)
   4.146+		line(screen, cvt(lines[i], lines[i+1]), cvt(lines[i+2], lines[i+3]), 0, 0, 0, display->black, ZP);
   4.147+	flushimage(display, 1);
   4.148+}
   4.149+
   4.150+void
   4.151+eresized(int new)
   4.152+{
   4.153+	if(new && getwindow(display, Refnone) < 0){
   4.154+		fprint(2, "colors: can't reattach to window: %r\n");
   4.155+		exits("resized");
   4.156+	}
   4.157+	redraw();
   4.158+}
   4.159+
   4.160+void
   4.161+main()
   4.162+{
   4.163+	char *s;
   4.164+
   4.165+	bin = Bfdopen(0, OREAD);
   4.166+	if(bin == nil) sysfatal("Bfdopen: %r");
   4.167+	
   4.168+	frames = malloc(sizeof(int));
   4.169+	frames[fp++] = 0;
   4.170+		
   4.171+	for(;;){
   4.172+		s = Brdstr(bin, '\n', 1);
   4.173+		if(s == nil) break;
   4.174+		runline(s);
   4.175+	}
   4.176+
   4.177+	if(initdraw(nil, nil, nil) < 0)
   4.178+		sysfatal("initdraw: %r");
   4.179+	einit(Emouse | Ekeyboard);
   4.180+	
   4.181+	redraw();
   4.182+	for(;;){
   4.183+		switch(ekbd()){
   4.184+		case Khome:
   4.185+			curframe = 0;
   4.186+			break;
   4.187+		case Kend:
   4.188+			curframe = fp - 2;
   4.189+			break;
   4.190+		case Kup: case Kleft:
   4.191+			if(curframe > 0)
   4.192+				curframe--;
   4.193+			break;
   4.194+		case ' ': case Kdown: case Kright:
   4.195+			if(curframe < fp - 2)
   4.196+				curframe++;
   4.197+			break;
   4.198+		case 'q': case Kdel:
   4.199+			exits(nil);
   4.200+		}
   4.201+		redraw();
   4.202+	}
   4.203+}