Plan 9 from Bell Labs’s /usr/web/sources/contrib/arpunk/zombies.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/* zombies */

#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <mouse.h>

#define NCOLORS 200

#define MINX -1.0
#define MAXX 1.0
#define MINY -1.0
#define MAXY 1.0

typedef struct Pos Pos;
typedef struct Person Person;

int ppl = 400;
int wlkrs = 10;

struct Pos
{
	double x, y;
};

struct Person
{
	Pos;
	int speed, dead;
	int health;
	int die, ref, targref;
};

Person *persons;
Mousectl *mctl;
Image *col[NCOLORS];
Image *grey;
Image *red;
long sync;

/* stolen from packet.c */
u32int
randomcol(void)
{
	int c[3] = {0, 255, 0};
	int *j, t;
	
	c[2] = rand() % 256;
	j = c + rand() % 3;
	t = c[2];
	c[2] = *j;
	*j = t;
	if(rand()%2){
		t = c[1];
		c[1] = c[0];
		c[0] = t;
	}
	return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | 0xFF;
}

Point
convert(Pos* p)
{
	return (Point){
		screen->r.min.x + (screen->r.max.x - screen->r.min.x) *
		((p->x - MINX) / (MAXX - MINX)),
		screen->r.min.y + (screen->r.max.y - screen->r.min.y) *
		((p->y - MINX) / (MAXX - MINX))};
}

Pos
deconvert(Point p)
{
	return (Pos){
		MINX + (MAXX - MINX) *
		((double)(p.x - screen->r.min.x) / (screen->r.max.x - screen->r.min.x)),
		MINY + (MAXY - MINY) *
		((double)(p.y - screen->r.min.y) / (screen->r.max.y - screen->r.min.y))};
}

void *
emallocz(int size)
{
	void *v;
	
	v = mallocz(size, 1);
	if(v == nil)
		sysfatal("malloc: %r");
	setmalloctag(v, getcallerpc(&size));
	return v;
}

void
createperson(Pos p)
{
	int i, j;
	j = ppl;

	for(i = 0; i < ppl; i++) {
		if(persons[i].Pos.x == p.x && persons[i].Pos.y == p.y)
			return;
		if(persons[i].die == 3 && j == ppl)
			j = i;
	}

	persons[j].Pos = p;
	persons[j].die = 0;
	persons[j].ref = 0;
	persons[j].targref = 0;
}

void
createworld(void)
{
	int i, j;

	for(i = 0; i < NCOLORS; i++)
		col[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, randomcol());

	grey = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x888888FF);
	red = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xFF0000FF);
	
	persons = emallocz(sizeof(*persons) * ppl);

	for(i = 0; i < ppl; i++) {
		persons[i].x = frand() * (MAXX - MINX) + MINX;
		persons[i].y = frand() * (MAXY - MINY) + MINY;
	}

	for(i = 0; i < wlkrs; i++) {
		persons[i].dead = 1;
	}
}

void
rect(Pos *p, int size, Image *col)
{
	Point poi;
	Rectangle r;
	
	poi = convert(p);
	r = insetrect(Rpt(poi, poi), -size);
	draw(screen, r, col, nil, ZP);
}

void
domouse(void)
{
	static Mouse m;
	int lastbut, i;
	double dx, dy, d;
	Point poi;
	
	if(nbrecv(mctl->resizec, &i) == 1)
		if(getwindow(display, Refnone) < 0)
			sysfatal("getwindow: %r");

	lastbut = m.buttons;
	nbrecv(mctl->c, &m);

	if(lastbut & 4 && !(m.buttons & 4))
		for(i = 0; i < ppl; i++){
			poi = convert(&persons[i]);
			dx = poi.x - m.xy.x;
			dy = poi.y - m.xy.y;
			d = sqrt(dx * dx + dy * dy);
			if(d < 5){
				persons[i].die = 1;
				break;
			}
		}

	if(lastbut & 1 && !(m.buttons & 1))
		createperson(deconvert(m.xy));
}

void
movepersons()
{
	int i;

	sleep(600);

	for(i = 0; i < ppl; i++) {
		persons[i].x = frand() * (MAXX - MINX) + MINX;
		persons[i].y = frand() * (MAXY - MINY) + MINY;
	}
}

void
timing()
{
	for(;;){
		semrelease(&sync, 1);
		sleep(30);
	}
}

void
usage(void)
{
	fprint(2, "usage: %s [-D] [-z walkers] [-p ppl]\n", argv0);
	exits("usage");
}

void
threadmain(int argc, char **argv)
{
	int i, j;
	Person *n;

	ARGBEGIN {
	case 'D': break;
	case 'z': wlkrs = atoi(EARGF(usage())); break;
	case 'p': ppl = atoi(EARGF(usage())); break;
	default: usage();
	} ARGEND;

	initdraw(nil, nil, nil);
	mctl = initmouse(nil, screen);
	createworld();

	proccreate(timing, nil, mainstacksize);

	for(;;) {
		domouse();
		draw(screen, screen->r, display->white, nil, ZP);

		for(n = persons; n < ppl + persons; n++) {
			if(!n->die || n->ref)
				rect(n, 3, n->die ? grey : display->black);

			if(n->dead)
				rect(n, 3, n->die ? grey : red);
		}

		movepersons();
		flushimage(display, 1);
		semacquire(&sync, 1);
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.