wyjasnienie­a

with Sem95; use Sem95;

with Ekran; use Ekran;

with Randompackage;

use Randompackage;

with Gnat.Io;-- cale with i use pozwalaja na korzystanie z zewnetrznych pakietow

use Gnat.Io;

with Winconsoleex;

use Winconsoleex;

-- przy zmiennych bedacych talbiacami, lub wsakznikami na nie (x,y) to indeksowanie po eleementach ,jak w c []

procedure Main is-- glowny program poniezej deklaracja zmiennych

Random_Sem: Semafor_Binarny(1);--semafor dostepu do generatora liczb pseudo losowych

procedure Getrandom( Wynik : out Integer ; Max : in Integer) is--procedura zwracaja liczbe preuso losowa w zakresie 1..max (lacznie)

begin --out przy parametrze oznacza ,ze zapis do tej zmiennej jest zapisywany na zewnatrz, czyli tak jakbysmy w c++ referencje dali

Pb(Random_Sem);--czekaj na semaforze

Wynik := Randomint(Max);

Vb(Random_Sem);--zwolnij semafor

end Getrandom;

Ekran : Screen;--nasz obiekt do rysowania po ekranie

task type Person ;-- deklaracja zapowiadajaca typu person

type Personptr is access Person;-- deklaracja wskaznika na person

type Personarray is array(Integer range <>) of Personptr;--deklaracja tablicy wskaznikow na person

type Personaptr is access Personarray;--deklaracja wsakznika na tablice wskanikow na person,

task type Elevator(Id :Integer) ;--tu podobnie jak wyzej, id to numer windy, bedzie to znmienna dostapna w obiekcie windy

type Elevatorptr is access Elevator;

type Elevatorarray is array(Integer range <>) of Elevatorptr;

type Elevatoraptr is access Elevatorarray;

type Integerarray is array( Integer range <>) of Integer;

type Integeraptr is access Integerarray;

type Integer2darray is array( Integer range <>,Integer range<>) of Integer;--tablica 2 wymiarowa

type Integer2daptr is access Integer2darray;

Queue_Sem : Semafor_Binarny(1);--semafor dostepu do kolejki

type Queue is--deklaracja typu kolejki jak struct w c

record

Czeka : Integer :=0;-- liczba osob dczekajacyh w kolejce

Zwolniono: Integer :=0;-- liczba osob ktore moga oposcic kolejke

Ypos,Xpos: Integer;--polozenie gdzie bedzie wystielana liczba osob czekajacych

end record;

type Queue2darray is array( Integer range <>,Integer range<>) of Queue;

type Queue2daptr is access Queue2darray;

Kolejkaup :Queue2daptr ;-- kolejki up down out jak w javie

Kolejkadown : Queue2daptr ;

Kolejkaout : Queue2daptr ;

procedure Qget(Qtype ,X,Y :Integer; Val : out Integer) is-- procedura zwraca liczbe osob czekajacch ,x - numer windy, y- numer pietra, qtype okresla ktora kolejka 0 - kolejka up, 1 down 2 out

begin--mialem napisane bardizej czytelne procedury,ale nei dzialaly do konca, wiec taki koszmarny kod jest, ogolnie to wszedzie jest sprawdzane jaki qtyle jest i odwoluywane jest do kolejkaup, down lub out

Pb(Queue_Sem);

if Qtype = 0 then

Val:= Kolejkaup(X,Y).Czeka;

else

if Qtype = 1 then

Val:= Kolejkadown(X,Y).Czeka;-- ogolnie tu nam tylko zwraca wartosc czekajacyh w k olejce

else

Val:= Kolejkaout(X,Y).Czeka;

end if;

end if;

Vb(Queue_Sem);

end Qget;

procedure Qrelease(Qtype ,X,Y :Integer) is-- zwalnia jedna osobe w kolejce

begin

Pb(Queue_Sem);

if Qtype = 0 then

Kolejkaup(X,Y).Zwolniono:= Kolejkaup(X,Y).Zwolniono +1;-- ustawia ze moze wyjsc jedna osoba wiecej

