From: Laurent Mazet Date: Sun, 4 Aug 2024 21:12:26 +0000 (+0200) Subject: split main function X-Git-Tag: v1.3~5^2~5 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=147fdc57827ed6331b95d73937ad2da5d0fb4631;p=tetris.git split main function --- diff --git a/constant.c b/constant.c index aa9c063..604fd50 100644 --- a/constant.c +++ b/constant.c @@ -1,3 +1,5 @@ +#define __CONSTANT_C__ + #include #include @@ -5,6 +7,23 @@ #include "constant.h" +/* constants */ + +int height = 20; +int minwidth = 8; +int width = 10; +int maxwidth = 15; + +int nbdigit = 5; +int maxscor = 100000; +int nbholes = 2; + +int savelen = 12; +int xoffset = 1; +int yoffset = 1; + +/* boards */ + #define _nb_blocks_std 7 block_t _blocks_std[_nb_blocks_std] = { @@ -29,5 +48,4 @@ block_t *getblocks (char *name, int *nb) return pt; } - /* vim: set ts=4 sw=4 et: */ diff --git a/constant.h b/constant.h index b31eb6f..9147046 100644 --- a/constant.h +++ b/constant.h @@ -3,6 +3,27 @@ #include "type.h" +/* global constants */ + +#ifndef __CONSTANT_C__ + +extern int height; +extern int minwidth; +extern int width; +extern int maxwidth; + +extern int nbdigit; +extern int maxscor; +extern int nbholes; + +extern int savelen; +extern int xoffset; +extern int yoffset; + +#endif /* __CONSTANT_C__ */ + +/* block definitions */ + block_t *getblocks (char *name, int *nb); #endif /* __CONSTANT_H__ */ diff --git a/oneplayer.c b/oneplayer.c new file mode 100644 index 0000000..3270377 --- /dev/null +++ b/oneplayer.c @@ -0,0 +1,312 @@ +#include +#include +#include + +#include "constant.h" +#include "debug.h" +#include "display.h" +#include "function.h" +#include "time.h" +#include "type.h" + +static char *help = + " Put down tile\n" + " Move left tile\n" + " Move down tile\n" + " Move right tile\n" + " Rotate left tile\n" + "

