first functional code form multiplayers
authorLaurent Mazet <mazet@softndesign.org>
Wed, 31 Jul 2024 11:16:55 +0000 (13:16 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Wed, 31 Jul 2024 11:16:55 +0000 (13:16 +0200)
display.c
display.h
tetris.c

index e6ed047e35a959edd1f74ce30ab80e4b39b2f0a0..b7396b5f591118b899690d02a5b6002bd642ed3a 100644 (file)
--- a/display.c
+++ b/display.c
@@ -161,17 +161,25 @@ void boardwindow (board_t *board, int mode)
     }
 }
 
-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);
index 17b72b17400281bba798117fe7795416e8f85787..045d1b2ec2f1c1dfab0cc4039c4c1c56f6990c02 100644 (file)
--- a/display.h
+++ b/display.h
@@ -10,7 +10,7 @@ int helpwindow (char *msg, int xoffset, int yoffset);
 
 void boardwindow (board_t *board, int mode);
 
-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);
 
 void displayblock (board_t *board, block_t *block, int x, int y);
 
index 934bf83507d0e13b718ee28654ffb6f61ff9d183..8b4b63dc998cc9229a385e551817a22f3fb8f10c 100644 (file)
--- a/tetris.c
+++ b/tetris.c
@@ -52,6 +52,17 @@ char *help =
     "<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;
@@ -70,18 +81,18 @@ int usage (int ret)
 
 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;
     }
 
@@ -132,6 +143,7 @@ int main (int argc, char *argv[])
         switch (c) {
         case 'c':
             chrono = 1;
+            multi = 0;
             break;
         case 'f':
             arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
@@ -145,6 +157,7 @@ int main (int argc, char *argv[])
         case 'm':
             multi = 1;
             filename = NULL;
+            chrono = 0;
             break;
         case 's':
             arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
@@ -190,9 +203,12 @@ int main (int argc, char *argv[])
     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) {
@@ -235,7 +251,11 @@ int main (int argc, char *argv[])
     /* get first bloc */
     int xblock, yblock;
     block_t *cblock = drawblock (board, blocks, nb_blocks, NULL, &current, &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, &current2, &xblock2, &yblock2, &next);
+    }
 
     /* init curses window */
     initscr ();
@@ -260,28 +280,31 @@ int main (int argc, char *argv[])
     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};
@@ -291,7 +314,8 @@ int main (int argc, char *argv[])
         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);
@@ -308,6 +332,16 @@ int main (int argc, char *argv[])
                 }
                 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);
             }
@@ -337,7 +371,11 @@ int main (int argc, char *argv[])
             }
             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, &current, &xblock, &yblock, &next);
@@ -346,11 +384,42 @@ int main (int argc, char *argv[])
                 }
                 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, &current2, &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) {
@@ -363,17 +432,21 @@ int main (int argc, char *argv[])
         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 ();
@@ -388,6 +461,16 @@ int main (int argc, char *argv[])
             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)) {
@@ -395,6 +478,11 @@ int main (int argc, char *argv[])
                 }
                 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)) {
@@ -423,6 +511,22 @@ int main (int argc, char *argv[])
                     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:
@@ -433,6 +537,11 @@ int main (int argc, char *argv[])
                     rotateblock (cblock, 1);
                 }
                 break;
+            case 'z':
+                while (testvalidpos (board2, cblock2, xblock2, yblock2 + 1)) {
+                    yblock2++;
+                }
+                settle2 = 1;
             }
             break;
         case 2:
@@ -453,11 +562,18 @@ int main (int argc, char *argv[])
                 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;
@@ -480,8 +596,10 @@ int main (int argc, char *argv[])
     endwin ();
 
     freeblock (cblock);
+    freeblock (cblock2);
     freeboard (nextblock);
     freeboard (board);
+    freeboard (board2);
 
     return 0;
 }