else

if Qtype = 1 then

Kolejkadown(X,Y).Zwolniono:= Kolejkadown(X,Y).Zwolniono +1;

else

Kolejkaout(X,Y).Zwolniono:= Kolejkaout(X,Y).Zwolniono +1;

end if;

end if;

Vb(Queue_Sem);

end Qrelease;

procedure Qreleaseall(Qtype ,X,Y :Integer) is-- zwalnia wszyskie osoby w kolejce, wtedy zwolniono = tyle co czeka

begin

Pb(Queue_Sem);

if Qtype = 0 then

Kolejkaup(X,Y).Zwolniono:= Kolejkaup(X,Y).Czeka ;

else

if Qtype = 1 then

Kolejkadown(X,Y).Zwolniono:= Kolejkadown(X,Y).Czeka ;

else

Kolejkaout(X,Y).Zwolniono:= Kolejkaout(X,Y).Czeka ;

end if;

end if;

Vb(Queue_Sem);

end Qreleaseall;

procedure Qenter(Qtype ,X,Y :Integer) is--wejscie do kolejki ,wyswietla zmiany na ekranie wartosci czeka

begin

Pb(Queue_Sem);

if Qtype = 0 then

Kolejkaup(X,Y).Czeka:= Kolejkaup(X,Y).Czeka+1 ;--zwieksza w kolejce liczbe czekajacych o 1

Ekran.Putati(Kolejkaup(X,Y).Ypos,Kolejkaup(X,Y).Xpos,Kolejkaup(X,Y).Czeka);

else

if Qtype = 1 then

Kolejkadown(X,Y).Czeka:= Kolejkadown(X,Y).Czeka+1 ;

Ekran.Putati(Kolejkadown(X,Y).Ypos,Kolejkadown(X,Y).Xpos,Kolejkadown(X,Y).Czeka);

else

Kolejkaout(X,Y).Czeka:= Kolejkaout(X,Y).Czeka +1;

Ekran.Putati(Kolejkaout(X,Y).Ypos,Kolejkaout(X,Y).Xpos,Kolejkaout(X,Y).Czeka);

end if;

end if;

-- Ekran.Putati(Q.Ypos,Q.Xpos,Q.Czeka);

Vb(Queue_Sem);

loop-- teraz w petli sprawdza czy moze wyjsc( liczba osob do zwolnienia jest >0 ) wtedy zminejsza liczbe ktora moze wyjsc o 1 i wychodzi z petli (exit)

Pb(Queue_Sem);

-- Ekran.putati(q.ypos,q.xpos+2,Q.zwolniono);

if Qtype = 0 then

if Kolejkaup(X,Y).Zwolniono >0 then

Kolejkaup(X,Y).Zwolniono := Kolejkaup(X,Y).Zwolniono -1;

Vb(Queue_Sem);

exit;

end if;

else

if Qtype = 1 then

if Kolejkadown(X,Y).Zwolniono >0 then

Kolejkadown(X,Y).Zwolniono := Kolejkadown(X,Y).Zwolniono -1;

Vb(Queue_Sem);

exit;

end if;

else

if Kolejkaout(X,Y).Zwolniono >0 then

Kolejkaout(X,Y).Zwolniono := Kolejkaout(X,Y).Zwolniono -1;

Vb(Queue_Sem);

exit;

end if;

end if;

end if;

Vb(Queue_Sem);

end loop;

Pb(Queue_Sem);

if Qtype = 0 then

Kolejkaup(X,Y).Czeka:= Kolejkaup(X,Y).Czeka-1 ;-- a tu teraz mniejsza liczbe osob czekajacych w kolejce

Ekran.Putati(Kolejkaup(X,Y).Ypos,Kolejkaup(X,Y).Xpos,Kolejkaup(X,Y).Czeka);

else

if Qtype = 1 then

Kolejkadown(X,Y).Czeka:= Kolejkadown(X,Y).Czeka-1 ;

