1 /* A Windows console program: taxi and passengers simulator */
13 void write_console(const char *msg
, DWORD len
, COORD coords
, DWORD attr
);
15 int add_br (int n
, int addon
);
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
24 HANDLE hproc
[5], htaxi
, hproc2
[5], hproc3
[5], hproc4
[5], ht2
;
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()
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()
34 DWORD si_attr
= FOREGROUND_GREEN
| FOREGROUND_INTENSITY
;
35 DWORD st_attr
= FOREGROUND_GREEN
;
36 DWORD tx_attr
= FOREGROUND_RED
;
39 void draw_statistics()
44 WaitForSingleObject (hs_ds
, INFINITE
);
49 sprintf (msg
, "station1=%d \n", br
[1]);
50 write_console (msg
, strlen(msg
), coords
, si_attr
);
53 sprintf (msg
, "station2=%d \n", br
[2]);
54 write_console (msg
, strlen(msg
), coords
, si_attr
);
57 sprintf (msg
, "station3=%d \n", br
[3]);
58 write_console (msg
, strlen(msg
), coords
, si_attr
);
61 sprintf (msg
, "station4=%d \n", br
[4]);
62 write_console (msg
, strlen(msg
), coords
, si_attr
);
65 sprintf (msg
, "taxi=%d \n", w
);
66 write_console (msg
, strlen(msg
), coords
, si_attr
);
68 ReleaseSemaphore (hs_ds
, 1, NULL
);
72 void draw_station(int station
)
78 WaitForSingleObject (hs_st
, INFINITE
);
86 write_console (" st1 ", 5, coords
, st_attr
);
88 write_console ("-----", 5, coords
, st_attr
);
100 for (j
= 5; j
> 5-n
; j
--)
103 write_console ("*", 1, coords
, si_attr
);
107 for (j
= 5-n
; j
> 0; j
--)
110 write_console (" ", 1, coords
, si_attr
);
124 write_console (" st3 ", 5, coords
, st_attr
);
126 write_console ("-----", 5, coords
, st_attr
);
138 for (j
= 0; j
< n
; j
++)
141 write_console ("*", 1, coords
, si_attr
);
145 for (j
= n
; j
< 5; j
++)
148 write_console (" ", 1, coords
, si_attr
);
162 write_console ("st2", 3, coords
, st_attr
);
164 for (j
= 14; j
>= 10; j
--)
167 write_console ("|", 1, coords
, st_attr
);
180 write_console (" ", 1, coords
, si_attr
);
184 write_console ("*****", br2
, coords
, si_attr
);
187 write_console (" ", 11-n
, coords
, si_attr
);
191 write_console (" ", 1, coords
, si_attr
);
204 write_console ("st4", 3, coords
, st_attr
);
206 for (j
= 10; j
<= 14; j
++)
209 write_console ("|", 1, coords
, st_attr
);
222 write_console (" ", 1, coords
, si_attr
);
225 write_console (" ", 10, coords
, si_attr
);
228 write_console ("**********", n
, coords
, si_attr
);
232 write_console (" ", 1, coords
, si_attr
);
239 ReleaseSemaphore (hs_st
, 1, NULL
);
245 int N
; // a passengers on the all stations
247 COORD coords
; // a cursor coords
249 int br1
, br2
, br3
, br4
; // a passengers on the station X
253 printf ("Taxi and passengers simulator:\n");
256 printf (" enter a max passengers number on the stations (0..20) = ");
258 if ((N
>= 0) && (N
<=20))
263 printf (" enter a passengers on the taxi (0..10) = ");
265 if ((w
>= 0) && (w
<=10))
271 br1
= rand () % 6; // passngers on the station1, 0..5
280 if (br3
> N
- br1
- br2
)
283 br4
= N
- br1
- br2
- br3
;
287 if (br1
< 5) { br1
++; continue; }
288 if (br2
< 5) { br2
++; continue; }
289 if (br3
< 5) { br3
++; continue; }
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
);
301 htaxi
= CreateThread (NULL
, 4096, Taxi
, NULL
, 0, NULL
);
303 for (i
= 0; i
< br1
; i
++) {
305 Sleep(600*(4+rand()%10));
306 hproc
[i
] = CreateThread (NULL
, 4096, Si1
, NULL
, 0, NULL
);
309 for (i
= 0; i
< br2
; i
++) {
311 Sleep(400*(4+rand()%10));
312 hproc2
[i
] = CreateThread (NULL
, 4096, Si2
, NULL
, 0, NULL
);
315 for (i
= 0; i
< br3
; i
++) {
317 Sleep(600*(4+rand()%10));
318 hproc3
[i
] = CreateThread (NULL
, 4096, Si3
, NULL
, 0, NULL
);
321 for (i
= 0; i
< br4
; i
++) {
323 Sleep(600*(4+rand()%10));
324 hproc4
[i
] = CreateThread (NULL
, 4096, Si4
, NULL
, 0, NULL
);
333 void draw_taxi (int orientation
, COORD coords
)
335 static int old_orientation
;
336 static COORD old_coords
;
338 if (orientation
!= 0) {
339 old_orientation
= orientation
;
343 orientation
= old_orientation
;
347 if (orientation
== 1)
355 write_console (" ----- ", 8, coords
, tx_attr
);
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
;
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
;
370 write_console (" ----- ", 8, coords
, tx_attr
);
372 for (ii
=0; ii
<5; ii
++)
375 write_console (" ", 8, coords
, tx_attr
);
379 if (orientation
== 2)
389 coords2
.X
= coords
.X
;
391 write_console (" ", 7, coords
, tx_attr
);
393 write_console (" -- ", 7, coords
, tx_attr
);
395 for (ii
=0; ii
< 5; ii
++)
397 coords2
.Y
= coords
.Y
+ 5 - ii
;
399 write_console (" |oo| ", 7, coords2
, tx_attr
);
404 write_console (" |o | ", 7, coords2
, tx_attr
);
408 write_console (" | | ", 7, coords2
, tx_attr
);
413 write_console (" -- ", 7, coords
, tx_attr
);
416 if (orientation
== 3)
419 for (ii
=0; ii
< 4; ii
++)
421 write_console (" ", 8, coords
, tx_attr
);
425 write_console (" ----- ", 8, coords
, tx_attr
);
428 write_console ("| | ", 8, coords
, tx_attr
);
433 write_console ( "ooooo", ii
, coords
, tx_attr
);
437 write_console ("| | ", 8, coords
, tx_attr
);
440 write_console ( "ooooo", ii
, coords
, tx_attr
);
444 write_console (" ----- ", 8, coords
, tx_attr
);
447 if (orientation
== 4)
456 write_console (" -- ", 7, coords
, tx_attr
);
458 for (ii
=0; ii
< 5; ii
++)
462 write_console (" |oo| ", 7, coords
, tx_attr
);
467 write_console (" | o| ", 7, coords
, tx_attr
);
471 write_console (" | | ", 7, coords
, tx_attr
);
475 write_console (" -- ", 7, coords
, tx_attr
);
478 write_console (" ", 7, coords
, tx_attr
);
483 Taxi (LPVOID _unused_thread_parm
)
485 int i
, ii
, j
, k
, f
, b
;
491 for (j
= 0; j
< 48; j
++) // taxi left
495 draw_taxi (3, coords
);
497 if (j
== 23) // station 3 for a passengers exit
499 int br3
= add_br (3, 0);
500 empty_st
= (br3
== 0);
503 f
= rand () % (16 - br3
); // passengers can be on the station
517 draw_taxi(0, coords
);
524 if (j
== 28) // station 3 for enter
526 int br3
= add_br (3, 0);
527 f
= rand () % (11 - w
); // passengers into taxi
530 if (br3
&& !empty_st
)
532 while (br3
> 0 && f
> 0)
536 br3
= add_br (3, -1);
540 draw_taxi(0, coords
);
549 for (i
= 0; i
< 10; i
++) // taxi up
553 draw_taxi(4, coords
);
555 if (i
== 4) // station 4 for exit
557 int br4
= add_br (4, 0);
558 empty_st
= (br4
== 0);
561 f
= rand () % (16 - br4
);
575 draw_taxi(0, coords
);
582 if (i
== 7) // station 4 for enter
584 int br4
= add_br (4, 0);
585 f
= rand () % (11 - w
);
588 if (br4
&& !empty_st
)
590 while (br4
> 0 && f
> 0)
594 br4
= add_br (4, -1);
598 draw_taxi(0, coords
);
607 for (k
= 0; k
< 48; k
++) // taxi rigth
611 draw_taxi (1, coords
);
613 if (k
== 19) // station 1 for exit
615 int br1
= add_br (1, 0);
616 empty_st
= (br1
== 0);
619 f
= rand () % (16 - br1
);
633 draw_taxi(0, coords
);
640 if (k
== 23) // station 1 for enter
642 int br1
= add_br (1, 0);
643 f
= rand () % (11 - w
);
645 if (br1
&& !empty_st
)
647 while (br1
> 0 && f
> 0)
651 br1
= add_br (1, -1);
655 draw_taxi(0, coords
);
664 for (i
= 0; i
< 9; i
++) // taxi down
668 draw_taxi (2, coords
);
670 if (i
== 4) // station 2 for exit
672 int br2
= add_br (2, 0);
673 empty_st
= (br2
== 0);
676 f
= rand () % (16 - br2
);
690 draw_taxi(0, coords
);
697 if (i
== 6) // station 2 for enter
699 int br2
= add_br (2, 0);
700 f
= rand () % (11 - w
);
702 if (br2
&& !empty_st
)
704 while (br2
> 0 && f
> 0)
708 br2
= add_br (2, -1);
712 draw_taxi(0, coords
);
722 ht2
= CreateThread (NULL
, 4096, Taxi
, NULL
, 0, NULL
); // endless loop
727 Si1 (LPVOID _unused_thread_parm
) // a passengers thread for the station 1
733 a
= 6 + rand () % 74; // a new passengers number, 6..79
746 write_console (" *", 2, coords
, si_attr
);
748 write_console ("* ", 2, coords
, si_attr
);
762 Si3 (LPVOID _unused_thread_parm
) // a passengers thread for the station 3
768 b
= 1 + rand () % 79;
781 write_console (" *", 2, coords
, si_attr
);
783 write_console ("* ", 2, coords
, si_attr
);
797 Si4 (LPVOID _unused_thread_parm
) // a passengers thread for the station 4
804 c
= 6 + rand () % 19; // a new passengers number, 6..24
810 write_console ("*", 1, coords
, si_attr
);
820 write_console (" ", 1, coords
, si_attr
);
834 Si2 (LPVOID _unused_thread_parm
) // a passengers thread for the station 2
840 d
= 1 + rand () % 24; // a new passengers number, 1..24
846 write_console ("*", 1, coords
, si_attr
);
857 write_console (" ", 1, coords
, si_attr
);
869 UINT oldcp
; // CodePage on the program start
870 CONSOLE_CURSOR_INFO old_ci
;
874 hstdout
= GetStdHandle (STD_OUTPUT_HANDLE
);
875 if (hstdout
== INVALID_HANDLE_VALUE
)
877 printf ("Error, can't get console handle\n");
883 oldcp
= GetConsoleOutputCP();
884 SetConsoleOutputCP(CP_UTF8
);
886 GetConsoleCursorInfo (hstdout
, &old_ci
);
890 CONSOLE_CURSOR_INFO new_ci
;
892 new_ci
.bVisible
= FALSE
;
893 new_ci
.dwSize
= old_ci
.dwSize
;
894 SetConsoleCursorInfo (hstdout
, &new_ci
);
902 SetConsoleOutputCP(oldcp
);
903 SetConsoleCursorInfo (hstdout
, &old_ci
);
909 CONSOLE_SCREEN_BUFFER_INFO csbi
;
913 SetConsoleTextAttribute (hstdout
, FOREGROUND_RED
|FOREGROUND_BLUE
|FOREGROUND_GREEN
);
914 GetConsoleScreenBufferInfo (hstdout
, &csbi
);
916 // printf ("csbi.dwSize.X=%u csbi.dwSize.Y=%u\n",
917 // csbi.dwSize.X, csbi.dwSize.Y);
920 coords
.X
=0; coords
.Y
=0;
921 SetConsoleCursorPosition (hstdout
, coords
);
922 FillConsoleOutputCharacterA(hstdout
, ' ', csbi
.dwSize
.X
* csbi
.dwSize
.Y
, coords
, &nocw
);
925 void write_console(const char *msg
, DWORD len
, COORD coords
, DWORD attr
)
929 WaitForSingleObject (hs_wc
, INFINITE
);
931 SetConsoleTextAttribute (hstdout
, attr
);
932 SetConsoleCursorPosition (hstdout
, coords
);
933 WriteConsole (hstdout
, msg
, len
, &len2
, NULL
);
935 ReleaseSemaphore (hs_wc
, 1, NULL
);
938 int add_br (int n
, int addon
)
942 WaitForSingleObject (hs_br
, INFINITE
);
945 ReleaseSemaphore (hs_br
, 1, NULL
);