Add a demo.bat file to the examples directory on Windows
[tinycc.git] / win32 / examples / taxi_simulator.c
blob8650f4961c3eb070be666df64729d1da45ffdafe
1 /* A Windows console program: taxi and passengers simulator */
3 #include <windows.h>
4 #include <wincon.h>
5 #include <stdio.h>
6 #include <conio.h>
7 #include <stdlib.h>
8 #include <time.h>
10 void init_scr();
11 void restore_scr();
12 void clrscr();
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
23 HANDLE hstdout;
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;
38 static
39 void draw_statistics()
41 char msg[100];
42 COORD coords;
44 WaitForSingleObject (hs_ds, INFINITE);
46 coords.X = 0;
47 coords.Y = 0;
49 sprintf (msg, "station1=%d \n", br[1]);
50 write_console (msg, strlen(msg), coords, si_attr);
52 coords.Y++;
53 sprintf (msg, "station2=%d \n", br[2]);
54 write_console (msg, strlen(msg), coords, si_attr);
56 coords.Y++;
57 sprintf (msg, "station3=%d \n", br[3]);
58 write_console (msg, strlen(msg), coords, si_attr);
60 coords.Y++;
61 sprintf (msg, "station4=%d \n", br[4]);
62 write_console (msg, strlen(msg), coords, si_attr);
64 coords.Y++;
65 sprintf (msg, "taxi=%d \n", w);
66 write_console (msg, strlen(msg), coords, si_attr);
68 ReleaseSemaphore (hs_ds, 1, NULL);
71 static
72 void draw_station(int station)
74 char msg[100];
75 COORD coords;
76 int j;
78 WaitForSingleObject (hs_st, INFINITE);
80 if (station == 1)
82 int br1, n, c;
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);
90 br1 = add_br (1, 0);
91 coords.X = 40;
92 c = 3;
93 while (c-- > 0)
95 n = 5;
96 if (br1 < 5)
97 n = br1;
99 if (n != 0)
100 for (j = 5; j > 5-n; j--)
102 coords.Y = j - 1;
103 write_console ("*", 1, coords, si_attr);
106 if (n != 5)
107 for (j = 5-n; j > 0; j--)
109 coords.Y = j - 1;
110 write_console (" ", 1, coords, si_attr);
113 coords.X++;
114 br1 -= n;
117 else
118 if (station == 3)
120 int br3, n, c;
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);
128 br3 = add_br (3, 0);
129 coords.X = 33;
130 c = 3;
131 while (c-- > 0)
133 n = 5;
134 if (br3 < 5)
135 n = br3;
137 if (n != 0)
138 for (j = 0; j < n; j++)
140 coords.Y = 20 + j;
141 write_console ("*", 1, coords, si_attr);
144 if (n != 5)
145 for (j = n; j < 5; j++)
147 coords.Y = 20 + j;
148 write_console (" ", 1, coords, si_attr);
151 coords.X--;
152 br3 -= n;
155 else
156 if (station == 2)
158 int br2, n, c;
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--)
166 coords.Y = j;
167 write_console ("|", 1, coords, st_attr);
170 br2 = add_br (2, 0);
171 coords.Y = 13;
172 c = 3;
173 while (c-- > 0)
175 n = 5;
176 if (br2 < 5)
177 n = br2;
179 coords.X = 79;
180 write_console (" ", 1, coords, si_attr);
182 coords.Y++;
183 coords.X = 68;
184 write_console ("*****", br2, coords, si_attr);
186 coords.X = 68+n;
187 write_console (" ", 11-n, coords, si_attr);
189 coords.Y++;
190 coords.X = 79;
191 write_console (" ", 1, coords, si_attr);
193 coords.Y--;
194 br2 -= n;
197 else
198 if (station == 4)
200 int br4, n, c;
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++)
208 coords.Y = j;
209 write_console ("|", 1, coords, st_attr);
212 coords.Y = 9;
213 br4 = add_br (4, 0);
214 c = 3;
215 while (c-- > 0)
217 n = 5;
218 if (br4 < 5)
219 n = br4;
221 coords.X = 0;
222 write_console (" ", 1, coords, si_attr);
224 coords.Y++;
225 write_console (" ", 10, coords, si_attr);
227 coords.X = 10 - n;
228 write_console ("**********", n, coords, si_attr);
230 coords.Y++;
231 coords.X = 0;
232 write_console (" ", 1, coords, si_attr);
234 coords.Y--;
235 br4 -= n;
239 ReleaseSemaphore (hs_st, 1, NULL);
243 main (void)
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
251 init_scr();
253 printf ("Taxi and passengers simulator:\n");
254 while (1)
256 printf (" enter a max passengers number on the stations (0..20) = ");
257 scanf ("%d", &N);
258 if ((N >= 0) && (N<=20))
259 break;
261 while (1)
263 printf (" enter a passengers on the taxi (0..10) = ");
264 scanf ("%d", &w);
265 if ((w >= 0) && (w<=10))
266 break;
268 init_scr();
270 srand (time (0));
271 br1 = rand () % 6; // passngers on the station1, 0..5
272 if (br1 > N)
273 br1 = N;
275 br2 = rand () % 6;
276 if (br2 > N - br1)
277 br2 = N - br1;
279 br3 = rand () % 6;
280 if (br3 > N - br1 - br2)
281 br3 = N - br1 - br2;
283 br4 = N - br1 - br2 - br3;
284 while (br4 > 5)
286 br4--;
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);
297 draw_statistics();
298 for (i=1; i<=4; i++)
299 draw_station(i);
301 htaxi = CreateThread (NULL, 4096, Taxi, NULL, 0, NULL);
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);
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);
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);
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);
327 getch ();
328 restore_scr();
329 return 0;
332 static
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;
340 old_coords = coords;
342 else {
343 orientation = old_orientation;
344 coords = old_coords;
347 if (orientation == 1)
349 int f, b, ii;
350 f = 5;
351 if (w < 5)
352 f = w;
353 b = w - f;
355 write_console (" ----- ", 8, coords, tx_attr);
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;
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;
369 coords.Y++;
370 write_console (" ----- ", 8, coords, tx_attr);
372 for (ii=0; ii<5; ii++)
374 coords.Y++;
375 write_console (" ", 8, coords, tx_attr);
378 else
379 if (orientation == 2)
381 COORD coords2;
382 int f, b, ii;
384 f = 5;
385 if (f > w)
386 f = w;
387 b = w - f;
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);
395 for (ii=0; ii < 5; ii++)
397 coords2.Y = coords.Y + 5 - ii;
398 if (f && b) {
399 write_console (" |oo| ", 7, coords2, tx_attr);
400 f--; b--;
402 else
403 if (f) {
404 write_console (" |o | ", 7, coords2, tx_attr);
405 f--;
407 else {
408 write_console (" | | ", 7, coords2, tx_attr);
412 coords.Y += 6;
413 write_console (" -- ", 7, coords, tx_attr);
415 else
416 if (orientation == 3)
418 int ii;
419 for (ii=0; ii < 4; ii++)
421 write_console (" ", 8, coords, tx_attr);
422 coords.Y++;
425 write_console (" ----- ", 8, coords, tx_attr);
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--;
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--;
443 coords.Y++;
444 write_console (" ----- ", 8, coords, tx_attr);
446 else
447 if (orientation == 4)
449 int f, b, ii;
451 f = 5;
452 if (f > w)
453 f = w;
454 b = w - f;
456 write_console (" -- ", 7, coords, tx_attr);
458 for (ii=0; ii < 5; ii++)
460 coords.Y++;
461 if (f && b) {
462 write_console (" |oo| ", 7, coords, tx_attr);
463 f--; b--;
465 else
466 if (f) {
467 write_console (" | o| ", 7, coords, tx_attr);
468 f--;
470 else
471 write_console (" | | ", 7, coords, tx_attr);
474 coords.Y++;
475 write_console (" -- ", 7, coords, tx_attr);
477 coords.Y++;
478 write_console (" ", 7, coords, tx_attr);
482 DWORD WINAPI
483 Taxi (LPVOID _unused_thread_parm)
485 int i, ii, j, k, f, b;
486 int empty_st;
487 COORD coords;
488 DWORD len;
489 char msg[100];
491 for (j = 0; j < 48; j++) // taxi left
493 coords.X = 59 - j;
494 coords.Y = 11;
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);
502 srand (time (0));
503 f = rand () % (16 - br3); // passengers can be on the station
505 if (w)
507 while(f)
509 if (w==0)
510 break;
512 f--;
513 w--;
514 add_br (3, 1);
515 draw_statistics();
516 draw_station(3);
517 draw_taxi(0, coords);
518 Sleep (300);
520 Sleep (3000);
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)
534 f--;
535 w++;
536 br3 = add_br (3, -1);
538 draw_statistics();
539 draw_station(3);
540 draw_taxi(0, coords);
541 Sleep (300);
543 Sleep (3000);
546 Sleep (300);
549 for (i = 0; i < 10; i++) // taxi up
551 coords.X = 12;
552 coords.Y = 15 - i;
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);
560 srand (time (0));
561 f = rand () % (16 - br4);
563 if (w)
565 while(f)
567 if (w==0)
568 break;
570 f--;
571 w--;
572 add_br (4, 1);
573 draw_statistics();
574 draw_station(4);
575 draw_taxi(0, coords);
576 Sleep (300);
578 Sleep (3000);
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)
592 f--;
593 w++;
594 br4 = add_br (4, -1);
596 draw_statistics();
597 draw_station(4);
598 draw_taxi(0, coords);
599 Sleep (300);
601 Sleep (3000);
604 Sleep (300);
607 for (k = 0; k < 48; k++) // taxi rigth
609 coords.X = 12 + k;
610 coords.Y = 5;
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);
618 srand (time (0));
619 f = rand () % (16 - br1);
621 if (w)
623 while(f)
625 if (w==0)
626 break;
628 f--;
629 w--;
630 add_br (1, 1);
631 draw_statistics();
632 draw_station(1);
633 draw_taxi(0, coords);
634 Sleep (300);
636 Sleep (3000);
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)
649 f--;
650 w++;
651 br1 = add_br (1, -1);
653 draw_statistics();
654 draw_station(1);
655 draw_taxi(0, coords);
656 Sleep (300);
658 Sleep (3000);
661 Sleep (300);
664 for (i = 0; i < 9; i++) // taxi down
666 coords.X = 60;
667 coords.Y = 3 + i;
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);
675 srand (time (0));
676 f = rand () % (16 - br2);
678 if (w)
680 while(f)
682 if (w==0)
683 break;
685 f--;
686 w--;
687 add_br (2, 1);
688 draw_statistics();
689 draw_station(2);
690 draw_taxi(0, coords);
691 Sleep (300);
693 Sleep (3000);
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)
706 f--;
707 w++;
708 br2 = add_br (2, -1);
710 draw_statistics();
711 draw_station(2);
712 draw_taxi(0, coords);
713 Sleep (300);
715 Sleep (3000);
719 Sleep (300);
722 ht2 = CreateThread (NULL, 4096, Taxi, NULL, 0, NULL); // endless loop
723 return 0;
726 DWORD WINAPI
727 Si1 (LPVOID _unused_thread_parm) // a passengers thread for the station 1
729 int a, j, n;
730 COORD coords;
732 srand (time (0));
733 a = 6 + rand () % 74; // a new passengers number, 6..79
735 while (a != 40)
737 if (a < 40)
738 a++;
739 else
740 a--;
742 coords.X = a;
743 coords.Y = 0;
745 if (a < 40)
746 write_console (" *", 2, coords, si_attr);
747 else
748 write_console ("* ", 2, coords, si_attr);
750 Sleep (1000);
753 add_br (1, 1);
754 draw_station(1);
755 draw_statistics();
757 Sleep (1000);
758 return 0;
761 DWORD WINAPI
762 Si3 (LPVOID _unused_thread_parm) // a passengers thread for the station 3
764 int b, j, n;
765 COORD coords;
767 srand (time (0));
768 b = 1 + rand () % 79;
770 while (b != 33)
772 if (b < 33)
773 b++;
774 else
775 b--;
777 coords.X = b;
778 coords.Y = 24;
780 if (b < 33)
781 write_console (" *", 2, coords, si_attr);
782 else
783 write_console ("* ", 2, coords, si_attr);
785 Sleep (1000);
788 add_br (3, 1);
789 draw_station(3);
790 draw_statistics();
792 Sleep (1000);
793 return 0;
796 DWORD WINAPI
797 Si4 (LPVOID _unused_thread_parm) // a passengers thread for the station 4
800 int c, j, n;
801 COORD coords;
803 srand (time (0));
804 c = 6 + rand () % 19; // a new passengers number, 6..24
806 coords.X = 0;
807 while (c != 10)
809 coords.Y = c;
810 write_console ("*", 1, coords, si_attr);
812 if (c < 10) {
813 c++;
814 coords.Y--;
816 else {
817 c--;
818 coords.Y++;
820 write_console (" ", 1, coords, si_attr);
822 Sleep (1000);
825 add_br (4, 1);
826 draw_station(4);
827 draw_statistics();
829 Sleep (1000);
830 return 0;
833 DWORD WINAPI
834 Si2 (LPVOID _unused_thread_parm) // a passengers thread for the station 2
836 int d, j, n;
837 COORD coords;
839 srand (time (0));
840 d = 1 + rand () % 24; // a new passengers number, 1..24
842 coords.X = 79;
843 while (d != 14)
845 coords.Y = d;
846 write_console ("*", 1, coords, si_attr);
847 if (d < 14)
849 d++;
850 coords.Y--;
852 else
854 d--;
855 coords.Y++;
857 write_console (" ", 1, coords, si_attr);
858 Sleep (1000);
861 add_br (2, 1);
862 draw_station(2);
863 draw_statistics();
865 Sleep (1000);
866 return 0;
869 UINT oldcp; // CodePage on the program start
870 CONSOLE_CURSOR_INFO old_ci;
872 void init_scr()
874 hstdout = GetStdHandle (STD_OUTPUT_HANDLE);
875 if (hstdout == INVALID_HANDLE_VALUE)
877 printf ("Error, can't get console handle\n");
878 exit (1);
881 if (oldcp == 0)
883 oldcp = GetConsoleOutputCP();
884 SetConsoleOutputCP(CP_UTF8);
886 GetConsoleCursorInfo (hstdout, &old_ci);
888 else
890 CONSOLE_CURSOR_INFO new_ci;
892 new_ci.bVisible = FALSE;
893 new_ci.dwSize = old_ci.dwSize;
894 SetConsoleCursorInfo (hstdout, &new_ci);
897 clrscr ();
900 void restore_scr()
902 SetConsoleOutputCP(oldcp);
903 SetConsoleCursorInfo (hstdout, &old_ci);
904 clrscr ();
907 void clrscr()
909 CONSOLE_SCREEN_BUFFER_INFO csbi;
910 DWORD nocw;
911 COORD coords;
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);
918 // getch ();
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)
927 DWORD len2;
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)
940 int new;
942 WaitForSingleObject (hs_br, INFINITE);
943 br[n] += addon;
944 new = br[n];
945 ReleaseSemaphore (hs_br, 1, NULL);
947 return new;