Ekran.Putati(Kolejkadown(X,Y).Ypos,Kolejkadown(X,Y).Xpos,Kolejkadown(X,Y).Czeka);

else

Kolejkaout(X,Y).Czeka:= Kolejkaout(X,Y).Czeka-1 ;

Ekran.Putati(Kolejkaout(X,Y).Ypos,Kolejkaout(X,Y).Xpos,Kolejkaout(X,Y).Czeka);

end if;

end if;

Vb(Queue_Sem);

end Qenter;

Elevatorcount : Integer;--liczba wind

Personcount : Integer;-- liczba osob

Floorcount : Integer;--jak w javie :)

Elevatorcapacity : Integer:=3;

Canenter : Integer2daptr;--tablica okreslajace ile osob moze wejsc do windy na danym pietrze

Canmove : Integeraptr;--w javie robiliscmy signal do sygnalizowania windzie ze moze ruszyc,teraz canMove(numer_windy) = 1 to winda rusza

W_Windzie: Integeraptr;--liczba osob w danej windzie

-- Changeq_Sem : Semafor_Binarny(1);--semafor ,cos nei potrzebny :D

Canenter_Sem : Semafor_Binarny(1);-- semafor dostepu do zmiennych canEnter

Elevator_Sem :Semafor_Binarny(1);--semafor dostepu do danych windy

-- Test: Queue ;-- tylko do mych testow

------------------------------------------------------------------------

task body Person is--typ osoby definicja

X,Y : Integer;--aktualna pozycja

Oldx,Oldy : Integer;--stara pozycja przed ruchem, potrzebne przy rysowania znaku osoby, w starym miejscu jest czyszczone

Btemp : Boolean ;--zmiena tymczasowa uzywana,lub nie poxniej

Dir : Integer;--nie wszystko jest uzywane, niektore mienne tlkyo tymczasowo uzywane, nei mozna w adzie gdzie sie che deklarowac zmiennych jak w c

Movespeed : constant Duration:= 0.45;--czas czekania osoby po wukonaiu ruchu

Temp : Integer;

Celw: Integer;--numer windy do ktorej chemy wejsc

Celp: Integer;--numer pietra na tkore chem wejsc

-- Pokoj : Integer;

Pietro: Integer;--aktualne peitro na jakim jestesmy

Temp2 : Integer;

Reached: Boolean;--czy doszlismy do celu, jak w javie

procedure Hide is-- schowaj znak postaci, rysuje tam spacje, pamietaj ,ze uklad wpoldzenych na ekranie jest od 1 nie od 0 jak w javie oraz pierwszy parametr to os y,a potem x

begin

Ekran.Putat(Y,X," ");

end Hide;

procedure Show is--odwrotnosc hide

begin

Ekran.Putat(Y,X,"p");

end Show;

procedure Move( Yr, Xr: Integer) is--move jak w javie

begin

Oldx:= X;

Oldy:= Y;

X:= X + Xr;

Y:= Y + Yr;

Ekran.Drawat(Oldy,Oldx,Y,X,'p');--na starej pozycji czysci pole (stawia spacje) na nowej stawia p

delay Movespeed;

end Move;

procedure Movetox( Xto : Integer)is-- jak w javie

Di : Integer:=-1;

begin

if Xto > X then

Di:=1;

end if;

loop

if X = Xto then

exit;

end if;

Move(0,Di);

end loop;

end Movetox;

procedure Movetoy( Yto : Integer)is-- jak w javie

Di : Integer:=-1;

begin

if Yto > Y then

Di:=1;

end if;

loop

if Y = Yto then

exit;

end if;

Move(Di,0);

end loop;

end Movetoy;

begin--tu sie zaczyna kod watku osoby

Getrandom(Pietro,Floorcount);--wylosuj pietro na ktorym zaczynamy

X:=3;

Y:=Pietro*2+1;--ustaw pozycje poczatkowa

Show;

Reached:=True;--ustawiane na true, by od razu wylosowac nowe miejsce

loop

<<petla_begin>>-- to jest etykieta, goto pela_begin; to skok bezwarunkowy w to miejsce

