correct special cases
authorLaurent Mazet <mazet@softndesign.org>
Fri, 9 Aug 2024 20:40:18 +0000 (22:40 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Fri, 9 Aug 2024 20:40:18 +0000 (22:40 +0200)
display.c
display.h
oneplayer.c
twoplayers.c

index b7396b5f591118b899690d02a5b6002bd642ed3a..2facdf54592acd0735cccf8321b304e31be4ecbc 100644 (file)
--- a/display.c
+++ b/display.c
@@ -7,6 +7,7 @@
 #include "color.h"
 #include "debug.h"
 #include "function.h"
+#include "time.h"
 #include "type.h"
 
 #include "display.h"
@@ -293,4 +294,14 @@ void msgwindow (char *msg, int xoffset, int yoffset, int length)
     setcolor (black_gray);
 }
 
+void removelines (board_t *board, int nblines, int tempo)
+{
+    while (nblines-- > 0) {
+        boardwindow (board, 0);
+        stackboard (board);
+        msleep (tempo);
+        refresh ();
+    }
+}
+
 /* vim: set ts=4 sw=4 et: */
index 045d1b2ec2f1c1dfab0cc4039c4c1c56f6990c02..cbaef2c09543bca0c081c8565755d40e87157250 100644 (file)
--- a/display.h
+++ b/display.h
@@ -18,6 +18,8 @@ char *savewindow (int length, int xoffset, int yoffset);
 
 void msgwindow (char *msg, int xoffset, int yoffset, int length);
 
+void removelines (board_t *board, int nblines, int tempo);
+
 #endif /* __DISPLAY_H__ */
 
 /* vim: set ts=4 sw=4 et: */
index 8b9d2770ad85695be85724192d8270a5a715dd8d..1e4f752db5645bee8816286245cf9bffe2166a9b 100644 (file)
@@ -21,6 +21,11 @@ static char *help =
     "<s> Save file\n"
     ;
 
+static int computetempo (int lines)
+{
+    return 20 + 200 / (lines / 10 + 1);
+}
+
 /* main function for one player*/
 int oneplayer (int width, int height, int scale, int chrono, char *filename)
 {
@@ -133,21 +138,17 @@ int oneplayer (int width, int height, int scale, int chrono, char *filename)
 
             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) {
+                int nblines = checkline (board, &score, &lines);
+                removelines (board, nblines, computetempo (lines));
+                if (nblines && chrono) {
                     setendtime (&lineend, chronoratio * speed);
                 }
-            } else if (chrono && lineend.tv_sec && isovertime (&lineend)) {
+            }
+            if (chrono && lineend.tv_sec && isovertime (&lineend)) {
                 if (!testvalidpos (board, cblock, xblock, yblock + 1)) {
                     settleblock (board, cblock, xblock, yblock);
+                    int nblines = checkline (board, &score, &lines);
+                    removelines (board, nblines, computetempo (lines));
                     settle = 1;
                 }
                 int isempty = addline (board, nbholes);
index 2fee681e81ecf5793d77206c1ef72ccddc563897..452e75ba97d3514bea8f6c31fbd925fa0579a696 100644 (file)
@@ -20,6 +20,16 @@ static char *help =
     "<escape> Quit\n"
     ;
 
+static int computetempo (int lines)
+{
+    return 20 + 200 / (lines / 20 + 1);
+}
+
+static int computepenalty (int nblines)
+{
+    return (nblines == 4) ? 4 : (nblines > 1) ? nblines - 1 : 0;
+}
+
 /* main function for two players */
 int twoplayers (int width, int height, int scale)
 {
@@ -109,8 +119,14 @@ int twoplayers (int width, int height, int scale)
             break;
         case 1:
             halfdelay (1);
+
             boardwindow (nextblock, 1);
             displayblock (nextblock, blocks + next, -1, -1);
+
+            int penalty_left = 0;
+            int penalty_right = 0;
+
+            /* check timeout */
             if (blockend_left.tv_sec && isovertime (&blockend_left)) {
                 if (testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) {
                     yblock_left++;
@@ -131,17 +147,9 @@ int twoplayers (int width, int height, int scale)
             /* 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) {
+                int nblines_left = checkline (board_left, &score_left, &lines);
+                penalty_right = computepenalty (nblines_left);
+                removelines (board_left, nblines_left, computetempo (lines));
                 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;
@@ -156,17 +164,9 @@ int twoplayers (int width, int height, int scale)
             /* 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) {
+                int nblines_right = checkline (board_right, &score_right, &lines);
+                penalty_left = computepenalty (nblines_right);
+                removelines (board_right, nblines_right, computetempo (lines));
                 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;
@@ -178,6 +178,58 @@ int twoplayers (int width, int height, int scale)
                 settle_right = 0;
             }
 
+            /* Penalty */
+            while ((penalty_left > 0) || (penalty_right > 0)) {
+
+                /* Player one */
+                if (penalty_left) {
+                    if (!testvalidpos (board_left, cblock_left, xblock_left, yblock_left + 1)) {
+                        settleblock (board_left, cblock_left, xblock_left, yblock_left);
+                        int nblines_left = checkline (board_left, &score_left, &lines);
+                        penalty_right += computepenalty (nblines_left);
+                        removelines (board_left, nblines_left, computetempo (lines));
+                        if (!testvalidpos (board_left, blocks + next , board_left->width / 2, 0)) {
+                            sprintf (msg, "To bad, player One looses. Score is %d / %d", score_right, score_left);
+                            mode = 2;
+                        } else {
+                            cblock_left = drawblock (board_left, blocks, nb_blocks, cblock_left, &current_left, &xblock_left, &yblock_left, &next);
+                            boardwindow (nextblock, 1);
+                            displayblock (nextblock, blocks + next, -1, -1);
+                        }
+                    }
+                    int isempty = addline (board_left, nbholes);
+                    if (!isempty) {
+                        sprintf (msg, "Shame, player One looses. Score is %d / %d", score_right, score_left);
+                        mode = 2;
+                    }
+                    penalty_left--;
+                }
+
+                /* Player two */
+                if (penalty_right) {
+                    if (!testvalidpos (board_right, cblock_right, xblock_right, yblock_right + 1)) {
+                        settleblock (board_right, cblock_right, xblock_right, yblock_right);
+                        int nblines_right = checkline (board_right, &score_right, &lines);
+                        penalty_left += computepenalty (nblines_right);
+                        removelines (board_right, nblines_right, computetempo (lines));
+                        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, &current_right, &xblock_right, &yblock_right, &next);
+                            boardwindow (nextblock, 1);
+                            displayblock (nextblock, blocks + next, -1, -1);
+                        }
+                    }
+                    int isempty = addline (board_right, nbholes);
+                    if (!isempty) {
+                        sprintf (msg, "Shame, player Two looses. Score is %d / %d", score_left, score_right);
+                        mode = 2;
+                    }
+                    penalty_right--;
+                }
+            }
+
             break;
         case 2:
             freeblock (cblock_left);