4 (* wersja styczen 1999*)
5 #include "classes/gui.inc"
8 (* symulacja windy wersja 4, czerwiec 97 *)
9 (*------------------------------------------------------------------------*)
10 (* klasa definiujaca procedury graficzne *)
11 (*------------------------------------------------------------------------*)
12 UNIT graph : GUI CLASS;
16 MaxX = 640, MaxY = 480,
17 minDx = 50,minDy=70,maxDx= 600,maxDy=450,
26 UNIT waitt : PROCEDURE;
30 IF GUI_KeyPressed =/= 0 THEN exit FI;
34 unit ludzik : procedure(x,y,k:integer);
37 call GUI_LineTo(x,y+6,k);
38 call GUI_LineTo(x-2,y+10,k); (*??*)
40 call GUI_LineTo(x+2,y+10,k);
41 call GUI_move(x-2,y+2);
42 call GUI_LineTo(x+2,y+2,k);
43 call GUI_move(x-2,y+2);
44 call GUI_LineTo(x-4,y+4,k);
45 call GUI_move(x+2,y+2);
46 call GUI_LineTo(x+4,y+4,k)
49 unit COMMENT : procedure(ss : string);
51 call GUI_WriteText(250,460,unpack(ss),cyklamen,15)
56 (*----------------------------------------------------------------------*)
59 UNIT EcRAN : graph process(node :integer);
61 H = 30,(* odleglosc miedzy pietrami*)
62 xMAXw = 400, xMINw =200, yMaxW =400,
63 xpp = 405, xpl = 195, (* poczatkowe pozycje ludzikow*)
66 PIETRA : arrayof etage,
67 MAP : arrayof integer;
70 var GORA, DOL : arrayof boolean;
72 array GORA dim(1:20); (* 20 maksymalna liczba pasazerow na pietrze*)
77 UNIT obrazWindy : procedure(pietro : integer);
79 MAP := GUI_getImg(XminW,YmaxW-(pietro+1)*H, XmaxW-XminW,H);
82 UNIT RysujWinde : procedure(Y,kolor: integer);
85 CALL GUI_Rect(XminW,Y,XmaxW,Y+H,bialy,bialy)
87 call GUI_putImg(XminW,Y,MAP)
89 (* i wszystkich jej pasazerow *)
92 UNIT schody : procedure(i:integer);
97 call GUI_Line (500+(j+1)*6, YmaxW-i*H+(j-1)*3,
98 500+(j+1)*6,YmaxW-i*H+j*3,czarny);
99 call GUI_Line( 500+j*6,YmaxW-i*H+(j-1)*3,
100 500+j*6+6,YmaxW-i*H+(j-1)*3, czarny);
104 UNIT okno : procedure(i: integer);
106 call GUI_Rect(minDX+10,YmaxW-i*H,
107 minDX+30,YmaxW-i*H+20,czarny,c_yellow);
110 UNIT DOM : procedure(kolor,ile_pieter : integer);
111 (* szyb windy i pietra *)
114 call GUI_Rect(minDX,minDY,maxDX,maxDY,1,szary);
117 call GUI_Move(250,10);
118 call GUI_LineTo(minDX-20+i, 72,c_darkGrey);
121 CALL GUI_Rect(xMINw-2,yMaxW-(ile_pieter+1)*H,xMAXw+2,yMAXw,czarny,czarny);
122 for i := 0 to ile_pieter do
123 call GUI_move(minDX,yMaxW-i*H);
124 call GUI_LineTo(maxDX,yMAXw-i*H,c_red);
125 call GUI_WriteInt(MaxDx-20,yMAXw-i*H-12,i,k,czarny);
128 for i :=1 to ile_pieter do
129 call schody(i) ; call okno(i)
133 call GUI_move(minDX,yMAXw-i*H);
134 call GUI_LineTo(maxDX,yMAXw-i*H,c_black);
136 CALL GUI_Rect(xMINw,yMAXw-i*H,xMAXw,yMAXw,c_white,c_white);
137 for i:=YmaxW to maxDY do
138 call GUI_Line(xMinW,YmaxW,minDx,i,c_darkGrey)
140 for i:=YmaxW to maxDY do
141 call GUI_Line(xMaxW,YmaxW,maxDx,i,c_darkGrey)
145 unit JESTEM : procedure(gora:boolean,k,z:integer;output i:integer);
150 if not PIETRA(z).gora(j) then
151 PIETRA(z).gora(j):= true;
152 call ludzik(xpp+10*j,yp-z*H-12,k);
158 if not PIETRA(z).dol(j) then
159 PIETRA(z).dol(j):= true;
160 call ludzik(xpl-10*j,yp-z*H-12,k);
167 unit usunZpietra: procedure(gora: boolean,pietro,i : integer);
170 PIETRA(pietro).gora(i) := false;
171 call ludzik(xpp+10*i,yp-pietro*H-12,szary);
173 PIETRA(pietro).dol(i):= false;
174 call ludzik(xpl-10*i,yp-pietro*H-12,szary);
178 unit Guzik : procedure(gora:boolean,k,i : integer);
180 call GUI_WriteInt(MaxDx-20,yMAXw-i*H-12,i,k,czarny);
181 (* if gora then call GUI_Elipse() else fi; *)
184 unit otworz : procedure(gora: boolean, i: integer);
187 call GUI_Rect(xMAXw,yMAXw-(i+1)*H,xMAXw+2,yMAXw-(i)*H,szary,szary)
189 call GUI_Rect(xMINw,yMAXw-(i+1)*H,xMINw-2,yMAXw-(i)*H,szary,szary)
193 unit zamknij : procedure(gora:boolean,i: integer);
196 call GUI_Rect(xMAXw,yMAXw-(i+1)*H,xMAXw+2,yMAXw-(i)*H,czarny,czarny);
198 call GUI_Rect(xMINw,yMAXw-(i+1)*H,xMINw-2,yMAXw-(i)*H,czarny,czarny)
203 unit Koniec: procedure;
206 for i:=1 to 500 do i:=i od;
211 others call comment("handler EKRAN ");
216 array PIETRA dim(0:10);
217 for i := 0 to 10 do PIETRA(i) := new etage od;
218 CALL GUI_Rect(xminW,yMaxW-H,xmaxW,yMaxW,szary,szary);
219 call ObrazWindy(0); (* obraz windy pustej na parterze *)
222 accept RysujWinde, JESTEM, DOM, COMMENT,LUDZIK,
223 obrazWindy, GUZIK, usunZpietra, OTWORZ, ZAMKNIJ, KONIEC;
229 (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
232 UNIT LIFT : process(node,n,MAXp : integer, EKRAN : ecran);
233 (* n = ilosc pieter, MAXp = maxymalna ilosc pasazerow w windzie *)
234 (* ile = ilosc pasazerow aktualnie w windzie *)
236 minX =200, maxY = 400, maxX=400, H=30,
237 xMINw =200, xMAXw =400, yMAXw = 400,
244 VAR i,j,p,jedzNa, NaPietrze,ile : integer,
245 booo, kierunek, stoj : boolean,
246 PIETRA : arrayof guzik,
247 PRZYCISKI : arrayof boolean,
248 WWindzie : arrayof boolean;
250 UNIT opis : class( k,x,y : integer); (* opis pasazera*)
251 (* x,y odpowiada pozycji na pietrze lub w windzie *)
255 var WGORE, Wdol : boolean;
258 UNIT pauza : PROCEDURE(JakDlugo : integer);
261 for i :=1 to JakDlugo do i:=i od;
265 UNIT Wolam : procedure(Gora : boolean, pietro : integer);
268 PIETRA(pietro).wgore := true
270 PIETRA(pietro).wdol := true
272 call EKRAN.guzik(gora,czerwony,pietro)
275 UNIT PasazerWysiada : procedure(j : integer);
278 (* Wymazac go z windy *)
280 y := yMaxW - naPietrze*H;
281 call EKRAN.ludzik(xMINw+10*j,y-12,szary);
283 PRZYCISKI(naPietrze):= false;
284 call Ekran.ObrazWindy(naPietrze)
287 UNIT PasazerWsiada :procedure(z,na,k,poz:integer; output p:integer);
291 if not (naPietrze=z and kierunek=(z<na) and ile< maxP) then
294 (* Wymaz pasazera z pietra z=naPietrze*)
295 call EKRAN.UsunZpietra(z<na,naPIETRZE,poz);
296 y := yMaxw- naPietrze*H;
298 (* Wpisz go do windy *)
300 if not Wwindzie(j) then
307 call EKRAN.ludzik(xMAXw-10*i,y-12,k);
309 call EKRAN.ludzik(xMAXw-10*i,y-12,7);
312 call EKRAN.ludzik(xMINw+10*j,y-12,k);
318 call Ekran.RysujWinde(yMaxW-(naPietrze+1)*H,k);
319 call Ekran.Ludzik(xMinW+10*j,y-12,k);
320 PRZYCISKI(na):= true;
321 call Ekran.ObrazWindy(naPietrze)
325 UNIT PRZYJECHALA : function(p:integer) : boolean;
327 result := (naPietrze=p)
330 unit CZEKAM : procedure(i: integer);
331 begin(*winda czeka na pasazerow*)
332 call Ekran.Otworz(gora,i);
333 call Ekran.Otworz(dol,i);
334 enable PRZYJECHALA,PASAZERWSIADA, PASAZERWYSIADA;
336 call Ekran.Guzik(gora,czerwony,i);
337 call Ekran.Guzik(dol,czerwony,i);
338 (* return enable WOLAM,PRZYJECHALA,PASAZERWSIADA, PASAZERWYSIADA;*)
341 UNIT OtwieramDrzwi : procedure( i: integer);
343 call Ekran.Otworz(kierunek,i);
344 enable PRZYJECHALA,PASAZERWSIADA, PASAZERWYSIADA;
345 call Ekran.Guzik(kierunek,czerwony,i);
348 UNIT ZamykamDrzwi : procedure(gora:boolean, i: integer);
352 PIETRA(i).wgore := false else PIETRA(i).wdol := false
355 call Ekran.Zamknij(gora,i);
356 call Ekran.Guzik(gora,szary,i);
357 disable PRZYJECHALA,PASAZERwsIADA, PASAZERwySIADA;
360 UNIT KierunekJazdy : procedure;
365 if (kierunek= gora) then
366 for i := naPIETRZE+1 to n
368 if (PRZYCISKI(i) or PIETRA(i).wgore or PIETRA(i).wdol) then
371 if JedzNa=naPietrze then
372 for i := naPIETRZE-1 downto 0
374 if (PRZYCISKI(i) or PIETRA(i).wdol or PIETRA(i).wgore) then
378 else (*if kierunek= dol then *)
379 for i := naPIETRZE downto 0
381 if (PRZYCISKI(i) or PIETRA(i).wdol or PIETRA(i).wgore) then
384 if JedzNa= naPietrze then
385 for i := naPIETRZE+1 to n
387 if (PRZYCISKI(i) or PIETRA(i).wgore or PIETRA(i).wdol) then
392 stoj := (naPIETRZE=JEDZna);
393 if stoj then kierunek := not kierunek else
394 kierunek := naPietrze < JedzNa
399 unit JEDZ : procedure(gora:boolean);
402 call EKRAN.RysujWinde(YmaxW-(naPietrze+1)*H,7);
405 call EKRAN.RysujWinde(YmaxW-(naPietrze+1)*H -j,7);
407 call EKRAN.RysujWinde(YmaxW-(naPietrze+1)*H -j,15);
410 call EKRAN.RysujWinde(YmaxW-(naPietrze+2)*H,7)
414 call EKRAN.RysujWinde(YmaxW-(naPietrze+1)*H +j,7);
416 call EKRAN.RysujWinde(YmaxW-(naPietrze+1)*H +j,15);
419 call EKRAN.RysujWinde(YmaxW-(naPietrze)*H,7);
424 others call EKRAN.comment("handler LIFT");
430 array PIETRA dim(0:n);
431 for i:= 0 to n do PIETRA(i):= new guzik od;
432 array PRZYCISKI dim (0:n);
433 jedzNa := 0; naPietrze:=0;
434 array WWindzie dim(1: MAXp); (* 20 = max ilosc pasazerow *)
440 call EKRAN.RysujWinde(YmaxW-H, szary);
446 call CZEKAM(naPIETRZE);
447 for j := 1 to 10 do j := j od;
450 call ZamykamDrzwi(gora,naPIETRZE);
451 call ZamykamDrzwi(dol,naPIETRZE);
453 if kierunek = gora then
454 for i:= naPIETRZE+1 to JEDZna
456 (* jade na nastepne pietro *)
459 (*jezeli ktos czeka lub wysiada to zatrzymaj*)
460 if (PIETRA(i).wgore or PRZYCISKI(i)) then
462 call OtwieramDrzwi(i);
463 (* pasazerowie wsiadaja lub wysiadaja *)
464 for j := 1 to 1000 do j := j od;
465 call ZamykamDRZWI(gora,i);
469 (*if kierunek = dol*)
471 for i := naPIETRZE-1 downto jedzNA
476 if ( PIETRA(i).wdol or PRZYCISKI(i)) then
478 call OtwieramDrzwi(i);
479 (* pasazerowie wsiadaja/ wysiadaja*)
481 call ZamykamDrzwi(dol,i);
484 od (* jedz w dol NA*);
487 OD (* zachowania windy *);
491 (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
494 UNIT PASAZER : process(node:integer,ss: string,z,na,kolor : integer,
495 winda: lift,EKRAN : ecran);
498 jest,przyjechala,Wgore,wsiadlem : boolean;
502 call EKRAN.comment("handler PASAZER");
506 BEGIN (*** opis zachowania pasazera ***)
510 call EKRAN.JESTEM(Wgore,kolor,z,i);
511 (*powinien otrzymac inormacje o swojej aktualnej pozycji na pietrze*)
512 wsiadlem := false; przyjechala:= false;
514 while not wsiadlem do
515 call Winda.Wolam(Wgore,z);
516 call WINDA.PasazerWsiada(z,na,kolor,i,j);
517 (* otrzymal od windy numerek j m lub 0 gdy nie wsiadl*)
520 while not przyjechala do
521 przyjechala := WINDA.PRZYJECHALA(na)
523 call WINDA.PasazerWysiada(j);
525 (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
527 UNIT irandom : FUNCTION(a,b:INTEGER):INTEGER;
529 result := entier((b-a)*random + a)
535 (*===================================================================*)
536 VAR EKRAN : ecran, Winda : LIFT,
537 P : arrayof PASAZER,pp :PASAZER,
538 i,n,m,z,na,k : integer;
540 when signal1 : call EKRAN.comment("K O N I E C");
542 others call EKRAN.comment("handler PROGRAM GLOWNY ");
547 EKRAN := new Ecran(0);
553 Winda := new LIFT(0,n,10,EKRAN);
556 DO (* generowanie pasazerow *)
558 for i := 1 to irandom(1,5) do
559 na,z := irandom (0,n);
560 while z=na do na := irandom(0,n) od;
562 while k=7 do k := irandom (0,14) od;
564 pp:= new pasazer(0,"aa",z,na,k,winda,EKRAN);
572 call EKRAN.comment("CONTINUE? (y/n)");
573 while not (l = ord('y') or l = ord('n')) do
576 call EKRAN.comment(" ");
577 if l = ord('n') then raise signal1 fi;
584 (***********************************************************************)
611 call ramka(420,310,480,335);
612 call ramka(422,312,478,333);
613 call ramka(421,311,479,334);
619 if j=60 then j:=0;i:=i+1 fi;
628 unit ramka:iiuwgraph procedure(x1,y1,x2,y2:integer);
639 unit virtual affichage : procedure;
644 var e: elem, next : box;
648 var premier, dernier : box;
650 unit virtual first : function : elem;
658 unit virtual insert : procedure( e: elem);
673 unit virtual delete : procedure;
677 premier := premier.next;
681 unit virtual empty : function : boolean;
683 result := (premier=none)
691 unit wstep:procedure;
694 call ramka(230,120,480,220);
695 call ramka(228,118,482,222);
696 call ramka(226,116,484,224);
698 call outstring("Symulacja windy przy pomocy procesow");
700 call outstring("GM");
702 call outstring(" Pau czerwiec 97");
708 (* Strona tytulowa *)
709 CONTINUE_IKONA := new IKONA(szary,400,400,550,430,3," CONTINUE");
710 CALL ramka (1,5,0,0,638,478,ciemnoszary,szary,bialy,czarny);
711 CALL ramka (3,3,230,30,390,80,niebieski,szary,bialy,granatowy);
712 CALL Tytul (1,270,50,czarny,szary," LIFT SIMULATION ");
714 call CONTINUE_IKONA.write_i;
717 boo := getpress(xx,yy,i,l,r,z);
718 if z=1 and CZY(xx,yy,CONTINUE_IKONA) then exit fi
720 call CONTINUE_IKONA.push;
725 when MEMERROR : call comment("Zabraklo pamieci");
726 call waitt; call GROFF;
727 when ACCERROR : call comment("Reference to none ");
728 call waitt; call GROFF;
729 when LOGERROR : call comment("Niepoprawny Attach");
730 call waitt;call GROFF;
731 when CONERROR : call comment(" Array-index error ");
732 call waitt; call GROFF;
733 when SYSERROR : call comment("input-output error");
734 call waitt; call GROFF;
735 when NUMERROR : call comment("blad numeryczny");
736 call waitt; call GROFF;
737 others : call comment("Jakis blad ");
738 call waitt; call GROFF;
749 unit restore : procedure;
750 (* odnawia kolory wierzcholkow na ekanie *)
756 lista(i).kolor := zolty;
760 UNIT strzalka : procedure(A,B : node);
761 var r : real, cx,cy,dx,dy,ex,ey,delt,del : integer;
769 r := sqrt((b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x));
770 cx := b.x- entier((b.x-a.x)*del/r );
771 cy := b.y- entier((b.y-a.y)*del/r );
772 dx := b.x- entier((b.x-a.x)*(del+delt)/r + (b.y-a.y)*delt/r);
773 dy := b.y- entier((b.y-a.y)*(del+delt)/r - (b.x-a.x)*delt/r);
774 ex := b.x- entier((b.x-a.x)*(del+delt)/r - (b.y-a.y)*delt/r);
775 ey := b.y- entier((b.y-a.y)*(del+delt)/r + (b.x-a.x)*delt/r);
776 call move(dx,dy); call draw(cx,cy);
777 call move(ex,ey); call draw(cx,cy);
781 unit print : procedure;
782 var aux, aux1 : node, i : integer;
784 call patern(MinX,MinY+40,MaxX,MaxY,7,1);
788 call aux.affichage(zolty);
789 if not aux.lista.empty
791 aux1 := aux.lista.first;
794 call strzalka(aux,aux1);
795 aux1 := aux.lista.next;
803 array lista dim(1:10);
807 (*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
808 (* NODE - wierzcholek grafu *)
809 (* x,y pozycja na ekranie, nr numer wierzcholka *)
810 (* lista - lista wierzcholkow incydentnych *)
811 (*----------------------------------------------------------------------*)
812 unit node : elem class(x,y,nr: integer);
816 unit affichage : procedure(c: integer);
818 call cirb(x+3,y+3,5,5,0,3600,c,1);
819 call track(x+5,y+5,nr,gris,noir);
822 unit wypisz : procedure(i: integer);
823 (* wypisz kolejnosc odwiedzania wierzcholkow *)
826 for j := 0 to 160 do j:=j; call affichage(j mod 16 ) od;
828 if k = gris then k := noir fi;
830 call track(piszX+delta,piszY,nr,gris,k);
838 unit visite : function : boolean;
839 (* Czy wierzcholek byl juz odwiedzony *)
840 (* Wierzcholek odwiedzony dostaje kolor czarny*)
842 if kolor=noir then result := true;
843 else result := false; kolor := noir
848 lista := new liste; kolor := zolty;
851 unit clear : procedure(col, minX,minY,maxX,maxY : integer);
852 var i, j, sr : integer;
855 sr := (minX+maxX) div 2;
856 for i := 0 to (maxX - minX) div 2
858 call move( sr, maxY);
859 call draw(sr +i, minY);
861 call draw(sr -i, minY);
862 for j:=1 to 100 do j:=j od;
864 for i := 0 to (maxY - minY)
866 call move( sr, maxY);
867 call draw(maxX, minY+i);
869 call draw(minX, minY+i);
870 for j:=1 to 100 do j:=j od;
876 unit clear_all : procedure(col, minX,minY,maxX,maxY : integer);
880 for i := 1 to ((maxY - minY) div 2)
882 call patern(minX+i,minY+i,maxX-i,maxY-i,3,0);
883 for j:=1 to 200 do j:=j od;
887 unit waittt : procedure;
888 var x,y,i,l,r,z : integer,boo : boolean;
890 call outstring(maxX-100,maxY+25, "CONTINUE",zielony,noir);
892 while z=0 do boo := getpress(x,y,i,l,r,z) od;
893 call outstring(maxX-100,maxY+25, " ",gris,gris);