if Reached then-- gdy doszlismy do celu

Reached :=False;

celp:=pietro;

while celp = pietro loop-- losuj pietro dopuki wypadnie jakies inne niz na ktorym jestesmy

Getrandom(Celp,Floorcount);

end loop;

end if;

Getrandom(Celw,Elevatorcount);--wylosuj docelowa winde

getrandom(temp,100);-- niestety nei wiem jak czas odmierzac w adzie, wiec ludziki losowa korzystaja ze schodow

if temp <15 then

Movetox(2);--idz w lewo na schody

if celp > pietro then--w zaleznosci czy pietro docelowe jest wyzej czy nizej

move(1,0);--idz w dol

move(1,0);

pietro := pietro+1;--jestesmy na nizszym pietrze

else

move(-1,0);--idz w gore

move(-1,0);

pietro:= pietro-1;

end if;

move(0,1);

move(0,1);--sun sie troche w prawo

if pietro=celp then--jak schodami doszlismy do celu to

reached:=true;

end if;

goto petla_begin;--skaczemy na poczatek petli, by znowu sobie cel obrac jezeli doszlismy

end if;

Movetox(Celw*2+2);--podejdz pod winde

<<nospace>>

--if Canenter(Celw,Pietro)= 0 then

if Celp > Pietro then--czekaj w odpowiedniej kolejce up lub down w zaleznosci od celu

Qenter(1,Celw,Pietro);

else

Qenter(0,Celw,Pietro);

end if;

--end if;

Move(0,1);

Hide;

Pb(Canenter_Sem);

Canenter(Celw,Pietro):= Canenter(Celw,Pietro) -1;--zmniejsz liczbe osob mogacych wejsc do windy

-- ekran.putati(1+ (pietro-1) *4+1,Elevatorcount*2+4+ celw*3+1,canenter(celw,pietro));

if Canenter(Celw,Pietro) < 0 then--jak zabraklo miejsca to sie wycofaj i powroc do kolejki

Vb(Canenter_Sem);

move(-1,0);

goto nospace;

end if;

if Canenter(Celw,Pietro) = 0 then-- jak juz ostatnia osoba weszla to

Pb(Elevator_Sem);

Canmove(Celw) := 1;--zasygnaluzuj windzie ze moze ruszac

Vb(Elevator_Sem);

end if;

Pb(Elevator_Sem);

W_Windzie(Celw) := W_Windzie(Celw) +1;--zwiekszamy informacje ile jest w windzie

Vb(Elevator_Sem);

Vb(Canenter_Sem);

Qenter(2,Celw,Celp);--czekamy w kolejce wyjscia na naszym pietrze docelowym

Pb(Elevator_Sem);

W_Windzie(Celw) := W_Windzie(Celw) -1;--zmniejszamy liczbe osob w windzie

Vb(Elevator_Sem);

Reached:=True;--jestesmy u celu

Pietro:=Celp;

Y:=Pietro*2+1;

Show;

Move(0,-1);--powrot na poczatek petli

end loop;

end Person;

------------------------------------------------------------------------

task body Elevator is--zadanie windy

Y : Integer := 2;--pozycje

X: Integer;

Czeka : Integer;--ile osob czeka w kolejce

Pietro : Integer:= 1;--pietro na ktorym jest winda

Dir : Integer :=1;--kierunek ruchu windy

Temp,Temp2,Temp3: Integer;

Elevatorspeed : constant Duration :=1.5;

begin

X:=Id*2+3;--ustaw pozycje poczatkowa

Ekran.Putat(Y,Id*2+3,"w");

loop

if Pietro= 1 then--jak doszlismy na krance to trzeba zmienic kierunek ruchu

Dir:= 1;

end if;

if Pietro= Floorcount then

Dir :=-1;

end if;

if Dir = -1 then--w zaleznosci od kierunku ruchu pobieramy liczbe osob czekajacyh w danej kolejce

Qget(0,Id,Pietro,Czeka);

else

Qget(1,Id,Pietro,Czeka);

end if;

