+#define __CONSTANT_C__
+
#include <stdio.h>
#include <string.h>
#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] = {
return pt;
}
-
/* vim: set ts=4 sw=4 et: */
#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__ */
--- /dev/null
+#include <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "constant.h"
+#include "debug.h"
+#include "display.h"
+#include "function.h"
+#include "time.h"
+#include "type.h"
+
+static char *help =
+ "<i> Put down tile\n"
+ "<j> Move left tile\n"
+ "<k> Move down tile\n"
+ "<l> Move right tile\n"
+ "<o> Rotate left tile\n"
+ "<p> Pause\n"
+ "<q> Quit\n"
+ "<u> Rotate right tile\n"
+ "<s> 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 <s> to start");
+ break;
+ case 0:
+ boardwindow (nextblock, 1);
+ displayblock (nextblock, blocks + current, -1, -1);
+ sprintf (msg, "Game in pause. Pause <p> 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 <q> 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: */
--- /dev/null
+#ifndef __ONEPLAYER_H__
+#define __ONEPLAYER_H__
+
+int oneplayer (int width, int height, int scale, int chrono, char *filename);
+
+#endif /* __ONEPLAYER_H__ */
/* 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 <curses.h>
#include <stdio.h>
#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;
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 =
- "<i> Put down tile\n"
- "<j> Move left tile\n"
- "<k> Move down tile\n"
- "<l> Move right tile\n"
- "<o> Rotate left tile\n"
- "<p> Pause\n"
- "<q> Quit\n"
- "<u> Rotate right tile\n"
- "<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;
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 <s> to start");
- break;
- case 0:
- boardwindow (nextblock, 1);
- displayblock (nextblock, blocks + current, -1, -1);
- sprintf (msg, "Game in pause. Pause <p> 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 <escape> to quit");
- } else {
- sprintf (msg, "End of game. Press <q> 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;
}
--- /dev/null
+#include <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "constant.h"
+#include "debug.h"
+#include "display.h"
+#include "function.h"
+#include "time.h"
+#include "type.h"
+
+static char *help =
+ "<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"
+ ;
+
+/* 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 <s> to start");
+ break;
+ case 0:
+ boardwindow (nextblock, 1);
+ //displayblock (nextblock, blocks + current, -1, -1);
+ sprintf (msg, "Game in pause. Pause <p> 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 <escape> 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: */
--- /dev/null
+#ifndef __TWOPLAYERS_H__
+#define __TWOPLAYERS_H__
+
+int twoplayers (int width, int height, int scale);
+
+#endif /* __TWOPLAYERS_H__ */