for (j = 0; j < board->height; j++) {
l += sprintf (buffer + l, "rem: \"");
for (i = 0; i < board->width; i++) {
- l += sprintf (buffer + l, "%c", getvalue (board, i, j));
+ l += sprintf (buffer + l, "%c", *getcell (board, i, j));
}
l += sprintf (buffer + l, "\"\n");
}
return block;
}
+int testvalidpos (board_t *board, block_t *block, int x, int y)
+{
+ int ret = 1;
+ if ((x - block->width / 2 < 0) || (x - block->width / 2 + block->width > board->width) ||
+ (y + block->height > board->height)) {
+ ret = 0;
+ } else {
+ 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 - block->width / 2 + i, y + j) != ' ') {
+ ret = 0;
+ }
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+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 - block->width / 2 + i, y + j) = '0' + block->color;
+ }
+ }
+ }
+}
+
/* vim: set ts=4 sw=4 et: */
#define getcell(b, x, y) ({ __typeof__ (b) _b = (b); int _x = (x), _y = (y);_b->tab + _x + _b->width * _y; })
-#define getvalue(b, x, y) ({ __typeof__ (b) _b = (b); int _x = (x), _y = (y); (_x >= 0) && (_x < _b->width) && (_y >= 0) && (_y < _b->height) ? *(getcell (_b, _x, _y)) : 0; })
-
block_t *initblock (int xsize, int ysize);
block_t *changeblock (block_t *dest, block_t *src);
block_t *rotateblock (block_t *block, int rot);
+int testvalidpos (board_t *board, block_t *block, int x, int y);
+
+void settleblock (board_t *board, block_t *block, int x, int y);
+
#endif /* __FUNCTION_H__ */
/* vim: set ts=4 sw=4 et: */
block_t *blocks = getblocks ("std", &nb_blocks);
int current = rand () % nb_blocks;
block_t *cblock = copyblock (blocks + current);
- int xblock = (board->width - cblock->width) / 2;
+ int xblock = board->width / 2;
int yblock = 0;
int next = rand () % nb_blocks;
VERBOSE (DEBUG, fprintf (stderr, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock));
int xboard = board->xoffset = xoffset + 1;
int yboard = board->yoffset = xoffset + 1;
int xhelp = xboard + xoffset + 1 + board->xsize;
- int xcursor = 1;
- int ycursor = 0;
int yhelp = yboard - 1;
int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
int ysave = yboard + (board->ysize - 1) / 2;
/* event loop */
int mode = 0;
int speed = 5000;
- int rot = 0;
+ int settle = 0;
int stop = 0;
struct timeval tend = {0, 0};
while (!stop) {
+ char msg[128] = {0};
- boardwindow (board);
- if (1) { /* not end of game */
- char msg[128] = {0};
- switch (mode) {
- case 0:
-freeblock (cblock);
-current = next;
-cblock = copyblock (blocks + current);
-xblock = (board->width - cblock->width) / 2;
-yblock = 0;
-next = rand () % nb_blocks;
-sprintf (msg, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock);
- halfdelay (0);
- //sprintf (msg, "Get ready player One");
- break;
- case 1:
- halfdelay (10);
- rotateblock (cblock, rot);
- if (isovertime (&tend)) {
+ switch (mode) {
+ case 0:
+ halfdelay (0);
+ sprintf (msg, "Get ready player One");
+ break;
+ case 1:
+ halfdelay (1);
+ if (tend.tv_sec && isovertime (&tend)) {
+ if (testvalidpos (board, cblock, xblock, yblock + 1)) {
yblock++;
- if (yblock + cblock->height >= board->height) {
- freeblock (cblock);
- current = next;
- cblock = copyblock (blocks + current);
- xblock = (board->width - cblock->width) / 2;
- yblock = 0;
- next = rand () % nb_blocks;
- }
- setendtime (&tend, speed);
+ } else {
+ settle = 1;
}
- displayblock (board, cblock, xblock, yblock);
- rot = 0;
-sprintf (msg, "%ld/%06ld\n", tend.tv_sec, tend.tv_usec);
- break;
+ setendtime (&tend, speed);
+ }
+ if (settle) {
+ settleblock (board, cblock, xblock, yblock);
+ freeblock (cblock);
+ current = next;
+ cblock = copyblock (blocks + current);
+ xblock = board->width / 2;
+ yblock = 0;
+ next = rand () % nb_blocks;
+ settle = 0;
+ }
+ if (!testvalidpos (board, cblock, xblock, yblock)) {
+ halfdelay (0);
+ mode = 2;
+ sprintf (msg, "End of game");
}
- msgwindow (msg, xmsg, ymsg, lmsg);
- } else {
- msgwindow ("End of game", xmsg, ymsg, lmsg);
+ break;
+ case 2:
+ freeblock (cblock);
+ cblock = NULL;
+ sprintf (msg, "Press q to quit");
+ }
+
+ msgwindow (msg, xmsg, ymsg, lmsg);
+ boardwindow (board);
+ if (mode == 1) {
+ displayblock (board, cblock, xblock, yblock);
}
int ch = getch ();
- switch (ch) {
- case KEY_ENTER:
- case '\n':
- case '\r':
- case 'c':
- yblock = board->height - cblock->height;
- break;
- case KEY_LEFT:
- case 'j':
- xblock--;
+ switch (mode) {
+ case 0:
break;
- case KEY_DOWN:
- case 'k':
- yblock++;
- break;
- case KEY_RIGHT:
- case 'l':
- xblock++;
+ case 1:
+ switch (ch) {
+ case KEY_ENTER:
+ case '\n':
+ case '\r':
+ case 'c':
+ while (testvalidpos (board, cblock, xblock, yblock + 1)) {
+ yblock++;
+ }
+ settle = 1;
+ break;
+ case KEY_LEFT:
+ case 'j':
+ if (testvalidpos (board, cblock, xblock - 1, yblock)) {
+ xblock--;
+ }
+ break;
+ case KEY_DOWN:
+ case 'k':
+ if (testvalidpos (board, cblock, xblock, yblock + 1)) {
+ yblock++;
+ } else {
+ settle = 1;
+ }
+ break;
+ case KEY_RIGHT:
+ case 'l':
+ if (testvalidpos (board, cblock, xblock + 1, yblock)) {
+ xblock++;
+ }
+ break;
+ case KEY_UP:
+ case ' ':
+ case 'i':
+ case 'o':
+ if (!testvalidpos (board, rotateblock (cblock, 1), xblock, yblock)) {
+ rotateblock (cblock, -1);
+ }
+ break;
+ case KEY_BACKSPACE:
+ case KEY_DELETE:
+ case 127:
+ case '\b':
+ case 'u':
+ if (!testvalidpos (board, rotateblock (cblock, -1), xblock, yblock)) {
+ rotateblock (cblock, 1);
+ }
+ break;
+ }
break;
- case KEY_UP:
- case ' ':
- case 'i':
- case 'o':
- rot = 1;
+ case 2:
break;
+ }
+ switch (ch) {
case 'p':
mode = (mode == 0) ? 1 : 0;
if (mode == 1) {
free (savename);
}
break;
- case KEY_BACKSPACE:
- case KEY_DELETE:
- case 127:
- case '\b':
- case 'u':
- rot = -1;
- break;
//case ERR:
//default:
}