Qreleaseall(2,Id,Pietro);--zwalniamy wszystkich czekajacych na wyjscie na tym pietrze

if Czeka >0 and w_windzie(id) < elevatorCapacity then--jezeli ktos czeka na wejsci i jest jeszcze iejsce

Pb(Elevator_Sem);

Canmove(Id) := 0;--ustaw ze winda stoi w miejscu

-- Ekran.Putati(id,42,canMove(id));

Vb(Elevator_Sem);

Pb(Elevator_Sem);

Temp2 := W_Windzie(Id);--pobierz i zapisz w tymczasowiej zmiennej ile jest w windzie osob

Vb(Elevator_Sem);

Pb(Canenter_Sem);

Canenter(Id,Pietro):= Elevatorcapacity - Temp2;

if Canenter(Id,Pietro) > Czeka then--wyznacz ile moze wejsc ,jak w javie

Canenter(Id,Pietro) := Czeka;

end if;

-- ekran.putati(1+ (pietro-1) *4+1,Elevatorcount*2+4+ id*3+1,canenter(id,pietro));

Temp2:= Canenter(Id,Pietro);

Vb(Canenter_Sem);

if Temp2 >0 then

for I in 1..Temp2 loop--zwolnij tyle osob ile moze wejsc

if Dir = -1 then

Qrelease(0,Id,Pietro);

else

Qrelease(1,Id,Pietro);

end if;

end loop;

end if;

loop--- czekaj az mozna ruszyc

Pb(Elevator_Sem);

if Canmove(Id) = 1 then

Vb(Elevator_Sem);

exit;

end if;

Vb(Elevator_Sem);

end loop;

end if;

Ekran.Putati(id,Elevatorcount*2+4+ elevatorCount*3+3,w_windzie(id));

-- Ekran.Putati(id,42,canMove(id));

Ekran.Putat(Y,X," ");

Y:= Y + Dir*2;--przswua i rysuje znaczek windy

Pietro:= Pietro+Dir;

Ekran.Putat(Y,X,"w");

delay Elevatorspeed;

getrandom(temp,100);--losowa wartosc czy wystawpi awaria

if temp < 5 then

Ekran.Putat(Y,X,"a");

delay elevatorSpeed*3;--wtedy czekamy dluzej

Ekran.Putat(Y,X,"w");

end if;

-- qReleaseall(kolejkaUp(id,pietro));

-- qReleaseall(kolejkaDown(id,pietro));

end loop;

end Elevator;

------------------------------------------------------------------------

Osoba : Personaptr;--tablica taskow person

Winda:Elevatoraptr;--tablica taskow wind

------------------------------------------------------------------------------- MAIN -------------------------------------------------

begin

loop--w petlach pobierz dane liczby, pobieraj poki <=0

Gnat.Io.Put("Podaj liczbe osob: ");

Get(Personcount);

if Personcount >0 then exit ; end if;

end loop;

loop

Gnat.Io.Put("Podaj liczbe pieter: ");

Get(floorcount);

if floorcount >0 then exit ; end if;

end loop;

loop

Gnat.Io.Put("Podaj liczbe wind: ");

Get(elevatorcount);

if elevatorcount >0 then exit ; end if;

end loop;

clearscreen;--czyscimy ekran

-- Personcount:=36;

-- Floorcount:=6;

-- Elevatorcount:=5;

for Y in 1..Floorcount loop--teraz rysowanie ramek jest

Ekran.Putat(Y*2,3,"#");

Ekran.Putat(Y*2,4,"#");

for X in 1..Elevatorcount loop

Ekran.Putat(Y*2,X*2+4,"#");

end loop;

end loop;

for Y in 1..Floorcount*2 loop

Ekran.Putat(Y+1,1,"#");

if Y mod 2 = 0 then

Ekran.Putat(Y+1,Elevatorcount*2+4,"#");

end if;

end loop;

for X in 1..Elevatorcount*2+4 loop

Ekran.Putat(Floorcount*2+2,X,"#");

Ekran.Putat(1,X,"#");

end loop;

