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

View Raw

More Information

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

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <keyboard.h>
enum{GAP = 4};
Point o;
Image *bg, *fg, *cards;
int w, h, from = -1, to = -1;
char locofcard[52], cardatloc[52];
Rectangle
rect(int i){
	Rectangle r;
	r.min.x = o.x + (i % 13) * (w + GAP);
	r.min.y = o.y + (i / 13) * (h + GAP);
	r.max.x = r.min.x + w;
	r.max.y = r.min.y + h;
	return r;
}
void
paint(Image *colour){
	border(screen, rect(from), -GAP, colour, ZP);
	if(to)
		draw(screen, rect(to), colour, nil, ZP);
	else{
		if(!cardatloc[0])
			draw(screen, rect(0), colour, nil, ZP);
		if(!cardatloc[13])
			draw(screen, rect(13), colour, nil, ZP);
		if(!cardatloc[26])
			draw(screen, rect(26), colour, nil, ZP);
		if(!cardatloc[39])
			draw(screen, rect(39), colour, nil, ZP);
	}
}
void
move(void){
	while(cardatloc[to])
		to += 13;	
	cardatloc[to] = cardatloc[from];
	cardatloc[from] = 0;
	locofcard[cardatloc[to]] = to;
	draw(screen, rect(from), bg, nil, ZP);
	draw(screen, rect(to), cards, nil, Pt(cardatloc[to] % 13 * w, cardatloc[to] / 13 * h));
	from = to = -1;
	flushimage(display, 1);
}
void
threadmain(int, char**){
	Mousectl *m;
	Keyboardctl *kbd;
	Rune k;
	int i, j, b;
	char *s = "shuffles used: 0";
	char *cmd[] = {"hint", "shuffle", "quit", nil};
	Menu menu = {cmd, nil, 0};
	enum{RESIZE, MOUSE, KEYBOARD};
	Alt a[] = {
		[RESIZE]{nil, nil, CHANRCV},
		[MOUSE]{nil, nil, CHANRCV},
		[KEYBOARD]{nil, &k, CHANRCV},
		{nil, nil, CHANEND}
	};
	if(initdraw(nil, nil, "addiction") < 0)
		sysfatal("initdraw: %r");
	bg = allocimage(display, Rect(0,0,1,1), RGBA32, 1, DDarkgreen);
	fg = allocimage(display, Rect(0,0,1,1), RGBA32, 1, DPaleyellow);
	if(bg == nil || fg == nil)
		sysfatal("allocimage: %r");
	if((i = open("/sys/games/lib/cards/default.bit", OREAD)) < 0)
		sysfatal("couldn't find cards: %r");
	if((cards = readimage(display, i, 0)) == nil)
		sysfatal("readimage: /sys/games/lib/cards/default.bit bad format");
	close(i);
	w = Dx(cards->r) / 13;
	h = Dy(cards->r) / 4;
	if((m = initmouse(nil, screen)) == nil)
		sysfatal("initmouse: %r");
	a[RESIZE].c = m->resizec;
	a[MOUSE].c = m->c;
	a[MOUSE].v = &m->Mouse;
	if((kbd = initkeyboard(nil)) == nil)
		sysfatal("initkeyboard: %r");
	a[KEYBOARD].c = kbd->c;
	srand(truerand());
	for(j = 0; j < 52; j++)
		cardatloc[j] = j;
	cardatloc[13] = cardatloc[26] = cardatloc[39] = 0;
	while(j > 1){
		i = nrand(j--);
		locofcard[cardatloc[j]] = i;
		if(i != j){
			locofcard[cardatloc[i]] = j;
			b = cardatloc[i];
			cardatloc[i] = cardatloc[j];
			cardatloc[j] = b;
		}
	}
	sendul(m->resizec, 1);
	for(;;)
		switch(alt(a)){
		case RESIZE:
			from = to = -1;
			if(getwindow(display, Refnone) < 0)
				sysfatal("getwindow: %r");
			draw(screen, screen->r, bg, nil, ZP);
			o.x = screen->r.min.x + screen->r.max.x - 13 * w - 12 * GAP >> 1;
			o.y = screen->r.min.y + screen->r.max.y - 4 * h - 3 * GAP >> 1;
			for(i = 0; i < 52; i++)
				if(cardatloc[i]){
					draw(screen, rect(i), cards, nil, Pt(cardatloc[i] % 13 * w, cardatloc[i] / 13 * h));
					flushimage(display, 1);
					sleep(20);
				}
			string(screen, Pt(o.x, o.y - font->height), fg, ZP, font, s);
			flushimage(display, 1);
			break;
		case MOUSE:
			if(!m->buttons)
				break;
			if(m->buttons & 4){
				i = menuhit(3, m, &menu, nil);
				if(i >= 0 && i < nelem(cmd))
					sendul(kbd->c, *cmd[i]);
				break;
			}
			b = m->buttons;
			do readmouse(m); while(m->buttons);
			if(from >= 0)
				paint(bg);
			i = m->xy.x - o.x;
			j = m->xy.y - o.y;
			if(i < 0 || j < 0
			|| i % (w + GAP) >= w || j % (h + GAP) >= h
			|| (i /= w + GAP) >= 13 || (j /= h + GAP) >= 4){
				if(from >= 0){
					from = to = -1;
					flushimage(display, 1);
				}
				break;
			}
			i += j * 13;
			if(from < 0){
				if(cardatloc[i] % 13 == 1
				&& !cardatloc[0] | !cardatloc[13] | !cardatloc[26] | !cardatloc[39]){
						from = i;
						to = 0;
				}
				else if(cardatloc[i]){
					j = locofcard[cardatloc[i] - 1] + 1;
					if(j % 13 && !cardatloc[j]){
						from = i;
						to = j;
					}
				}
				if(from == i){
					if(b & 2)
						move();
					else{
						paint(fg);
						flushimage(display, 1);
					}
				}
				break;
			}
			if(cardatloc[i] || i % 13 && i != to || i % 13 == 0 && to){
				from = to = -1;
				flushimage(display, 1);
				break;
			}
			to = i;
			move();
			break;
		case KEYBOARD:
			switch(k){
			case ' ':
				if(from >= 0){
					paint(bg);
					move();
					break;
				}
			case 'h':
				if(from >= 0)
					paint(bg);
				i = j = from < 0 ? 53 : from;
				do{
					i = i == 53 ? 0 : i + 1;
					if(cardatloc[i] % 13 == 1 &&
					(!cardatloc[0] || !cardatloc[13] || !cardatloc[26] || !cardatloc[39])){
						from = i;
						to = 0;
						paint(fg);
						break;
					}
					if(cardatloc[i] % 13 > 1
					&& locofcard[cardatloc[i] - 1] % 13 < 12
					&& !cardatloc[locofcard[cardatloc[i] - 1] + 1]){
						from = i;
						to = locofcard[cardatloc[i] - 1] + 1;
						paint(fg);
						break;
					}
				}while(i != j);
				flushimage(display, 1);
				break;
			case 's':
				s[15] = s[15] == '9' ? 'A' : s[15] + 1;
				i = j = 0;
				if(cardatloc[i] % 13 == 1)
					do i++; while(cardatloc[i] == cardatloc[i - 1] + 1);
				while(i < 13){
					locofcard[j++] = cardatloc[i];
					cardatloc[i++] = 52;
				}
				if(cardatloc[i] % 13 == 1)
					do i++; while(cardatloc[i] == cardatloc[i - 1] + 1);
				while(i < 26){
					locofcard[j++] = cardatloc[i];
					cardatloc[i++] = 52;
				}
				if(cardatloc[i] % 13 == 1)
					do i++; while(cardatloc[i] == cardatloc[i - 1] + 1);
				while(i < 39){
					locofcard[j++] = cardatloc[i];
					cardatloc[i++] = 52;
				}
				if(cardatloc[i] % 13 == 1)
					do i++; while(cardatloc[i] == cardatloc[i - 1] + 1);
				while(i < 52){
					locofcard[j++] = cardatloc[i];
					cardatloc[i++] = 52;
				}
				while(j > 1){
					i = nrand(j--);
					from = locofcard[i];
					locofcard[i] = locofcard[j];
					locofcard[j] = from;
				}
				for(i = j = 0; i < 52; i++)
					if(cardatloc[i] == 52)
						cardatloc[i] = locofcard[j++];
				for(i = 0; i < 52; i++)
					locofcard[cardatloc[i]] = i;
				from = to = -1;
				sendul(m->resizec, 1);
				break;
			case Kesc:
				if((i = open("/dev/wctl", OWRITE)) >= 0){
					write(i, "hide", 4);
					close(i);
				}
				break;
			case Kdel: case 'q':
				threadexitsall(nil);
			}
			break;
		default:
			sysfatal("Murtis bene felas");
		}
}