Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* A Windows console program: taxi and passengers simulator */
  2.  
  3. #include <windows.h>
  4. #include <wincon.h>
  5. #include <stdio.h>
  6. #include <conio.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9.  
  10. void init_scr();
  11. void restore_scr();
  12. void clrscr();
  13. void write_console(const char *msg, DWORD len, COORD coords, DWORD attr);
  14.  
  15. int  add_br (int n, int addon);
  16.  
  17. DWORD WINAPI Si1  (LPVOID parm);        // a passengers thread
  18. DWORD WINAPI Si2  (LPVOID parm);
  19. DWORD WINAPI Si3  (LPVOID parm);
  20. DWORD WINAPI Si4  (LPVOID parm);
  21. DWORD WINAPI Taxi (LPVOID parm);        // a taxi thread
  22.  
  23. HANDLE hstdout;
  24. HANDLE hproc[5], htaxi, hproc2[5], hproc3[5], hproc4[5], ht2;
  25.  
  26. HANDLE hs_br;                   // a semaphor for br[]
  27. HANDLE hs_wc;                   // a semaphor for write_console()
  28. HANDLE hs_ds;                   // a semaphor for draw_statistics()
  29. HANDLE hs_st;                   // a semaphor for draw_station()
  30.  
  31. int br[5];                      // a number of the passengers on the taxi stations
  32. int w;                          // a number of the passengers on the taxi, used in taxi()
  33.  
  34. DWORD si_attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
  35. DWORD st_attr = FOREGROUND_GREEN;
  36. DWORD tx_attr = FOREGROUND_RED;
  37.  
  38. static
  39. void draw_statistics()
  40. {
  41.   char msg[100];
  42.   COORD coords;
  43.  
  44.   WaitForSingleObject (hs_ds, INFINITE);
  45.  
  46.   coords.X = 0;
  47.   coords.Y = 0;
  48.  
  49.   sprintf (msg, "station1=%d \n", br[1]);
  50.   write_console (msg, strlen(msg), coords, si_attr);
  51.  
  52.   coords.Y++;
  53.   sprintf (msg, "station2=%d \n", br[2]);
  54.   write_console (msg, strlen(msg), coords, si_attr);
  55.  
  56.   coords.Y++;
  57.   sprintf (msg, "station3=%d \n", br[3]);
  58.   write_console (msg, strlen(msg), coords, si_attr);
  59.  
  60.   coords.Y++;
  61.   sprintf (msg, "station4=%d \n", br[4]);
  62.   write_console (msg, strlen(msg), coords, si_attr);
  63.  
  64.   coords.Y++;
  65.   sprintf (msg, "taxi=%d \n", w);
  66.   write_console (msg, strlen(msg), coords, si_attr);
  67.  
  68.   ReleaseSemaphore (hs_ds, 1, NULL);
  69. }
  70.  
  71. static
  72. void draw_station(int station)
  73. {
  74.   char msg[100];
  75.   COORD coords;
  76.   int j;
  77.  
  78.   WaitForSingleObject (hs_st, INFINITE);
  79.  
  80.   if (station == 1)
  81.   {
  82.     int br1, n, c;
  83.  
  84.     coords.X = 34;
  85.     coords.Y = 3;
  86.     write_console (" st1 ", 5, coords, st_attr);
  87.     coords.Y++;
  88.     write_console ("-----", 5, coords, st_attr);
  89.  
  90.     br1 = add_br (1, 0);
  91.     coords.X = 40;
  92.     c = 3;
  93.     while (c-- > 0)
  94.     {
  95.       n  = 5;
  96.       if (br1 < 5)
  97.         n = br1;
  98.  
  99.       if (n != 0)
  100.       for (j = 5; j > 5-n; j--)
  101.       {
  102.         coords.Y = j - 1;
  103.         write_console ("*", 1, coords, si_attr);
  104.       }
  105.  
  106.       if (n != 5)
  107.       for (j = 5-n; j > 0; j--)
  108.       {
  109.         coords.Y = j - 1;
  110.         write_console (" ", 1, coords, si_attr);
  111.       }
  112.  
  113.       coords.X++;
  114.       br1 -= n;
  115.     }
  116.   }
  117.   else
  118.   if (station == 3)
  119.   {
  120.     int br3, n, c;
  121.  
  122.     coords.X = 34;
  123.     coords.Y = 20;
  124.     write_console (" st3 ", 5, coords, st_attr);
  125.     coords.Y--;
  126.     write_console ("-----", 5, coords, st_attr);
  127.  
  128.     br3 = add_br (3, 0);
  129.     coords.X = 33;
  130.     c = 3;
  131.     while (c-- > 0)
  132.     {
  133.       n = 5;
  134.       if (br3 < 5)
  135.         n = br3;
  136.  
  137.       if (n != 0)
  138.       for (j = 0; j < n; j++)
  139.       {
  140.         coords.Y = 20 + j;
  141.         write_console ("*", 1, coords, si_attr);
  142.       }
  143.  
  144.       if (n != 5)
  145.       for (j = n; j < 5; j++)
  146.       {
  147.         coords.Y = 20 + j;
  148.         write_console (" ", 1, coords, si_attr);
  149.       }
  150.  
  151.       coords.X--;
  152.       br3 -= n;
  153.     }
  154.   }
  155.   else
  156.   if (station == 2)
  157.   {
  158.     int br2, n, c;
  159.  
  160.     coords.X = 69;
  161.     coords.Y = 11;
  162.     write_console ("st2", 3, coords, st_attr);
  163.     coords.X -= 2;
  164.     for (j = 14; j >= 10; j--)
  165.     {
  166.       coords.Y = j;
  167.       write_console ("|", 1, coords, st_attr);
  168.     }
  169.  
  170.     br2 = add_br (2, 0);
  171.     coords.Y = 13;
  172.     c = 3;
  173.     while (c-- > 0)
  174.     {
  175.       n = 5;
  176.       if (br2 < 5)
  177.         n = br2;
  178.  
  179.       coords.X = 79;
  180.       write_console (" ", 1, coords, si_attr);
  181.  
  182.       coords.Y++;
  183.       coords.X = 68;
  184.       write_console ("*****", br2, coords, si_attr);
  185.  
  186.       coords.X = 68+n;
  187.       write_console ("            ", 11-n, coords, si_attr);
  188.  
  189.       coords.Y++;
  190.       coords.X = 79;
  191.       write_console (" ", 1, coords, si_attr);
  192.  
  193.       coords.Y--;
  194.       br2 -= n;
  195.     }
  196.   }
  197.   else
  198.   if (station == 4)
  199.   {
  200.     int br4, n, c;
  201.  
  202.     coords.X = 7;
  203.     coords.Y = 13;
  204.     write_console ("st4", 3, coords, st_attr);
  205.     coords.X += 4;
  206.     for (j = 10; j <= 14; j++)
  207.     {
  208.       coords.Y = j;
  209.       write_console ("|", 1, coords, st_attr);
  210.     }
  211.  
  212.     coords.Y = 9;
  213.     br4 = add_br (4, 0);
  214.     c = 3;
  215.     while (c-- > 0)
  216.     {
  217.       n = 5;
  218.       if (br4 < 5)
  219.         n = br4;
  220.  
  221.       coords.X = 0;
  222.       write_console (" ", 1, coords, si_attr);
  223.      
  224.       coords.Y++;
  225.       write_console ("          ", 10, coords, si_attr);
  226.  
  227.       coords.X = 10 - n;
  228.       write_console ("**********", n, coords, si_attr);
  229.  
  230.       coords.Y++;
  231.       coords.X = 0;
  232.       write_console (" ", 1, coords, si_attr);
  233.  
  234.       coords.Y--;
  235.       br4 -= n;
  236.     }
  237.   }
  238.  
  239.   ReleaseSemaphore (hs_st, 1, NULL);
  240. }
  241.  
  242. int
  243. main (void)
  244. {
  245.   int N;                        // a passengers on the all stations
  246.   int i, j;
  247.   COORD coords;                 // a cursor coords
  248.   DWORD len;
  249.   int   br1, br2, br3, br4;     // a passengers on the station X
  250.  
  251.   init_scr();
  252.  
  253.   printf ("Taxi and passengers simulator:\n");
  254.   while (1)
  255.     {
  256.       printf ("  enter a max passengers number on the stations (0..20) = ");
  257.       scanf ("%d", &N);
  258.       if ((N >= 0) && (N<=20))
  259.         break;
  260.     }
  261.   while (1)
  262.     {
  263.       printf ("  enter a passengers on the taxi (0..10) = ");
  264.       scanf ("%d", &w);
  265.       if ((w >= 0) && (w<=10))
  266.         break;
  267.     }
  268.   init_scr();
  269.  
  270.   srand (time (0));
  271.   br1 = rand () % 6;                    // passngers on the station1, 0..5
  272.   if (br1 > N)
  273.     br1 = N;
  274.  
  275.   br2 = rand () % 6;
  276.   if (br2 > N - br1)
  277.     br2 = N - br1;
  278.  
  279.   br3 = rand () % 6;
  280.   if (br3 > N - br1 - br2)
  281.     br3 = N - br1 - br2;
  282.  
  283.   br4 = N - br1 - br2 - br3;
  284.   while (br4 > 5)
  285.   {
  286.     br4--;
  287.     if (br1 < 5) { br1++; continue; }
  288.     if (br2 < 5) { br2++; continue; }
  289.     if (br3 < 5) { br3++; continue; }
  290.   }
  291.  
  292.   hs_br = CreateSemaphore (NULL, 1,  1, NULL);
  293.   hs_wc = CreateSemaphore (NULL, 1,  1, NULL);
  294.   hs_ds = CreateSemaphore (NULL, 1,  1, NULL);
  295.   hs_st = CreateSemaphore (NULL, 1,  1, NULL);
  296.  
  297.   draw_statistics();
  298.   for (i=1; i<=4; i++)
  299.     draw_station(i);
  300.  
  301.   htaxi = CreateThread (NULL, 4096, Taxi, NULL, 0, NULL);
  302.  
  303.   for (i = 0; i < br1; i++) {
  304.       srand(time(0));
  305.       Sleep(600*(4+rand()%10));
  306.       hproc[i] = CreateThread (NULL, 4096, Si1, NULL, 0, NULL);
  307.   }
  308.  
  309.   for (i = 0; i < br2; i++) {
  310.       srand(time(0));
  311.       Sleep(400*(4+rand()%10));
  312.       hproc2[i] = CreateThread (NULL, 4096, Si2, NULL, 0, NULL);
  313.   }
  314.  
  315.   for (i = 0; i < br3; i++) {
  316.       srand(time(0));
  317.       Sleep(600*(4+rand()%10));
  318.       hproc3[i] = CreateThread (NULL, 4096, Si3, NULL, 0, NULL);
  319.   }
  320.  
  321.   for (i = 0; i < br4; i++) {
  322.       srand(time(0));
  323.       Sleep(600*(4+rand()%10));
  324.       hproc4[i] = CreateThread (NULL, 4096, Si4, NULL, 0, NULL);
  325.   }
  326.  
  327.   getch ();
  328.   restore_scr();
  329.   return 0;
  330. }
  331.  
  332. static
  333. void draw_taxi (int orientation, COORD coords)
  334. {
  335.   static int   old_orientation;
  336.   static COORD old_coords;
  337.  
  338.   if (orientation != 0) {
  339.     old_orientation = orientation;
  340.     old_coords = coords;
  341.   }
  342.   else {
  343.     orientation = old_orientation;
  344.     coords = old_coords;
  345.   }
  346.  
  347.   if (orientation == 1)
  348.   {
  349.       int f, b, ii;
  350.       f = 5;
  351.       if (w < 5)
  352.         f = w;
  353.       b = w - f;
  354.  
  355.       write_console ("  ----- ", 8, coords, tx_attr);
  356.  
  357.       coords.Y++;
  358.       write_console (" |     |", 8, coords, tx_attr);
  359.       coords.X += 2 + 5 - b;
  360.       write_console (  "ooooo", b, coords, tx_attr);
  361.       coords.X -= 2 + 5 - b;
  362.  
  363.       coords.Y++;
  364.       write_console (" |     |", 8, coords, tx_attr);
  365.       coords.X += 2 + 5 - f;
  366.       write_console (  "ooooo", f, coords, tx_attr);
  367.       coords.X -= 2 + 5 - f;
  368.  
  369.       coords.Y++;
  370.       write_console ("  ----- ", 8, coords, tx_attr);
  371.  
  372.       for (ii=0; ii<5; ii++)
  373.       {
  374.       coords.Y++;
  375.       write_console ("        ", 8, coords, tx_attr);
  376.       }
  377.   }
  378.   else
  379.   if (orientation == 2)
  380.   {
  381.       COORD coords2;
  382.       int f, b, ii;
  383.  
  384.       f = 5;
  385.       if (f > w)
  386.         f = w;
  387.       b = w - f;
  388.  
  389.       coords2.X = coords.X;
  390.       coords.Y--;
  391.       write_console ("       ", 7, coords, tx_attr);
  392.       coords.Y++;
  393.       write_console ("   --  ", 7, coords, tx_attr);
  394.  
  395.       for (ii=0; ii < 5; ii++)
  396.       {
  397.         coords2.Y = coords.Y + 5 - ii;
  398.         if (f && b) {
  399.           write_console ("  |oo| ", 7, coords2, tx_attr);
  400.           f--; b--;
  401.         }
  402.         else
  403.         if (f) {
  404.           write_console ("  |o | ", 7, coords2, tx_attr);
  405.           f--;
  406.         }
  407.         else {
  408.           write_console ("  |  | ", 7, coords2, tx_attr);
  409.         }
  410.       }
  411.  
  412.       coords.Y += 6;
  413.       write_console ("   --  ", 7, coords, tx_attr);
  414.   }
  415.   else
  416.   if (orientation == 3)
  417.   {
  418.       int ii;
  419.       for (ii=0; ii < 4; ii++)
  420.       {
  421.       write_console ("        ", 8, coords, tx_attr);
  422.       coords.Y++;
  423.       }
  424.  
  425.       write_console (" -----  ", 8, coords, tx_attr);
  426.  
  427.       coords.Y++;
  428.       write_console ("|     | ", 8, coords, tx_attr);
  429.       coords.X++;
  430.       ii = 5;
  431.       if (w < 5)
  432.         ii = w;
  433.       write_console ( "ooooo",   ii, coords, tx_attr);
  434.       coords.X--;
  435.  
  436.       coords.Y++;
  437.       write_console ("|     | ", 8, coords, tx_attr);
  438.       coords.X++;
  439.       ii = w - ii;
  440.       write_console ( "ooooo",  ii, coords, tx_attr);
  441.       coords.X--;
  442.  
  443.       coords.Y++;
  444.       write_console (" -----  ", 8, coords, tx_attr);
  445.   }
  446.   else
  447.   if (orientation == 4)
  448.   {
  449.       int f, b, ii;
  450.  
  451.       f = 5;
  452.       if (f > w)
  453.         f = w;
  454.       b = w - f;
  455.  
  456.       write_console ("  --   ", 7, coords, tx_attr);
  457.  
  458.       for (ii=0; ii < 5; ii++)
  459.       {
  460.         coords.Y++;
  461.         if (f && b) {
  462.           write_console (" |oo|  ", 7, coords, tx_attr);
  463.           f--; b--;
  464.         }
  465.         else
  466.         if (f) {
  467.           write_console (" | o|  ", 7, coords, tx_attr);
  468.           f--;
  469.         }
  470.         else
  471.           write_console (" |  |  ", 7, coords, tx_attr);
  472.       }
  473.  
  474.       coords.Y++;
  475.       write_console ("  --   ", 7, coords, tx_attr);
  476.  
  477.       coords.Y++;
  478.       write_console ("       ", 7, coords, tx_attr);
  479.   }
  480. }
  481.  
  482. DWORD WINAPI
  483. Taxi (LPVOID _unused_thread_parm)
  484. {
  485.   int i, ii, j, k, f, b;
  486.   int empty_st;
  487.   COORD coords;
  488.   DWORD len;
  489.   char msg[100];
  490.  
  491.   for (j = 0; j < 48; j++)                              // taxi left
  492.     {
  493.       coords.X = 59 - j;
  494.       coords.Y = 11;
  495.       draw_taxi (3, coords);
  496.  
  497.       if (j == 23)              // station 3 for a passengers exit
  498.         {
  499.           int br3 = add_br (3, 0);
  500.           empty_st = (br3 == 0);
  501.  
  502.           srand (time (0));
  503.           f = rand () % (16 - br3); // passengers can be on the station
  504.  
  505.           if (w)
  506.           {
  507.             while(f)
  508.             {
  509.               if (w==0)
  510.                 break;
  511.  
  512.               f--;
  513.               w--;
  514.               add_br (3, 1);
  515.               draw_statistics();
  516.               draw_station(3);
  517.               draw_taxi(0, coords);
  518.               Sleep (300);
  519.             }
  520.             Sleep (3000);
  521.           }
  522.         }
  523.  
  524.       if (j == 28)              // station 3 for enter
  525.       {
  526.           int br3 = add_br (3, 0);
  527.           f = rand () % (11 - w); // passengers into taxi
  528.  
  529.  
  530.           if (br3 && !empty_st)
  531.           {
  532.             while (br3 > 0 && f > 0)
  533.             {
  534.               f--;
  535.               w++;
  536.               br3 = add_br (3, -1);
  537.  
  538.               draw_statistics();
  539.               draw_station(3);
  540.               draw_taxi(0, coords);
  541.               Sleep (300);
  542.             }
  543.             Sleep (3000);
  544.           }
  545.       }
  546.       Sleep (300);
  547.     }
  548.  
  549.   for (i = 0; i < 10; i++)      // taxi up
  550.     {
  551.       coords.X = 12;
  552.       coords.Y = 15 - i;
  553.       draw_taxi(4, coords);
  554.  
  555.       if (i == 4)               // station 4 for exit
  556.         {
  557.           int br4 = add_br (4, 0);
  558.           empty_st = (br4 == 0);
  559.  
  560.           srand (time (0));
  561.           f = rand () % (16 - br4);
  562.  
  563.           if (w)
  564.           {
  565.             while(f)
  566.             {
  567.               if (w==0)
  568.                 break;
  569.  
  570.               f--;
  571.               w--;
  572.               add_br (4, 1);
  573.               draw_statistics();
  574.               draw_station(4);
  575.               draw_taxi(0, coords);
  576.               Sleep (300);
  577.             }
  578.             Sleep (3000);
  579.           }
  580.         }
  581.  
  582.       if (i == 7)                 // station 4 for enter
  583.         {
  584.           int br4 = add_br (4, 0);
  585.           f = rand () % (11 - w);
  586.  
  587.  
  588.           if (br4 && !empty_st)
  589.           {
  590.             while (br4 > 0 && f > 0)
  591.             {
  592.               f--;
  593.               w++;
  594.               br4 = add_br (4, -1);
  595.  
  596.               draw_statistics();
  597.               draw_station(4);
  598.               draw_taxi(0, coords);
  599.               Sleep (300);
  600.             }
  601.             Sleep (3000);
  602.           }
  603.         }
  604.        Sleep (300);
  605.     }
  606.  
  607.   for (k = 0; k < 48; k++)      // taxi rigth
  608.     {
  609.       coords.X = 12 + k;
  610.       coords.Y = 5;
  611.       draw_taxi (1, coords);
  612.  
  613.       if (k == 19)              // station 1 for exit
  614.         {
  615.           int br1 = add_br (1, 0);
  616.           empty_st = (br1 == 0);
  617.  
  618.           srand (time (0));
  619.           f = rand () % (16 - br1);
  620.  
  621.           if (w)
  622.           {
  623.             while(f)
  624.             {
  625.               if (w==0)
  626.                 break;
  627.  
  628.               f--;
  629.               w--;
  630.               add_br (1, 1);
  631.               draw_statistics();
  632.               draw_station(1);
  633.               draw_taxi(0, coords);
  634.               Sleep (300);
  635.             }
  636.             Sleep (3000);
  637.           }
  638.         }
  639.  
  640.       if (k == 23)              // station 1 for enter
  641.         {
  642.           int br1 = add_br (1, 0);
  643.           f = rand () % (11 - w);
  644.  
  645.           if (br1 && !empty_st)
  646.           {
  647.             while (br1 > 0 && f > 0)
  648.             {
  649.               f--;
  650.               w++;
  651.               br1 = add_br (1, -1);
  652.  
  653.               draw_statistics();
  654.               draw_station(1);
  655.               draw_taxi(0, coords);
  656.               Sleep (300);
  657.             }
  658.             Sleep (3000);
  659.           }
  660.         }
  661.       Sleep (300);
  662.     }
  663.  
  664.   for (i = 0; i < 9; i++)       // taxi down
  665.     {
  666.       coords.X = 60;
  667.       coords.Y = 3 + i;
  668.       draw_taxi (2, coords);
  669.  
  670.       if (i == 4)                       // station 2 for exit
  671.         {
  672.           int br2 = add_br (2, 0);
  673.           empty_st = (br2 == 0);
  674.  
  675.           srand (time (0));
  676.           f = rand () % (16 - br2);
  677.  
  678.           if (w)
  679.           {
  680.             while(f)
  681.             {
  682.               if (w==0)
  683.                 break;
  684.  
  685.               f--;
  686.               w--;
  687.               add_br (2, 1);
  688.               draw_statistics();
  689.               draw_station(2);
  690.               draw_taxi(0, coords);
  691.               Sleep (300);
  692.             }
  693.             Sleep (3000);
  694.           }
  695.         }
  696.  
  697.       if (i == 6)                       // station 2 for enter
  698.         {
  699.           int br2 = add_br (2, 0);
  700.           f = rand () % (11 - w);
  701.  
  702.           if (br2 && !empty_st)
  703.           {
  704.             while (br2 > 0 && f > 0)
  705.             {                  
  706.               f--;
  707.               w++;
  708.               br2 = add_br (2, -1);
  709.  
  710.               draw_statistics();
  711.               draw_station(2);
  712.               draw_taxi(0, coords);
  713.               Sleep (300);
  714.             }
  715.             Sleep (3000);
  716.           }
  717.         }
  718.  
  719.       Sleep (300);
  720.     }
  721.  
  722.   ht2 = CreateThread (NULL, 4096, Taxi, NULL, 0, NULL); // endless loop
  723.   return 0;
  724. }
  725.  
  726. DWORD WINAPI
  727. Si1 (LPVOID _unused_thread_parm) // a passengers thread for the station 1
  728. {
  729.   int a, j, n;
  730.   COORD coords;
  731.  
  732.   srand (time (0));
  733.   a = 6 + rand () % 74;         // a new passengers number, 6..79
  734.  
  735.   while (a != 40)
  736.     {
  737.       if (a < 40)
  738.           a++;
  739.       else
  740.           a--;
  741.  
  742.       coords.X = a;
  743.       coords.Y = 0;
  744.  
  745.       if (a < 40)
  746.         write_console (" *", 2, coords, si_attr);
  747.       else
  748.         write_console ("* ", 2, coords, si_attr);
  749.  
  750.       Sleep (1000);
  751.     }
  752.  
  753.   add_br (1, 1);
  754.   draw_station(1);
  755.   draw_statistics();
  756.  
  757.   Sleep (1000);
  758.   return 0;
  759. }
  760.  
  761. DWORD WINAPI
  762. Si3 (LPVOID _unused_thread_parm) // a passengers thread for the station 3
  763. {
  764.   int b, j, n;
  765.   COORD coords;
  766.  
  767.   srand (time (0));
  768.   b = 1 + rand () % 79;
  769.  
  770.   while (b != 33)
  771.     {
  772.       if (b < 33)
  773.           b++;
  774.       else
  775.           b--;
  776.  
  777.       coords.X = b;
  778.       coords.Y = 24;
  779.  
  780.       if (b < 33)
  781.         write_console (" *", 2, coords, si_attr);
  782.       else
  783.         write_console ("* ", 2, coords, si_attr);
  784.  
  785.       Sleep (1000);
  786.     }
  787.  
  788.   add_br (3, 1);
  789.   draw_station(3);
  790.   draw_statistics();
  791.  
  792.   Sleep (1000);
  793.   return 0;
  794. }
  795.  
  796. DWORD WINAPI
  797. Si4 (LPVOID _unused_thread_parm) // a passengers thread for the station 4
  798. {
  799.  
  800.   int c, j, n;
  801.   COORD coords;
  802.  
  803.   srand (time (0));
  804.   c = 6 + rand () % 19;         // a new passengers number, 6..24
  805.  
  806.   coords.X = 0;
  807.   while (c != 10)
  808.     {
  809.       coords.Y = c;
  810.       write_console ("*", 1, coords, si_attr);
  811.  
  812.       if (c < 10) {
  813.         c++;
  814.         coords.Y--;
  815.       }
  816.       else {
  817.         c--;
  818.         coords.Y++;
  819.       }
  820.       write_console (" ", 1, coords, si_attr);
  821.  
  822.       Sleep (1000);
  823.     }
  824.  
  825.   add_br (4, 1);
  826.   draw_station(4);
  827.   draw_statistics();
  828.  
  829.   Sleep (1000);
  830.   return 0;
  831. }
  832.  
  833. DWORD WINAPI
  834. Si2 (LPVOID _unused_thread_parm) // a passengers thread for the station 2
  835. {
  836.   int d, j, n;
  837.   COORD coords;
  838.  
  839.   srand (time (0));
  840.   d = 1 + rand () % 24;          // a new passengers number, 1..24
  841.  
  842.   coords.X = 79;
  843.   while (d != 14)
  844.     {
  845.       coords.Y = d;
  846.       write_console ("*", 1, coords, si_attr);
  847.       if (d < 14)
  848.         {
  849.           d++;
  850.           coords.Y--;
  851.         }
  852.       else
  853.       {
  854.           d--;
  855.           coords.Y++;
  856.       }
  857.       write_console (" ", 1, coords, si_attr);
  858.       Sleep (1000);
  859.     }
  860.  
  861.   add_br (2, 1);
  862.   draw_station(2);
  863.   draw_statistics();
  864.  
  865.   Sleep (1000);
  866.   return 0;
  867. }
  868.  
  869. UINT oldcp;                             // CodePage on the program start
  870. CONSOLE_CURSOR_INFO old_ci;
  871.  
  872. void init_scr()
  873. {
  874.   hstdout = GetStdHandle (STD_OUTPUT_HANDLE);
  875.   if (hstdout == INVALID_HANDLE_VALUE)
  876.     {
  877.       printf ("Error, can't get console handle\n");
  878.       exit (1);
  879.     }
  880.  
  881.   if (oldcp == 0)
  882.   {
  883.     oldcp = GetConsoleOutputCP();
  884.     SetConsoleOutputCP(CP_UTF8);
  885.  
  886.     GetConsoleCursorInfo (hstdout, &old_ci);
  887.   }
  888.   else
  889.   {
  890.     CONSOLE_CURSOR_INFO new_ci;
  891.  
  892.     new_ci.bVisible = FALSE;
  893.     new_ci.dwSize   = old_ci.dwSize;
  894.     SetConsoleCursorInfo (hstdout, &new_ci);
  895.   }
  896.  
  897.   clrscr ();
  898. }
  899.  
  900. void restore_scr()
  901. {
  902.   SetConsoleOutputCP(oldcp);
  903.   SetConsoleCursorInfo (hstdout, &old_ci);
  904.   clrscr ();
  905. }
  906.  
  907. void clrscr()
  908. {
  909.   CONSOLE_SCREEN_BUFFER_INFO csbi;
  910.   DWORD nocw;
  911.   COORD coords;
  912.  
  913.   SetConsoleTextAttribute (hstdout, FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
  914.   GetConsoleScreenBufferInfo (hstdout, &csbi);
  915.  
  916.   // printf ("csbi.dwSize.X=%u csbi.dwSize.Y=%u\n",
  917.   //    csbi.dwSize.X, csbi.dwSize.Y);
  918.   //  getch ();
  919.  
  920.   coords.X=0; coords.Y=0;
  921.   SetConsoleCursorPosition (hstdout, coords);
  922.   FillConsoleOutputCharacterA(hstdout, ' ', csbi.dwSize.X * csbi.dwSize.Y, coords, &nocw);
  923. }
  924.  
  925. void write_console(const char *msg, DWORD len, COORD coords, DWORD attr)
  926. {
  927.   DWORD len2;
  928.  
  929.   WaitForSingleObject (hs_wc, INFINITE);
  930.  
  931.   SetConsoleTextAttribute (hstdout, attr);
  932.   SetConsoleCursorPosition (hstdout, coords);
  933.   WriteConsole (hstdout, msg, len, &len2, NULL);
  934.  
  935.   ReleaseSemaphore (hs_wc, 1, NULL);
  936. }
  937.  
  938. int add_br (int n, int addon)
  939. {
  940.   int new;
  941.  
  942.   WaitForSingleObject (hs_br, INFINITE);
  943.   br[n] += addon;
  944.   new = br[n];
  945.   ReleaseSemaphore (hs_br, 1, NULL);
  946.  
  947.   return new;
  948. }
  949.