💾 Archived View for runjimmyrunrunyoufuckerrun.com › src › games › lights.c captured on 2021-12-17 at 13:26:06.

View Raw

More Information

-=-=-=-=-=-=-

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

enum{ZZZ = 200, SQ = 50, DIM = 8};

uchar bulbdata[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,
0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x01,
0xff,0xff,0x80,0x00,0x00,0x03,0xff,0xff,0xc0,0x00,0x00,0x03,0xff,0xff,0xe0,0x00,
0x00,0x07,0xff,0xff,0xf0,0x00,0x00,0x07,0xff,0xff,0xf0,0x00,0x00,0x0f,0xff,0xff,
0xf0,0x00,0x00,0x0f,0xff,0xff,0xf8,0x00,0x00,0x0f,0xff,0xff,0xf8,0x00,0x00,0x1f,
0xff,0xff,0xf8,0x00,0x00,0x1f,0xff,0xff,0xf8,0x00,0x00,0x1f,0xff,0xff,0xf8,0x00,
0x00,0x0f,0xff,0xff,0xf8,0x00,0x00,0x0f,0xff,0xf3,0xf8,0x00,0x00,0x0f,0xe7,0xed,
0xf8,0x00,0x00,0x0f,0xc9,0xdd,0xf0,0x00,0x00,0x07,0xd9,0x9d,0xf0,0x00,0x00,0x07,
0xdc,0x9d,0xf0,0x00,0x00,0x03,0xdc,0xb3,0xe0,0x00,0x00,0x03,0xce,0x33,0xe0,0x00,
0x00,0x01,0xe6,0x6f,0xc0,0x00,0x00,0x01,0xf2,0x0f,0x80,0x00,0x00,0x00,0xf8,0x1f,
0x80,0x00,0x00,0x00,0xfe,0x7f,0x80,0x00,0x00,0x00,0xfe,0x7f,0x00,0x00,0x00,0x00,
0x7f,0x7f,0x00,0x00,0x00,0x00,0x7f,0x7e,0x00,0x00,0x00,0x00,0x3f,0x7e,0x00,0x00,
0x00,0x00,0x3f,0x7e,0x00,0x00,0x00,0x00,0x3f,0x7e,0x00,0x00,0x00,0x00,0x3f,0x7e,
0x00,0x00,0x00,0x00,0x3f,0x7c,0x00,0x00,0x00,0x00,0x3f,0x7c,0x00,0x00,0x00,0x00,
0x3f,0x7c,0x00,0x00,0x00,0x00,0x1f,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
char *cmds[] = {"solve", "new", "exit", nil};
Menu menu = {cmds};

Image *bulb, *yellow;
u64int lights, pushed, lmask, rmask;

void
redraw(void)
{
	Rectangle r;
	Point p;
	int i, j;

	r = Rect(0, 0, SQ - Borderwidth, SQ - Borderwidth);
	for(i = 0; i < DIM; i++){
		p = addpt(screen->r.min, Pt(Borderwidth, Borderwidth + i * SQ));
		for(j = 0; j < DIM; j++){
			draw(screen, rectaddpt(r, p), lights >> i * DIM + j & 1 ? yellow : display->black, bulb, ZP);
			p.x += SQ;
		}
	}
	flushimage(display, 1);
}

void
eresized(int new)
{
	int fd;

	if(new && getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
	if((!new
	|| Dx(screen->r) != DIM * SQ + Borderwidth
	|| Dy(screen->r) != DIM * SQ + Borderwidth)
	&& (fd = open("/dev/wctl", OWRITE)) >= 0){
		fprint(fd, "resize -dx %d -dy %d",
			DIM * SQ + 3 * Borderwidth,
			DIM * SQ + 3 * Borderwidth);
		close(fd);
	}
	draw(screen, screen->r, display->black, nil, ZP);
	redraw();
}

void
push(u64int x)
{
	lights ^= x | x >> DIM | x << DIM;
	lights ^= x >> 1 & rmask | x << 1 & lmask;
	pushed ^= x;
}

void
solve(void)
{
	while(pushed){
		push(pushed & -pushed);
		redraw();
		sleep(ZZZ);
	}
}

void
new(void)
{
	u64int seed;

	pushed = lights = 0;
	for(seed = lrand() ^ lrand() << 31; seed; seed &= seed - 1)
		push(seed & -seed);
}

void
main(int, char *argv[])
{
	Mouse m;
	int i, b1;

	if(initdraw(nil, nil, argv[0]) < 0)
		sysfatal("initdraw: %r");
	yellow = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DYellow);
	bulb = allocimage(display, Rect(0, 0, 48, 48), GREY1, 1, DNofill);
	loadimage(bulb, bulb->r, bulbdata, sizeof(bulbdata));
	for(lmask = rmask = ~0, i = 0; i < DIM;){
		lmask ^= 1ULL << i * DIM;
		rmask ^= 1ULL << ++i * DIM - 1;
	}
	srand(truerand());
	new();
	einit(Emouse|Ekeyboard);
	eresized(0);
	for(b1 = 0;;){
		m = emouse();
		if(m.buttons & 1)
			b1 = 1;
		else if(m.buttons & 4)
			switch(emenuhit(3, &m, &menu)){
			case 0:
				solve();
				break;
			case 1:
				new();
				redraw();
				break;
			case 2:
				exits(nil);
			}
		else if(b1){
			i = (m.xy.y - screen->r.min.y) / SQ * DIM;
			i += (m.xy.x - screen->r.min.x) / SQ;
			push(1ULL << i);
			redraw();
			b1 = 0;
		}
	}
}