free (block);
}
+block_t *mirrorblock (block_t *block, int dir)
+{
+ int i, j;
+ switch (dir % 2) {
+ case 0:
+ for (i = 0; i < block->width; i++) {
+ for (j = 0; j < block->height / 2; j++) {
+ char t = *getcell (block, i, j);
+ *getcell (block, i, j) = *getcell (block, i, block->height - 1 - j);
+ *getcell (block, i, block->height - 1 - j) = t;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < block->width / 2; i++) {
+ for (j = 0; j < block->height; j++) {
+ char t = *getcell (block, i, j);
+ *getcell (block, i, j) = *getcell (block, block->width - 1 - i, j);
+ *getcell (block, block->width - 1 - i, j) = t;
+ }
+ }
+ break;
+ }
+ return block;
+}
+
block_t *rotateblock (block_t *block, int rot)
{
int i, j;
CHECKALLOC (blocks->y);
blocks->block = (block_t **) calloc (nb, sizeof (block_t *));
CHECKALLOC (blocks->block);
+ blocks->settle = (int *) calloc (nb, sizeof (int));
+ CHECKALLOC (blocks->settle);
return (blocks);
}
void freeblocks (blocks_t *blocks)
{
- int i;
- for (i = 0; i < blocks->nb; i++) {
- freeblock (blocks->block[i]);
+ if (blocks) {
+ int i;
+ for (i = 0; i < blocks->nb; i++) {
+ freeblock (blocks->block[i]);
+ }
+ free (blocks->x);
+ free (blocks->y);
+ free (blocks->block);
+ free (blocks->settle);
}
- free (blocks->x);
- free (blocks->y);
- free (blocks->block);
free (blocks);
}
+int findnext (int i, int *tab, int n)
+{
+ int c = 0;
+ do {
+ i++;
+ if (i >= n) {
+ i = 0;
+ }
+ c++;
+ if (c > n) {
+ return -1;
+ }
+ } while (tab[i]);
+
+ return i;
+}
+
+int testposition (board_t *board, block_t *block, int x, int y)
+{
+ int i, j;
+
+ for (i = 0; i < block->width; i++) {
+ for (j = 0; j < block->height; j++) {
+ if (*getcell (block, i, j) != ' ') {
+ if (*getcell (board, x + i, y + j) != ' ') {
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+void settleblock (board_t *board, block_t *block, int x, int y)
+{
+ int i, j;
+
+ for (i = 0; i < block->width; i++) {
+ for (j = 0; j < block->height; j++) {
+ if (*getcell (block, i, j) != ' ') {
+ *getcell (board, x + i, y + j) = ' ' + block->color;
+ }
+ }
+ }
+}
+
/* vim: set ts=4 sw=4 et: */
"<j> Move left cursor\n"
"<k> Move down cursor\n"
"<l> Move right cursor\n"
+ "<m> Mirror horizontally \n"
"<o> Rotate piece right\n"
+ "<p> Mirror vertically \n"
"<u> Rotate piece left\n"
"<y> Yank next piece\n"
"<q> Quit\n"
n = 3;
break;
}
- bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (1 + n) * yoffset + n * hblock);
+ bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (n - 1) * yoffset + n * hblock);
VERBOSE (DEBUG, fprintf (stderr, "windows: %dx%d\n", xoffset + (xoffset + wblock) * (blocks->nb + n - 1) / n, (1 + n) * yoffset + n * hblock));
setscale (bench, scale);
for (i = 0; i < blocks->nb; i++) {
blocks->x[i] = xoffset + (xoffset + wblock) * (i / n) + (wblock - blocks->block[i]->width + 1) / 2;
- blocks->y[i] = yoffset + (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2;
+ blocks->y[i] = (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2;
}
/* init curses window */
curs_set (0);
start_color ();
- /* window positions */
+ /* window positions (board) */
int xboard = board->xoffset = xoffset + 1;
int yboard = board->yoffset = xoffset + 1;
- int xhelp = xboard + xoffset + 1 + board->xsize;
- int xcursor = board->width / 2;
- int ycursor = board->height / 2;
- int cursor = 0;
- int yhelp = yboard - 1;
int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
int ysave = yboard + (board->ysize - 1) / 2;
-
char *savename = NULL;
- /* help window */
+ /* cursor definition */
+ int cursor = 0;
+ int xcursor = (board->width - blocks->block[cursor]->width) / 2;
+ int ycursor = (board->height - blocks->block[cursor]->height) / 2;
+
+ /* window positions (bench) */
+ int xbench = bench->xoffset = xboard;
+ int ybench = bench->yoffset = yboard + board->ysize + 1 + yoffset;
+
+ /* window positions (help) */
+ int xhelp = xbench + bench->xsize + xoffset + 1;
+ int yhelp = yboard - 1;
int lhelp = helpwindow (help, xhelp, yhelp);
- /* window positions */
- int xblocks = bench->xoffset = xboard;
- int yblocks = bench->yoffset = max (yboard + board->ysize + 1, yhelp + lhelp) + yoffset + 1;
- int xmsg = xblocks;
- int ymsg = yblocks + yoffset + 2;
- int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
+ /* window positions (msg) */
+ int xmsg = xbench;
+ int ymsg = ybench + bench->ysize + yoffset + 1;
+ int lmsg = bench->xsize + strmaxlen (help, '\n') + xoffset + 1;
/* blocks positions */
- boardwindow (bench, 0);
+ boardwindow (bench, 1);
for (i = 0; i < blocks->nb; i++) {
displayblock (bench, blocks->block[i], blocks->x[i], blocks->y[i]);
}
while (!stop) {
boardwindow (board, 0);
- block_t *block = blocks->block[cursor];
- displayblock (board, block, xcursor, ycursor);
-
- if (1) { //if (!endofgame (board)) {
- // cursorwindow (board, xcursor, ycursor, mode);
+ block_t *block = NULL;
+ if (cursor >= 0) {
+ block = blocks->block[cursor];
+ displayblock (board, block, xcursor, ycursor);
+ msgwindow ("Can you solve this puzzle?", xmsg, ymsg, lmsg);
} else {
- msgwindow ("End of game", xmsg, ymsg, lmsg);
+ msgwindow ("Puzzle solved", xmsg, ymsg, lmsg);
}
int ch = getch ();
+
+ /* general controls */
+ switch (ch) {
+ case KEY_ESC:
+ case 'q':
+ stop = 1;
+ break;
+ case 's':
+ savename = savewindow (savelen, xsave, ysave);
+ if (savename != NULL) {
+ char *ptr = saveboard (board);
+ if (writedata (savename, ptr)) {
+ VERBOSE (WARNING, printf ("issue writing Board\n"));
+ }
+ free (ptr);
+ free (savename);
+ }
+ break;
+ }
+
+ /* test end of game */
+ if (cursor < 0) {
+ continue;
+ }
+
+ /* game controls */
switch (ch) {
case '\n':
case '\r':
case 'h':
+ if (testposition (board, block, xcursor, ycursor)) {
+ settleblock (board, block, xcursor, ycursor);
+ blocks->settle[cursor] = 1;
+ cursor = findnext (cursor, blocks->settle, blocks->nb);
+ }
break;
case KEY_UP:
case 'i':
- if (ycursor > - (block->height + 0) / 2) {
+ if (ycursor > - block->height / 2) {
ycursor--;
}
break;
case KEY_LEFT:
case 'j':
- if (xcursor > - (block->width + 0) / 2) {
+ if (xcursor > - block->width / 2) {
xcursor--;
}
break;
xcursor++;
}
break;
+ case 'm':
+ mirrorblock (block, 0);
+ break;
case KEY_DELETE:
case 127:
case 'o':
rotateblock (block, 1);
break;
- case KEY_ESC:
- case 'q':
- stop = 1;
- break;
- case 's':
- savename = savewindow (savelen, xsave, ysave);
- if (savename != NULL) {
- char *ptr = saveboard (board);
- if (writedata (savename, ptr)) {
- VERBOSE (WARNING, printf ("issue writing Board\n"));
- }
- free (ptr);
- free (savename);
- }
+ case 'p':
+ mirrorblock (block, 1);
break;
case KEY_BACKSPACE:
case '\b':
break;
case ' ':
case 'y':
- cursor++;
- if (cursor >= blocks->nb) {
- cursor = 0;
- }
- break;
+ cursor = findnext (cursor, blocks->settle, blocks->nb);
break;
- //case ERR:
- //default:
}
}
endwin ();
freeboard (board);
+ freeblocks (blocks);
return 0;
}