shithub: cflood

Download patch

ref: 24784c25acafe9837586ef877b6cc7960a880a83
parent: b503317e6c71100ce331e24715d8cc538781840b
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Tue Dec 18 17:48:03 EST 2012

games/cflood: restyle and add color reverse option

--- a/games/cflood.c
+++ b/games/cflood.c
@@ -3,12 +3,14 @@
 #include <draw.h>
 #include <event.h>
 
-enum {
+enum{
+	/* sid */
 	Ssmall,
 	Snormal,
 	Slarge,
 	Scustom,
 
+	/* state */
 	Tgame,
 	Twin,
 	Tfail,
@@ -21,8 +23,14 @@
 	ButtonSize = 32
 };
 
-static int sizes[] = {14, 21, 28, 1};
-static int turns[] = {25, 35, 50, 1};
+static int sizes[] = {
+	14, 21, 28, 1
+};
+
+static int turns[] = {
+	25, 35, 50, 1
+};
+
 static const ulong srccolors[NumColors] = {
 	0x6060a8ff,
 	0xf6f61dff,
@@ -31,6 +39,7 @@
 	0xf070a0ff,
 	0xdc4a20ff
 };
+
 static char *mstr[] = {
 	"14x14 / 25",
 	"25x25 / 35",
@@ -39,12 +48,13 @@
 	0
 };
 
-static int sid;
+static int inv;
 static int size;
-static int type;
-static int wait4click;
+static int sid;
+static int state;
+static int clickwait;
 static int turnsleft;
-static uchar *cells; // enough for maximal size
+static uchar *cells;
 static Image *colors[NumColors];
 static Rectangle buttons[NumColors];
 
@@ -52,58 +62,76 @@
 floodneighbours(uchar color, int x, int y);
 
 static void
-redraw(Image *screen) {
-	Rectangle r = screen->r;
-	draw(screen, r, display->white, nil, ZP);
-
+redraw(Image *screen)
+{
+	int i, x, y, w, h, csize, left;
+	Point p, sp, strsize;
+	const uchar *c;
+	Rectangle r;
 	char s[64];
-	if(type == Tgame)
+	Font *f;
+	Image *colora, *colorb;
+
+	colora = colorb = display->black;
+	if(inv)
+		colorb = display->white;
+	else
+		colora = display->white;
+
+	draw(screen, screen->r, colora, nil, ZP);
+
+	if(state == Tgame)
 		sprint(s, "%d", turnsleft);
-	else if(type == Twin)
-		sprint(s, "You won using %d turns (of %d)",
-			turns[sid]-turnsleft,
-			turns[sid]);
-	else if(type == Tfail)
+	else if(state == Twin)
+		sprint(s, "You won using %d turns (of %d)", turns[sid]-turnsleft, turns[sid]);
+	else if(state == Tfail)
 		sprint(s, "You failed");
-	Font *f = display->defaultfont;
-	Point strsize = stringsize(f, s);
 
-	const uchar *cell = &cells[0];
-	int w = Dx(r);
-	int h = Dy(r) - ButtonSize - 2 - strsize.y;
-	int c = (w < h ? w : h) / size;
-	w = c*size;
-	int left = r.min.x + (Dx(r) - w)/2;
+	f = display->defaultfont;
+	strsize = stringsize(f, s);
 
-	// cells
-	for(int x = left; x < left+size*c; x+=c) {
-		for(int y = r.min.y; y < r.min.y+size*c; y+=c) {
-			Rectangle r = Rect(x, y, x+c, y+c);
-			draw(screen, r, colors[*cell & ColorMask], nil, ZP);
-			cell++;
+	w = Dx(screen->r);
+	h = Dy(screen->r) - ButtonSize - 4 - strsize.y;
+	csize = (w < h ? w : h) / size;
+	w = size*csize;
+	left = screen->r.min.x + (Dx(screen->r) - w)/2;
+
+	/* cells */
+	c = cells;
+	for(x = 0; x < size; x++){
+		for(y = 0; y < size; y++){
+			r.min.x = left + x*csize;
+			r.min.y = screen->r.min.y + 2 + y*csize;
+			r.max.x = r.min.x + csize;
+			r.max.y = r.min.y + csize;
+			draw(screen, r, colors[*c & ColorMask], nil, ZP);
+			c++;
 		}
 	}
 
-	// buttons
-	int x = left + (w/2) - NumColors*ButtonSize/2;
-	int y = r.min.y + h + strsize.y;
-	for(int i = 0; i < NumColors; i++, x += ButtonSize) {
+	/* buttons */
+	x = left + (w - NumColors*ButtonSize)/2;
+	y = screen->r.min.y + h + strsize.y;
+	for(i = 0; i < NumColors; i++, x += ButtonSize){
 		buttons[i] = Rect(x, y, x+ButtonSize, y+ButtonSize);
 		draw(screen, buttons[i], colors[i], nil, ZP);
 	}
 
-	// caption
-	Point p = {left + w/2 - strsize.x/2, y - strsize.y};
-	Point sp = {0, 0};
-	string(screen, p, display->black, sp, f, s);
+	/* caption */
+	p.x = left + w/2 - strsize.x/2;
+	p.y = y - strsize.y;
+	sp.x = sp.y = 0;
+	string(screen, p, colorb, sp, f, s);
 
 	flushimage(display, 1);
 }
 
 static void
-floodrecurse(uchar color, int x, int y) {
-	uchar *c = &cells[x + y*size];
-	if((*c & Flood) == 0 && (*c & ColorMask) == color) {
+floodrecurse(uchar color, int x, int y)
+{
+	uchar *c;
+	c = &cells[x + y*size];
+	if((*c & Flood) == 0 && (*c & ColorMask) == color){
 		*c = color | Flood;
 		floodneighbours(color, x, y);
 	}
@@ -110,7 +138,8 @@
 }
 
 static void
-floodneighbours(uchar color, int x, int y) {
+floodneighbours(uchar color, int x, int y)
+{
 	cells[x + y*size] = color | Flood;
 
 	if(x > 0)
@@ -124,21 +153,29 @@
 }
 
 static int
-reflood(uchar color) {
+reflood(uchar color)
+{
+	int n, x, y;
+
 	color &= ColorMask;
 
-	int n = 0;
-	for(int x = 0; x < size; x++)
-		for(int y = 0; y < size; y++)
-			if(cells[x + y*size] & Flood) {
+	n = 0;
+	for(x = 0; x < size; x++){
+		for(y = 0; y < size; y++){
+			if(cells[x + y*size] & Flood){
 				floodneighbours(color, x, y);
 				n++;
 			}
+		}
+	}
 	return n;
 }
 
 static void
-flood(uchar color) {
+flood(uchar color)
+{
+	int n;
+
 	if((cells[0] & Flood) != 0 && (cells[0] & ColorMask) == color)
 		return;
 
@@ -146,14 +183,14 @@
 		return;
 
 	turnsleft--;
-	int n = reflood(color);
+	n = reflood(color);
 
-	if(n == size*size) {
-		type = Twin;
-		wait4click = 1;
-	} else if(!turnsleft) {
-		type = Tfail;
-		wait4click = 1;
+	if(n == size*size){
+		state = Twin;
+		clickwait = 1;
+	}else if(!turnsleft){
+		state = Tfail;
+		clickwait = 1;
 	}
 
 	redraw(screen);
@@ -160,19 +197,23 @@
 }
 
 static void
-newgame(int sid) {
-	type = Tgame;
+newgame(int sid)
+{
+	uchar *c;
+	int i, maxsize;
+
+	state = Tgame;
 	size = sizes[sid];
 	turnsleft = turns[sid];
 
-	if(cells == nil) {
-		int maxsize = size > sizes[Slarge] ? size : sizes[Slarge];
+	if(cells == nil){
+		maxsize = (size > sizes[Slarge]) ? size : sizes[Slarge];
 		cells = malloc(maxsize*maxsize);
 	}
 
-	// randomize
-	uchar *c = &cells[0];
-	for(int i = 0; i < size*size; i++) {
+	/* randomize */
+	c = cells;
+	for(i = 0; i < size*size; i++){
 		*c++ = nrand(NumColors);
 	}
 
@@ -196,14 +237,19 @@
 	exits("usage");
 }
 
-void main(int argc, char** argv) {
+void main(int argc, char** argv)
+{
+	int key, p, i, oldbuttons;
+	Event e;
+	Mouse m;
 	Menu menu;
+	Rectangle r;
 
 	if(initdraw(0, 0, "cflood") < 0)
 		sysfatal("initdraw failed");
 
-	Rectangle r = Rect(0, 0, 1, 1);
-	for(int i = 0; i < NumColors; i++)
+	r = Rect(0, 0, 1, 1);
+	for(i = 0; i < NumColors; i++)
 		colors[i] = allocimage(display, r, CMAP8, 1, srccolors[i]);
 
 	einit(Emouse);
@@ -211,8 +257,12 @@
 	menu.lasthit = 0;
 	srand(time(0));
 
-	sid = Snormal;
-	ARGBEGIN {
+	sid = Ssmall;
+	inv = 0;
+	ARGBEGIN{
+	case 'b':
+		inv = 1;
+		break;
 	case 's':
 		sid = Scustom;
 		sizes[sid] = atoi(ARGF());
@@ -227,26 +277,25 @@
 
 	newgame(sid);
 
-	for(int mold = 0;;) {
-		Event e;
-		int key = event(&e);
-		Mouse m = e.mouse;
+	for(oldbuttons = 0;;){
+		key = event(&e);
+		m = e.mouse;
 
 		if(key != Emouse)
 			continue;
 
-		if(m.buttons & 4) {
-			int p = emenuhit(3, &m, &menu);
+		if(m.buttons & 4){
+			p = emenuhit(3, &m, &menu);
 			if(p >= Ssmall && p <= Slarge)
 				newgame(sid = p);
 			else if(p > 0)
 				break;
-		} else if(wait4click && !mold && m.buttons != mold) {
-			wait4click = 0;
+		}else if(clickwait && !oldbuttons && m.buttons){
+			clickwait = 0;
 			newgame(sid);
-		} else if(m.buttons & 1) {
-			for(int i = 0; i < NumColors; i++) {
-				if(ptinrect(m.xy, buttons[i])) {
+		}else if(m.buttons & 1){
+			for(i = 0; i < NumColors; i++){
+				if(ptinrect(m.xy, buttons[i])){
 					flood(i);
 					break;
 				}
@@ -253,6 +302,6 @@
 			}
 		}
 
-		mold = m.buttons;
+		oldbuttons = m.buttons;
 	}
 }
--- a/games/cflood.man
+++ b/games/cflood.man
@@ -4,6 +4,9 @@
 .SH SYNOPSIS
 .B cflood
 [
+.I -b
+]
+[
 .I -s size
 ]
 [
@@ -14,6 +17,10 @@
 is a game in which player must fill an area with one color in limited number of turns.
 .PP
 The
+.B -b
+option reverses the color scheme for text and background.
+.PP
+The
 .B -s
 option sets the size of the area to
 .IR size
@@ -31,4 +38,4 @@
 .SH SOURCE
 http://bitbucket.org/ftrvxmtrx/p9
 .SH BUGS
-Probably.
+Of course.