Kolejkaup := new Queue2darray(1..Elevatorcount,1..Floorcount);--tworzenie naszych tablic, tablice sa indeksowane od 1 do rozmiar wlacznie

Kolejkadown := new Queue2darray(1..Elevatorcount,1..Floorcount);

Kolejkaout := new Queue2darray(1..Elevatorcount,1..Floorcount);

Canenter := new Integer2darray(1..Elevatorcount,1..Floorcount);

W_Windzie:= new Integerarray(1..Elevatorcount);

Canmove:= new Integerarray(1..Elevatorcount);

for X in 1..Elevatorcount loop --ustawianie wartosci poczatkowych

W_Windzie(X):=0;

Canmove(X):=0;

end loop;

for X in 1..Elevatorcount loop

for Y in 1..Floorcount loop--ustawlenie pozycji liczb wyswieltanych na ekranie

Kolejkaup(X,Y).Ypos := 1+ (Y-1) *4;

Kolejkaup(X,Y).Xpos :=Elevatorcount*2+4+ X*3;

Kolejkadown(X,Y).Ypos := 1+ (Y-1) *4+1;

Kolejkadown(X,Y).Xpos :=Elevatorcount*2+4+ X*3;

Kolejkaout(X,Y).Ypos := 1+ (Y-1) *4+2;

Kolejkaout(X,Y).Xpos :=Elevatorcount*2+4+ X*3;

Ekran.Putati(Kolejkaup(X,Y).Ypos,Kolejkaup(X,Y).Xpos,0);

Ekran.Putati(Kolejkadown(X,Y).Ypos,Kolejkadown(X,Y).Xpos,0);

Ekran.Putati(Kolejkaout(X,Y).Ypos,Kolejkaout(X,Y).Xpos,0);

-- Kolejkaup(X,Y):= 0;

-- Kolejkadown(X,Y):= 0;

-- Kolejkaout(X,Y):= 0;

Canenter(X,Y):= 0;

end loop;

end loop;

Winda := new Elevatorarray(1..Elevatorcount); --tworzenie wind

for I in 1..Elevatorcount loop

Winda(I) := new Elevator(I);

end loop;

Osoba := new Personarray(1..Personcount); --tworzenie osob

for I in 1..Personcount loop

Osoba(I) := new Person;

end loop;

------------------------------------------------------------------------

-- Ekran.Putat(10,10,"wejscie");

-- qenter(test);

-- Ekran.Putat(10,10,"wyjscie");

end Main;


Wyszukiwarka

Podobne podstrony:
wyjaśnij pojęcie cyklu i trendu wzrostu gospodarczego (3 str, Ekonomia, ekonomia
Syzyfowe prace - wyjaśnienie tytułu, Przydatne do szkoły, rozprawki
EFEKT GREJPFRUTA WYJAÅšNIONY, NAUKA, WIEDZA
Podać jakiś wzór i wyjaśnić symbole
LIST DO ROMEA OD OJCA LAURENTEGO W KTÓRYM ZAKONNIK WYJAŚNIA SWÓJ PODSTĘP
21 Wyjaśnij pojęcia rozpiętość produktu, linia produktowa, głębokość i zawartość produktu
MB pojecia wyjasnienie
3 wyjaśn i modyf 21 07
Metateza - wyjaśnienie pojecia, Poetyka
Wyjaśnij na czym polega tzw. kwestia homerycka, P-Ż
Wyjaśnienie poszkodowanego, BHP, Wypadki
Dlaczego zło, filozoficzno teologiczna próba wyjaśnienia zła
INFORMACJA WYJAŚNIAJĄCA wypełnienie wniosku
Wyjaśnienie żydowskich nazwisk
OÅšWIECENIE WYJAÅšNIENIE
WYJAŚNIENIE POJĘĆ HUMANIZM I REFORMACJA
Wyjaśnienie3
27 Wyjaśnić znaczenie odchylenia linii pionu w rozwiązywaniu podstawowych zadań geodezyjnych
wyjaśnienie i mod "

więcej podobnych podstron