}
}
-void scorewindow (int xoffset, int yoffset, int length, int score, int level)
+void scorewindow (int xoffset, int yoffset, int length, int score, int score2, int level)
{
setcolor (black_gray);
- _dobound (length + 9, 2, xoffset, yoffset);
+ _dobound ((score2 < 0) ? length + 10 : 2 * (length + 1) + 11, 2, xoffset, yoffset);
setcolor (gray_black);
char fmt[12], msg[32];
- sprintf (fmt, "%% %dd", length);
- sprintf (msg, " score: ");
- sprintf (msg + strlen (msg), fmt, score);
+ if (score2 < 0) {
+ sprintf (fmt, " %% %dd", length);
+ sprintf (msg, " score: ");
+ sprintf (msg + strlen (msg), fmt, score);
+ } else {
+ sprintf (fmt, " %%-%dd", length);
+ sprintf (msg, fmt, score);
+ sprintf (msg + strlen (msg), " score ");
+ sprintf (fmt, "%% %dd ", length);
+ sprintf (msg + strlen (msg), fmt, score2);
+ }
mvaddstr (yoffset, xoffset, msg);
sprintf (msg, " level: % 3d", level);
"<s> Save file\n"
;
+char *help2 =
+ "<a> or <u> Rotate right tile\n"
+ "<d> or <l> Move right tile\n"
+ "<e> or <o> Rotate left tile\n"
+ "<s> or <k> Move down tile\n"
+ "<p> Pause\n"
+ "<q> or <j> Move left tile\n"
+ "<z> or <i> Put down tile\n"
+ "<escape> Quit\n"
+ ;
+
int usage (int ret)
{
FILE *fd = ret ? stderr : stdout;
block_t *drawblock (board_t *board, block_t *blocks, int nb_blocks, block_t *cblock, int *current, int *xblock, int *yblock, int *next)
{
- /* clean block and get next */
- if (cblock) {
- freeblock (cblock);
- *current = *next;
- *next = rand () % nb_blocks;
- }
+ freeblock (cblock);
- /* init state */
- if (*current == -1) {
- *current = rand () % nb_blocks;
- }
- if (*next == -1) {
+ /* if not restarting a saved game */
+ if (cblock == NULL) {
+ if (*current == -1) {
+ *current = rand () % nb_blocks;
+ }
+ if (*next == -1) {
+ *next = rand () % nb_blocks;
+ }
+ } else {
+ *current = *next;
*next = rand () % nb_blocks;
}
switch (c) {
case 'c':
chrono = 1;
+ multi = 0;
break;
case 'f':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
case 'm':
multi = 1;
filename = NULL;
+ chrono = 0;
break;
case 's':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
board_t *board = NULL;
board_t *board2 = NULL;
int current = -1;
+ int current2 = -1;
int lines = 0;
+ int lines2 = 0;
int next = -1;
int score = 0;
+ int score2 = (multi) ? 0 : -1;
/* read file */
if (filename) {
/* get first bloc */
int xblock, yblock;
block_t *cblock = drawblock (board, blocks, nb_blocks, NULL, ¤t, &xblock, &yblock, &next);
- VERBOSE (DEBUG, fprintf (stderr, "%d/%d: (%d, %d)\n", current, nb_blocks, xblock, yblock));
+ int xblock2, yblock2;
+ block_t *cblock2 = NULL;
+ if (multi) {
+ cblock2 = drawblock (board2, blocks, nb_blocks, NULL, ¤t2, &xblock2, &yblock2, &next);
+ }
/* init curses window */
initscr ();
char *savename = NULL;
/* help window */
- int lhelp = helpwindow (help, xhelp, yhelp);
+ int lhelp = helpwindow ((multi) ? help2 : help, xhelp, yhelp);
/* window positions */
int xmsg = xboard;
int ymsg = max (yboard + xoffset + 1 + board->ysize, yhelp + lhelp + yoffset);
- int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
+ int lmsg = xhelp - xmsg + strmaxlen (multi ? help2 : help, '\n');
/* resize windows for multiplayer */
if (board2) {
- board2->xoffset = xhelp + strmaxlen (help, '\n') + xoffset + 1;
+ board2->xoffset = xhelp + strmaxlen (help2, '\n') + xoffset + 1;
board2->yoffset = yboard;
- nextblock->xoffset += (nbdigit + 1) / 2;
+ nextblock->xoffset = xscore + (strmaxlen (help2, '\n') - nextblock->xsize - 2) / 2;
+ xscore += (strmaxlen (help2, '\n') - 11 - 2 * (nbdigit + 1) - 2) / 2;
lmsg += xhelp - xmsg;
}
/* event loop */
int mode = -1;
int settle = 0;
+ int settle2 = 0;
int speed = 5000;
float chronoratio = 5.0;
int stop = 0;
struct timeval blockend = {0, 0};
+ struct timeval blockend2 = {0, 0};
struct timeval lineend = {0, 0};
while (!stop) {
char msg[128] = {0};
case -1:
boardwindow (nextblock, 1);
displayblock (nextblock, blocks + current, -1, -1);
- sprintf (msg, "Get ready player One. Press <s> to start");
+ sprintf (msg, (multi) ? "Get ready players." : "Get ready player One.");
+ sprintf (msg + strlen (msg), " Press <s> to start");
break;
case 0:
boardwindow (nextblock, 1);
}
setendtime (&blockend, speed);
}
+ if (multi && blockend2.tv_sec && isovertime (&blockend2)) {
+ if (testvalidpos (board2, cblock2, xblock2, yblock2 + 1)) {
+ yblock2++;
+ } else {
+ settle2 = 1;
+ }
+ setendtime (&blockend2, speed);
+ }
+
+ /* Player one */
if (settle) {
settleblock (board, cblock, xblock, yblock);
}
}
if (settle) {
if (!testvalidpos (board, blocks + next , board->width / 2, 0)) {
- sprintf (msg, "To bad, you loose. Score is %d", score);
+ if (multi) {
+ sprintf (msg, "To bad, player One looses. Score is %d / %d", score, score2);
+ } else {
+ sprintf (msg, "To bad, you loose. Score is %d", score);
+ }
mode = 2;
} else {
cblock = drawblock (board, blocks, nb_blocks, cblock, ¤t, &xblock, &yblock, &next);
}
settle = 0;
}
+
+ /* Player two */
+ if (multi) {
+ if (settle2) {
+ settleblock (board2, cblock2, xblock2, yblock2);
+ }
+ int nblines2 = checkline (board2, &score2, &lines2);
+ if (nblines2) {
+ while (nblines2-- > 0) {
+ boardwindow (board2, 0);
+ stackboard (board2);
+ usleep ((200 + 2000 / (lines / 10 + 1)) * 100);
+ refresh ();
+ }
+ }
+ if (settle2) {
+ if (!testvalidpos (board2, blocks + next , board2->width / 2, 0)) {
+ sprintf (msg, "To bad, player Two looses. Score is %d / %d", score, score2);
+ mode = 2;
+ } else {
+ cblock2 = drawblock (board2, blocks, nb_blocks, cblock2, ¤t2, &xblock2, &yblock2, &next);
+ }
+ settle2 = 0;
+ }
+ }
break;
case 2:
freeblock (cblock);
+ freeblock (cblock2);
cblock = NULL;
- sprintf (msg, "End of game. Press <q> to quit");
+ cblock2 = NULL;
+ if (multi) {
+ sprintf (msg, "End of game. Press <escape> to quit");
+ } else {
+ sprintf (msg, "End of game. Press <q> to quit");
+ }
}
if (*msg) {
if (multi) {
boardwindow (board2, 0);
}
- scorewindow (xscore, yscore, nbdigit, score, (lines / 10) + 1);
+ scorewindow (xscore, yscore, nbdigit, score, score2, (lines / 10) + 1);
int newspeed = 10 + 4900 / (lines / 10 + 1);
if (newspeed != speed) {
speed = newspeed;
setendtime (&blockend, speed);
+ setendtime (&blockend2, speed);
if (chrono) {
setendtime (&lineend, chronoratio * speed);
}
}
if (mode == 1) {
displayblock (board, cblock, xblock, yblock);
+ if (multi) {
+ displayblock (board2, cblock2, xblock2, yblock2);
+ }
}
int ch = getch ();
break;
case 1:
switch (ch) {
+ case 'a':
+ if (!testvalidpos (board2, rotateblock (cblock2, -1), xblock2, yblock2)) {
+ rotateblock (cblock2, 1);
+ }
+ break;
+ case 'e':
+ if (!testvalidpos (board2, rotateblock (cblock2, 1), xblock2, yblock2)) {
+ rotateblock (cblock2, -1);
+ }
+ break;
case KEY_UP:
case 'i':
while (testvalidpos (board, cblock, xblock, yblock + 1)) {
}
settle = 1;
break;
+ case 'd':
+ if (testvalidpos (board2, cblock2, xblock2 + 1, yblock2)) {
+ xblock2++;
+ }
+ break;
case KEY_LEFT:
case 'j':
if (testvalidpos (board, cblock, xblock - 1, yblock)) {
rotateblock (cblock, -1);
}
break;
+ case 'q':
+ if (multi) {
+ if (testvalidpos (board2, cblock2, xblock2 - 1, yblock2)) {
+ xblock2--;
+ }
+ }
+ break;
+ case 's':
+ if (multi) {
+ if (testvalidpos (board2, cblock2, xblock2, yblock2 + 1)) {
+ yblock2++;
+ } else {
+ settle2 = 1;
+ }
+ }
+ break;
case KEY_BACKSPACE:
case KEY_DELETE:
case 127:
rotateblock (cblock, 1);
}
break;
+ case 'z':
+ while (testvalidpos (board2, cblock2, xblock2, yblock2 + 1)) {
+ yblock2++;
+ }
+ settle2 = 1;
}
break;
case 2:
break;
}
break;
- case KEY_ESC:
case 'q':
+ if (multi) {
+ break;
+ }
+ /* fall through */
+ case KEY_ESC:
stop = 1;
break;
case 's':
+ if (multi) {
+ break;
+ }
savename = savewindow (savelen, xsave, ysave);
if (savename != NULL) {
board->current = current;
endwin ();
freeblock (cblock);
+ freeblock (cblock2);
freeboard (nextblock);
freeboard (board);
+ freeboard (board2);
return 0;
}