Pause\n" + " Quit\n" + " Rotate right tile\n" + " Save file\n" + ; + +/* main function for one player*/ +int oneplayer (int width, int height, int scale, int chrono, char *filename) +{ + + /* init all variables */ + board_t *board = NULL; + int current = -1; + int lines = 0; + int next = -1; + int score = 0; + + /* read file */ + if (filename) { + char *buffer = readdata (filename); + if (buffer == NULL) { + VERBOSE (ERROR, fprintf (stderr, "can't read file (%s)\n", filename)); + return 1; + } + board = loadboard (buffer); + free (buffer); + if (board == NULL) { + VERBOSE (ERROR, fprintf (stderr, "incorrect file (%s)\n", filename)); + return 1; + } + current = board->current; + lines = board->lines; + next = board->next; + score = board->score; + } else { + board = initboard (width, height); + } + setscale (board, scale); + + /* get blocks */ + int nb_blocks = 0; + block_t *blocks = getblocks ("std", &nb_blocks); + board_t *nextblock = initboard (maxblockwidth (blocks, nb_blocks) + 2, + maxblockheight (blocks, nb_blocks) + 2); + setscale (nextblock, scale); + + /* init seed */ + newseed (); + + /* get first bloc */ + int xblock, yblock; + block_t *cblock = drawblock (board, blocks, nb_blocks, NULL, ¤t, &xblock, &yblock, &next); + + /* init curses window */ + initscr (); + noecho (); + cbreak (); + nonl (); + keypad (stdscr, TRUE); + curs_set (0); + start_color (); + + /* window positions */ + int xboard = board->xoffset = xoffset + 1; + int yboard = board->yoffset = xoffset + 1; + int xscore = xboard + xoffset + 2 + board->xsize; + int yscore = yboard; + nextblock->xoffset = xscore + (9 + nbdigit + 1 - nextblock->xsize) / 2; + int ynext = nextblock->yoffset = yscore + 1 + 2 + yoffset; + int xhelp = xscore - 1; + int yhelp = ynext + nextblock->ysize + yoffset; + int xsave = max (xboard + (board->xsize - savelen) / 2, 1); + int ysave = yboard + (board->ysize - 1) / 2; + char *savename = NULL; + + /* help window */ + int lhelp = helpwindow (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'); + + /* event loop */ + int mode = -1; + int settle = 0; + int speed = 5000; + float chronoratio = 5.0; + int stop = 0; + timeval_t blockend = {0, 0}; + timeval_t lineend = {0, 0}; + while (!stop) { + char msg[128] = {0}; + msgwindow (msg, xmsg, ymsg, lmsg); + + switch (mode) { + case -1: + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + current, -1, -1); + sprintf (msg, "Get ready player One. Press to start"); + break; + case 0: + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + current, -1, -1); + sprintf (msg, "Game in pause. Pause

to continue"); + break; + case 1: + halfdelay (1); + + if (blockend.tv_sec && isovertime (&blockend)) { + if (testvalidpos (board, cblock, xblock, yblock + 1)) { + yblock++; + } else { + settle = 1; + } + setendtime (&blockend, speed); + } + + if (settle) { + settleblock (board, cblock, xblock, yblock); + } + int nblines = checkline (board, &score, &lines); + if (nblines) { + while (nblines-- > 0) { + boardwindow (board, 0); + stackboard (board); + msleep (20 + 200 / (lines / 10 + 1)); + refresh (); + } + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } + } else if (chrono && lineend.tv_sec && isovertime (&lineend)) { + if (!testvalidpos (board, cblock, xblock, yblock + 1)) { + settleblock (board, cblock, xblock, yblock); + settle = 1; + } + int isempty = addline (board, nbholes); + if (!isempty) { + sprintf (msg, "Shame, you loose. Score is %d", score); + mode = 2; + settle = 0; + } + setendtime (&lineend, chronoratio * speed); + } + if (settle) { + if (!testvalidpos (board, blocks + next , board->width / 2, 0)) { + sprintf (msg, "To bad, you loose. Score is %d", score); + mode = 2; + } else { + cblock = drawblock (board, blocks, nb_blocks, cblock, ¤t, &xblock, &yblock, &next); + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + next, -1, -1); + } + settle = 0; + } + + break; + case 2: + freeblock (cblock); + cblock = NULL; + sprintf (msg, "End of game. Press to quit"); + } + + if (*msg) { + halfdelay (0); + msgwindow (msg, xmsg, ymsg, lmsg); + msleep (800); + } + + boardwindow (board, 0); + scorewindow (xscore, yscore, nbdigit, score, -1, (lines / 10) + 1); + int newspeed = 10 + 4900 / (lines / 10 + 1); + if (newspeed != speed) { + speed = newspeed; + setendtime (&blockend, speed); + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } + } + if (mode == 1) { + displayblock (board, cblock, xblock, yblock); + } + + int ch = getch (); + switch (mode) { + case -1: + switch (ch) { + case 's': + mode = 0; + ch = 'p'; + break; + } + break; + case 1: + switch (ch) { + case KEY_UP: + case 'i': + 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_ENTER: + case '\n': + case '\r': + 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 ' ': + case 'u': + if (!testvalidpos (board, rotateblock (cblock, -1), xblock, yblock)) { + rotateblock (cblock, 1); + } + break; + } + break; + case 2: + break; + } + switch (ch) { + case 'p': + switch (mode) { + case 0: + mode = 1; + setendtime (&blockend, speed); + if (chrono) { + setendtime (&lineend, chronoratio * speed); + } + break; + case 1: + mode = 0; + break; + } + break; + case 'q': + case KEY_ESC: + stop = 1; + break; + case 's': + savename = savewindow (savelen, xsave, ysave); + if (savename != NULL) { + board->current = current; + board->lines = lines; + board->next = next; + board->score = score; + char *ptr = saveboard (board); + if (writedata (savename, ptr)) { + VERBOSE (WARNING, printf ("issue writing Board\n")); + } + free (ptr); + free (savename); + } + break; + //case ERR: + //default: + } + } + + endwin (); + + freeblock (cblock); + freeboard (nextblock); + freeboard (board); + + return 0; +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/oneplayer.h b/oneplayer.h new file mode 100644 index 0000000..cbf130c --- /dev/null +++ b/oneplayer.h @@ -0,0 +1,6 @@ +#ifndef __ONEPLAYER_H__ +#define __ONEPLAYER_H__ + +int oneplayer (int width, int height, int scale, int chrono, char *filename); + +#endif /* __ONEPLAYER_H__ */ diff --git a/tetris.c b/tetris.c index 756a73e..3dcd3c5 100644 --- a/tetris.c +++ b/tetris.c @@ -1,8 +1,8 @@ /* depend: */ /* cflags: */ -/* linker: block.o color.c constant.o debug.o display.o function.o time.o -lcurses */ -/* doslnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdc~1 */ -/* winlnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdcurses */ +/* linker: block.o color.c constant.o debug.o display.o function.o oneplayer.o time.o twoplayers.o -lcurses */ +/* doslnk: block.o color.c constant.o debug.o display.o function.o oneplayer.o time.o twoplayers.o -lpdc~1 */ +/* winlnk: block.o color.c constant.o debug.o display.o function.o oneplayer.o time.o twoplayers.o -lpdcurses */ #include #include @@ -13,8 +13,10 @@ #include "debug.h" #include "display.h" #include "function.h" +#include "oneplayer.h" #include "time.h" #include "type.h" +#include "twoplayers.h" /* static variables */ char *progname = NULL; @@ -25,42 +27,6 @@ char *filename = NULL; int multi = 0; int scale = 1; -int height = 20; -int minwidth = 8; -int width = 10; -int maxwidth = 15; - -int nbdigit = 5; -int maxscor = 100000; -int nbholes = 2; - -int savelen = 12; -int xoffset = 1; -int yoffset = 1; - -char *help = - " Put down tile\n" - " Move left tile\n" - " Move down tile\n" - " Move right tile\n" - " Rotate left tile\n" - "

Pause\n" - " Quit\n" - " Rotate right tile\n" - " Save file\n" - ; - -char *help2 = - " or Rotate right tile\n" - " or Move right tile\n" - " or Rotate left tile\n" - " or Move down tile\n" - "

Pause\n" - " or Move left tile\n" - " or Put down tile\n" - " Quit\n" - ; - int usage (int ret) { FILE *fd = ret ? stderr : stdout; @@ -157,408 +123,15 @@ int main (int argc, char *argv[]) return 1; } - /* init all variables */ - 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) { - char *buffer = readdata (filename); - if (buffer == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't read file (%s)\n", filename)); - return 1; - } - board = loadboard (buffer); - free (buffer); - if (board == NULL) { - VERBOSE (ERROR, fprintf (stderr, "incorrect file (%s)\n", filename)); - return 1; - } - current = board->current; - lines = board->lines; - next = board->next; - score = board->score; - } else { - board = initboard (width, height); - if (multi) { - board2 = initboard (width, height); - } - } - setscale (board, scale); - if (multi) { - setscale (board2, scale); - } - - /* get blocks */ - int nb_blocks = 0; - block_t *blocks = getblocks ("std", &nb_blocks); - board_t *nextblock = initboard (maxblockwidth (blocks, nb_blocks) + 2, - maxblockheight (blocks, nb_blocks) + 2); - setscale (nextblock, scale); - - /* init seed */ - newseed (); - - /* get first bloc */ - int xblock, yblock; - block_t *cblock = drawblock (board, blocks, nb_blocks, NULL, ¤t, &xblock, &yblock, &next); - int xblock2, yblock2; - block_t *cblock2 = NULL; - if (multi) { - cblock2 = drawblock (board2, blocks, nb_blocks, NULL, ¤t2, &xblock2, &yblock2, &next); - } - - /* init curses window */ - initscr (); - noecho (); - cbreak (); - nonl (); - keypad (stdscr, TRUE); - curs_set (0); - start_color (); - - /* window positions */ - int xboard = board->xoffset = xoffset + 1; - int yboard = board->yoffset = xoffset + 1; - int xscore = xboard + xoffset + 2 + board->xsize; - int yscore = yboard; - nextblock->xoffset = xscore + (9 + nbdigit + 1 - nextblock->xsize) / 2; - int ynext = nextblock->yoffset = yscore + 1 + 2 + yoffset; - int xhelp = xscore - 1; - int yhelp = ynext + nextblock->ysize + yoffset; - int xsave = max (xboard + (board->xsize - savelen) / 2, 1); - int ysave = yboard + (board->ysize - 1) / 2; - char *savename = NULL; - - /* help window */ - 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 (multi ? help2 : help, '\n'); - - /* resize windows for multiplayer */ - if (board2) { - board2->xoffset = xhelp + strmaxlen (help2, '\n') + xoffset + 1; - board2->yoffset = yboard; - 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; - timeval_t blockend = {0, 0}; - timeval_t blockend2 = {0, 0}; - timeval_t lineend = {0, 0}; - while (!stop) { - char msg[128] = {0}; - msgwindow (msg, xmsg, ymsg, lmsg); - - switch (mode) { - case -1: - boardwindow (nextblock, 1); - displayblock (nextblock, blocks + current, -1, -1); - sprintf (msg, (multi) ? "Get ready players." : "Get ready player One."); - sprintf (msg + strlen (msg), " Press to start"); - break; - case 0: - boardwindow (nextblock, 1); - displayblock (nextblock, blocks + current, -1, -1); - sprintf (msg, "Game in pause. Pause

to continue"); - break; - case 1: - halfdelay (1); - if (blockend.tv_sec && isovertime (&blockend)) { - if (testvalidpos (board, cblock, xblock, yblock + 1)) { - yblock++; - } else { - settle = 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); - } - int nblines = checkline (board, &score, &lines); - if (nblines) { - while (nblines-- > 0) { - boardwindow (board, 0); - stackboard (board); - msleep (20 + 200 / (lines / 10 + 1)); - refresh (); - } - if (chrono) { - setendtime (&lineend, chronoratio * speed); - } - } else if (chrono && lineend.tv_sec && isovertime (&lineend)) { - if (!testvalidpos (board, cblock, xblock, yblock + 1)) { - settleblock (board, cblock, xblock, yblock); - settle = 1; - } - int isempty = addline (board, nbholes); - if (!isempty) { - sprintf (msg, "Shame, you loose. Score is %d", score); - mode = 2; - settle = 0; - } - setendtime (&lineend, chronoratio * speed); - } - if (settle) { - if (!testvalidpos (board, blocks + next , board->width / 2, 0)) { - 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); - boardwindow (nextblock, 1); - displayblock (nextblock, blocks + next, -1, -1); - } - 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); - msleep (20 + 200 / (lines / 10 + 1)); - 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; - cblock2 = NULL; - if (multi) { - sprintf (msg, "End of game. Press to quit"); - } else { - sprintf (msg, "End of game. Press to quit"); - } - } - - if (*msg) { - halfdelay (0); - msgwindow (msg, xmsg, ymsg, lmsg); - msleep (800); - } - - boardwindow (board, 0); - if (multi) { - boardwindow (board2, 0); - } - 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 (); - switch (mode) { - case -1: - switch (ch) { - case 's': - mode = 0; - ch = 'p'; - break; - } - 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)) { - yblock++; - } - 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)) { - 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_ENTER: - case '\n': - case '\r': - case 'o': - if (!testvalidpos (board, rotateblock (cblock, 1), xblock, 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: - case '\b': - case ' ': - case 'u': - if (!testvalidpos (board, rotateblock (cblock, -1), xblock, yblock)) { - rotateblock (cblock, 1); - } - break; - case 'z': - while (testvalidpos (board2, cblock2, xblock2, yblock2 + 1)) { - yblock2++; - } - settle2 = 1; - } - break; - case 2: - break; - } - switch (ch) { - case 'p': - switch (mode) { - case 0: - mode = 1; - setendtime (&blockend, speed); - if (chrono) { - setendtime (&lineend, chronoratio * speed); - } - break; - case 1: - mode = 0; - break; - } - break; - 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; - board->lines = lines; - board->next = next; - board->score = score; - char *ptr = saveboard (board); - if (writedata (savename, ptr)) { - VERBOSE (WARNING, printf ("issue writing Board\n")); - } - free (ptr); - free (savename); - } - break; - //case ERR: - //default: - } + switch (multi) { + case 0: + return oneplayer (width, height, scale, chrono, filename); + break; + case 1: + return twoplayers (width, height, scale); + break; } - endwin (); - - freeblock (cblock); - freeblock (cblock2); - freeboard (nextblock); - freeboard (board); - freeboard (board2); - return 0; } diff --git a/twoplayers.c b/twoplayers.c new file mode 100644 index 0000000..c9dadd1 --- /dev/null +++ b/twoplayers.c @@ -0,0 +1,334 @@ +#include +#include +#include + +#include "constant.h" +#include "debug.h" +#include "display.h" +#include "function.h" +#include "time.h" +#include "type.h" + +static char *help = + " or Rotate right tile\n" + " or Move right tile\n" + " or Rotate left tile\n" + " or Move down tile\n" + "

Pause\n" + " or Move left tile\n" + " or Put down tile\n" + " Quit\n" + ; + +/* main function for two players */ +int twoplayers (int width, int height, int scale) +{ + + /* init all variables */ + board_t *board_left = initboard (width, height); + board_t *board_right = initboard (width, height); + int current_left = -1; + int current_right = -1; + int lines = 0; + int next = -1; + int score_left = 0; + int score_right = 0; + + setscale (board_left, scale); + setscale (board_right, scale); + + /* get blocks */ + int nb_blocks = 0; + block_t *blocks = getblocks ("std", &nb_blocks); + board_t *nextblock = initboard (maxblockwidth (blocks, nb_blocks) + 2, + maxblockheight (blocks, nb_blocks) + 2); + setscale (nextblock, scale); + + /* init seed */ + newseed (); + + /* get first bloc */ + int xblock_left, yblock_left; + block_t *cblock_left = drawblock (board_left, blocks, nb_blocks, NULL, ¤t_left, &xblock_left, &yblock_left, &next); + int xblock_right, yblock_right; + block_t *cblock_right = drawblock (board_right, blocks, nb_blocks, NULL, ¤t_right, &xblock_right, &yblock_right, &next); + + /* init curses window */ + initscr (); + noecho (); + cbreak (); + nonl (); + keypad (stdscr, TRUE); + curs_set (0); + start_color (); + + /* window positions */ + board_left->xoffset = xoffset + 1; + board_left->yoffset = xoffset + 1; + int xscore = board_left->xoffset + xoffset + 2 + board_left->xsize; + int yscore = board_left->yoffset; + nextblock->xoffset = xscore + (9 + nbdigit + 1 - nextblock->xsize) / 2; + nextblock->yoffset = yscore + 1 + 2 + yoffset; + int xhelp = xscore - 1; + int yhelp = nextblock->yoffset + nextblock->ysize + yoffset; + + /* help window */ + int lhelp = helpwindow (help, xhelp, yhelp); + + /* window positions */ + int xmsg = board_left->xoffset; + int ymsg = max (board_left->yoffset + yoffset + 1 + board_left->ysize, yhelp + lhelp + yoffset); + int lmsg = xhelp - xmsg + strmaxlen (help, '\n'); + + /* resize windows for multiplayer */ + board_right->xoffset = xhelp + strmaxlen (help, '\n') + xoffset + 1; + board_right->yoffset = yoffset + 1; + nextblock->xoffset = xscore + (strmaxlen (help, '\n') - nextblock->xsize - 2) / 2; + xscore += (strmaxlen (help, '\n') - 11 - 2 * (nbdigit + 1) - 2) / 2; + lmsg += xhelp - xmsg; + + /* event loop */ + int mode = -1; + int settle_left = 0; + int settle_right = 0; + int speed = 5000; + int stop = 0; + timeval_t blockend_left = {0, 0}; + timeval_t blockend_right = {0, 0}; + while (!stop) { + char msg[128] = {0}; + msgwindow (msg, xmsg, ymsg, lmsg); + + switch (mode) { + case -1: + boardwindow (nextblock, 1); + //displayblock (nextblock, blocks + current, -1, -1); + sprintf (msg, "Get ready players. Press to start"); + break; + case 0: + boardwindow (nextblock, 1); + //displayblock (nextblock, blocks + current, -1, -1); + sprintf (msg, "Game in pause. Pause

to continue"); + break; + case 1: + halfdelay (1); + if (blockend_left.tv_sec && isovertime (&blockend_left)) { + if (testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) { + yblock_left++; + } else { + settle_left = 1; + } + setendtime (&blockend_left, speed); + } + if (blockend_right.tv_sec && isovertime (&blockend_right)) { + if (testvalidpos (board_right, cblock_right, xblock_right, yblock_right + 1)) { + yblock_right++; + } else { + settle_right = 1; + } + setendtime (&blockend_right, speed); + } + + /* Player one */ + if (settle_left) { + settleblock (board_left, cblock_left, xblock_left, yblock_left); + } + int nblines_left = checkline (board_left, &score_left, &lines); + if (nblines_left) { + while (nblines_left-- > 0) { + boardwindow (board_left, 0); + stackboard (board_left); + msleep (20 + 200 / (lines / 20 + 1)); + refresh (); + } + } + if (settle_left) { + if (!testvalidpos (board_left, blocks + next , board_left->width / 2, 0)) { + sprintf (msg, "To bad, player One looses. Score is %d / %d", score_left, score_right); + mode = 2; + } else { + cblock_left = drawblock (board_left, blocks, nb_blocks, cblock_left, ¤t_left, &xblock_left, &yblock_left, &next); + boardwindow (nextblock, 1); + displayblock (nextblock, blocks + next, -1, -1); + } + settle_left = 0; + } + + /* Player two */ + if (settle_right) { + settleblock (board_right, cblock_right, xblock_right, yblock_right); + } + int nblines_right = checkline (board_right, &score_right, &lines); + if (nblines_right) { + while (nblines_right-- > 0) { + boardwindow (board_right, 0); + stackboard (board_right); + msleep (20 + 200 / (lines / 20 + 1)); + refresh (); + } + } + if (settle_right) { + if (!testvalidpos (board_right, blocks + next , board_right->width / 2, 0)) { + sprintf (msg, "To bad, player Two looses. Score is %d / %d", score_left, score_right); + mode = 2; + } else { + cblock_right = drawblock (board_right, blocks, nb_blocks, cblock_right, ¤t_right, &xblock_right, &yblock_right, &next); + } + settle_right = 0; + } + + break; + case 2: + freeblock (cblock_left); + freeblock (cblock_right); + cblock_left = NULL; + cblock_right = NULL; + sprintf (msg, "End of game. Press to quit"); + } + + if (*msg) { + halfdelay (0); + msgwindow (msg, xmsg, ymsg, lmsg); + msleep (800); + } + + boardwindow (board_left, 0); + boardwindow (board_right, 0); + scorewindow (xscore, yscore, nbdigit, score_left, score_right, (lines / 20) + 1); + int newspeed = 10 + 4900 / (lines / 20 + 1); + if (newspeed < speed) { + speed = newspeed; + setendtime (&blockend_left, speed); + setendtime (&blockend_right, speed); + } + if (mode == 1) { + displayblock (board_left, cblock_left, xblock_left, yblock_left); + displayblock (board_right, cblock_right, xblock_right, yblock_right); + } + + int ch = getch (); + switch (mode) { + case -1: + switch (ch) { + case 's': + mode = 0; + ch = 'p'; + break; + } + break; + case 1: + switch (ch) { + case 'a': + if (!testvalidpos (board_left, rotateblock (cblock_left, -1), xblock_left, yblock_left)) { + rotateblock (cblock_left, 1); + } + break; + case 'e': + if (!testvalidpos (board_left, rotateblock (cblock_left, 1), xblock_left, yblock_left)) { + rotateblock (cblock_left, -1); + } + break; + case KEY_UP: + case 'i': + while (testvalidpos (board_right, cblock_right, xblock_right, yblock_right + 1)) { + yblock_right++; + } + settle_right = 1; + break; + case 'd': + if (testvalidpos (board_left, cblock_left, xblock_left + 1, yblock_left)) { + xblock_left++; + } + break; + case KEY_LEFT: + case 'j': + if (testvalidpos (board_right, cblock_right, xblock_right - 1, yblock_right)) { + xblock_right--; + } + break; + case KEY_DOWN: + case 'k': + if (testvalidpos (board_right, cblock_right, xblock_right, yblock_right + 1)) { + yblock_right++; + } else { + settle_right = 1; + } + break; + case KEY_RIGHT: + case 'l': + if (testvalidpos (board_right, cblock_right, xblock_right + 1, yblock_right)) { + xblock_right++; + } + break; + case KEY_ENTER: + case '\n': + case '\r': + case 'o': + if (!testvalidpos (board_right, rotateblock (cblock_right, 1), xblock_right, yblock_right)) { + rotateblock (cblock_right, -1); + } + break; + case 'q': + if (testvalidpos (board_left, cblock_left, xblock_left - 1, yblock_left)) { + xblock_left--; + } + break; + case 's': + if (testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) { + yblock_left++; + } else { + settle_left = 1; + } + break; + case KEY_BACKSPACE: + case KEY_DELETE: + case 127: + case '\b': + case ' ': + case 'u': + if (!testvalidpos (board_right, rotateblock (cblock_right, -1), xblock_right, yblock_right)) { + rotateblock (cblock_right, 1); + } + break; + case 'z': + while (testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) { + yblock_left++; + } + settle_left = 1; + } + break; + case 2: + break; + } + switch (ch) { + case 'p': + switch (mode) { + case 0: + mode = 1; + setendtime (&blockend_left, speed); + break; + case 1: + mode = 0; + break; + } + break; + case KEY_ESC: + stop = 1; + break; + //case ERR: + //default: + } + } + + endwin (); + + freeblock (cblock_left); + freeblock (cblock_right); + freeboard (nextblock); + freeboard (board_left); + freeboard (board_right); + + return 0; +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/twoplayers.h b/twoplayers.h new file mode 100644 index 0000000..2ce7f92 --- /dev/null +++ b/twoplayers.h @@ -0,0 +1,6 @@ +#ifndef __TWOPLAYERS_H__ +#define __TWOPLAYERS_H__ + +int twoplayers (int width, int height, int scale); + +#endif /* __TWOPLAYERS_H__ */