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.