| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- uses Graph,CRT;
- CONST
- TeamSize = 4;
- SwimmerRad=4;
- PoolX1 = 30;
- PoolY1 = 50;
- PoolSX = 500;
- PoolSY = 200;
- var
- Tick : longint Absolute $0040:$006c;
- type
- EDo = (WAITING, SWIM_NEXT, SWIMMING_F, SWIMMING_B, DONE);
- PTeam = ^CTeam;
- CSwimmer = object
- Name : String[40];
- Team : PTeam;
- Number : Integer;
- Speed : real;
- V0,V1 : real;
- Doing : EDo;
- Pos : real;
- Constructor Init(aName:String;aT:PTeam;aNum:integer);
- Procedure SetSpeed(aV0,aV1:real);
- Procedure Frame(aT:Real);
- Procedure Draw(aOrder:integer);
- Procedure Return;
- Procedure Swim;
- end;
- PSwimmer = ^CSwimmer;
- PWorld = ^CWorld;
- CTeam = object
- Name : string[30];
- Number : integer;
- World : PWorld;
- TotalDist : real;
- maxDist : real;
- Swimmers : array [1..TeamSize] of PSwimmer;
- NextNumber: integer;
- ifDone : boolean;
- AllTime : real;
- Constructor Init(aW:PWorld;aName:string;aNum:word);
- Procedure Draw;
- Procedure Frame(aTime:real);
- Procedure SwimNext;
- end;
- TLetter = record
- Width : word;
- Height : word;
- Data : pointer;
- Size : word;
- end;
- CWorld = object
- Numbers : array [0..9] of TLetter;
- AllRelay : array [0..3] of PTeam;
- LWidth : word;
- LeadTeam,Leader : byte;
- Time,LTime: real;
- BegTick : longint;
- Play : boolean;
- Table : array [1..4] of Byte;
- TPos : word;
- Constructor Init;
- Procedure DrawPool;
- Procedure InitLetters;
- Procedure DrawTime(aTime:real);
- Procedure DrawLeader;
- Procedure Work;
- Procedure FinishTeam(aNum:word);
- end;
-
- Procedure CWorld.DrawPool;
- var i,j : integer;
- begin
- SetFillStyle(SolidFill,White);
- Bar(PoolX1-20,PoolY1-20,PoolX1+PoolSX+20,PoolY1+PoolSY+20);
- SetColor(LightGray);
- Line(PoolX1-20,PoolY1-10,PoolX1+PoolSX+20,PoolY1-10);
- Line(PoolX1-20,PoolY1+PoolSY+10,PoolX1+PoolSX+20,PoolY1+PoolSY+10);
- Line(PoolX1-10,PoolY1-20,PoolX1-10,PoolY1+PoolSY+20);
- Line(PoolX1+PoolSX+10,PoolY1-20,PoolX1+PoolSX+10,PoolY1+PoolSY+20);
- for j := 1 to (PoolSX div 10)+1 do
- begin
- Line(PoolX1-10+j*10,PoolY1-20,PoolX1-10+j*10,PoolY1);
- Line(PoolX1-10+j*10,PoolY1+PoolSY,PoolX1-10+j*10,PoolY1+PoolSY+20);
- end;
- for j := 1 to (PoolSY div 10)+1 do
- begin
- Line(PoolX1-20,PoolY1-10+j*10,PoolX1,PoolY1-10+j*10);
- Line(PoolX1+PoolSX,PoolY1-10+j*10,PoolX1+PoolSX+20,PoolY1-10+j*10);
- end;
- SetFillStyle(SolidFill,LightBlue);
- Bar(PoolX1,PoolY1,PoolX1+PoolSX,PoolY1+PoolSY);
- for i := 1 to 3 do
- for j := 1 to 24 do
- begin
- if odd(i+j) then SetFillStyle(SolidFill,Red) else SetFillStyle(SolidFill,White);
- FillEllipse(PoolX1+j*(PoolSX div 25),PoolY1+i*(PoolSY div 4),3,3);
- end;
- end;
- Procedure CWorld.InitLetters;
- var
- i : integer;
- pos : word;
- s : string[4];
- begin
- SetTextStyle(SansSerifFont,HorizDir,4);
- SetTextJustify(LeftText,TopText);
- SetColor(Green);
- LWidth := TextWidth('8');
- s[0] := #1;
- pos := 0;
- for i := 0 to 9 do
- begin
- s[1] := chr(i+$30);
- OutTextXY(pos,100,S);
- with numbers[i] do
- begin
- Width := TextWidth(S);
- Height := TextHeight(S);
- Size := ImageSize(pos,100,pos+Width,100+Height);
- GetMem(Data,Size);
- GetImage(pos,100,pos+Width,100+Height,Data^);
- inc(Pos,Width);
- end;
- end;
- ClearDevice;
- end;
- Procedure CSwimmer.Draw(aOrder:integer);
- begin
- SetFillStyle(SolidFill,Number+Team^.Number);
- case Doing of
- SWIM_NEXT:
- FillEllipse(PoolX1+PoolSX+5,PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)),
- SwimmerRad,SwimmerRad);
- WAITING :
- FillEllipse(PoolX1+PoolSX+25,PoolY1+round((Team^.Number+0.2)*PoolSY/4)+aOrder*8,
- SwimmerRad,SwimmerRad);
- SWIMMING_F:
- FillEllipse(round(PoolX1+PoolSX-SwimmerRad-(PoolSX-2*SwimmerRad)/50.0*Pos),
- PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)), SwimmerRad,SwimmerRad);
- SWIMMING_B:
- FillEllipse(round(PoolX1+SwimmerRad+(PoolSX-2*SwimmerRad)/50*(Pos - 50.0)),
- PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)), SwimmerRad,SwimmerRad)
- end;
- end;
- Procedure CWorld.DrawTime(aTime:real);
- var
- tt : real;
- begin
- tt := aTime - trunc(aTime/60)*60.0;
- PutImage(100,300,Numbers[trunc(aTime/600) mod 10].Data^,XORPut);
- PutImage(100+Lwidth,300,Numbers[trunc(aTime/60) mod 10].Data^,XORPut);
- PutImage(100+2*LWidth,300,Numbers[trunc(tT/10) mod 10].Data^,XORPut);
- PutImage(100+3*LWidth,300,Numbers[trunc(tT) mod 10].Data^,XORPut);
- PutImage(100+4*LWidth,300,Numbers[trunc(tT*10) mod 10].Data^,XORPut);
- PutImage(100+5*LWidth,300,Numbers[round(tT*100) mod 10].Data^,XORPut);
- end;
- Procedure CWorld.DrawLeader;
- begin
- SetFillStyle(SolidFill,Black);
- Bar(400,273,640,349);
- SetColor(LightGreen);
- SetTextStyle(TriplexFont,HorizDir,2);
- SetTextJustify(LeftText,TopText);
- OutTextXY(400,273,AllRelay[LeadTeam]^.Swimmers[Leader]^.Name);
- OutTextXY(400,303,AllRelay[LeadTeam]^.Name);
- end;
- Procedure CTeam.Draw;
- var
- i : byte;
- begin
- SetFillStyle(SolidFill,LightBlue);
- Bar(PoolX1,PoolY1+round((Number+0.5)*PoolSY/4 - SwimmerRad*1.1),
- PoolX1+PoolSX,PoolY1+round((Number+0.5)*PoolSY/4 + SwimmerRad*1.1));
- SetFillStyle(SolidFill,Black);
- Bar(PoolX1+PoolSX+21,PoolY1+Number *PoolSY div 4+10,
- PoolX1+PoolSX+40,PoolY1+(Number+1)*PoolSY div 4);
- SetFillStyle(SolidFill,White);
- Bar(PoolX1+PoolSX+5-SwimmerRad,PoolY1+round((Number+0.5)*(PoolSY/4.0))-SwimmerRad,
- PoolX1+PoolSX+5+SwimmerRad,PoolY1+round((Number+0.5)*(PoolSY/4.0))+SwimmerRad);
- for i := 1 to TeamSize do
- Swimmers[i]^.Draw(i);
- end;
- Constructor CSwimmer.Init;
- begin
- Name := aName;
- Number:= aNum;
- Team := aT;
- Speed := 0;
- Doing := WAITING;
- Pos := 0;
- end;
- Procedure CSwimmer.Frame(aT:real);
- begin
- Pos := Pos + Speed*aT;
- if (Pos >= 50.0) and (Doing = SWIMMING_F) then
- begin
- Doing := SWIMMING_B;
- Team^.Swimmers[Team^.NextNumber]^.Doing := SWIM_NEXT;
- end;
- end;
- Procedure CSwimmer.Return;
- begin
- Doing := DONE;
- Pos := 0;
- end;
- Procedure CSwimmer.Swim;
- begin
- Doing := SWIMMING_F;
- Speed := V0 + random*(v1-v0);
- Pos := 0;
- end;
- Constructor CTeam.Init(aW:PWorld;aName:string;aNum:word);
- var
- j : byte;
- begin
- Name := aName;
- Number := aNum;
- World := aW;
- AllTime:=0;
- ifDone := false;
- TotalDist:=0;
- NextNumber:= 1;
- for j := 1 to TeamSize do
- begin
- New(Swimmers[j],Init('',@self,j));
- Swimmers[j]^.SetSpeed(5, 8);
- end;
- end;
- Procedure CTeam.SwimNext;
- begin
- if NextNumber > TeamSize then Exit;
- Swimmers[NextNumber]^.Swim;
- Inc(NextNumber);
- end;
- Procedure CWorld.FinishTeam(aNum:word);
- begin
- Table[TPos] := aNum;
- Inc(TPos);
- if TPos = 5 then Play := false;
- end;
- Procedure CTeam.Frame(aTime:real);
- var
- i : byte;
- begin
- for i := 1 to TeamSize do if Swimmers[i]^.Doing in [SWIMMING_F,SWIMMING_B] then
- begin
- Swimmers[i]^.Frame(aTime);
- MaxDist := Swimmers[i]^.Pos;
- if MaxDist >= 100.0 then
- begin
- TotalDist := TotalDist + MaxDist;
- if NextNumber <= TeamSize then
- begin
- Swimmers[i]^.Return;
- SwimNext;
- end
- else
- begin
- Swimmers[i]^.Return;
- AllTime := World^.Time;
- ifDone := true;
- World^.FinishTeam(Number);
- end;
- end;
- end;
- MaxDist := MaxDist + TotalDist;
- end;
- Procedure CSwimmer.SetSpeed;
- begin
- V0:=aV0;v1:=aV1;
- end;
- Constructor CWorld.Init;
- var
- grDriver: Integer;
- grMode: Integer;
- ErrCode: Integer;
- i : byte;
- begin
- grDriver := VGA;
- grMode := VGAMed;
- InitGraph(grDriver, grMode,' ');
- ErrCode := GraphResult;
- if ErrCode <> grOk then
- begin
- Writeln('Graphics error:', GraphErrorMsg(ErrCode));
- Halt(1);
- end;
- InitLetters;
- DrawPool;
- TPos := 1;
- for i := 0 to 3 do
- New(AllRelay[i],Init(@Self,'',i));
- Allrelay[0]^.Name := 'Team RUS';
- AllRelay[0]^.Swimmers[1]^.Name := 'Ivanov I';
- AllRelay[0]^.Swimmers[2]^.Name := 'Petrov P';
- AllRelay[0]^.Swimmers[3]^.Name := 'Sidorov A';
- AllRelay[0]^.Swimmers[4]^.Name := 'Vatulin B';
- Allrelay[1]^.Name := 'Team FRA';
- AllRelay[1]^.Swimmers[1]^.Name := 'Jaquot J-M';
- AllRelay[1]^.Swimmers[2]^.Name := 'Sevuit B';
- AllRelay[1]^.Swimmers[3]^.Name := 'Beliniu S';
- AllRelay[1]^.Swimmers[4]^.Name := 'Moneu G';
- AllRelay[2]^.Name := 'Team GB';
- AllRelay[2]^.Swimmers[1]^.Name := 'Johnson Jr';
- AllRelay[2]^.Swimmers[2]^.Name := 'Smith B';
- AllRelay[2]^.Swimmers[3]^.Name := 'Debian K';
- AllRelay[2]^.Swimmers[4]^.Name := 'Vesson R';
- Allrelay[3]^.Name := 'Team USA';
- AllRelay[3]^.Swimmers[1]^.Name := 'Stivenson A';
- AllRelay[3]^.Swimmers[2]^.Name := 'Brewing B';
- AllRelay[3]^.Swimmers[3]^.Name := 'Robertini F';
- AllRelay[3]^.Swimmers[4]^.Name := 'Stpanson L';
- SetTextStyle(SansSerifFont,HorizDir,4);
- SetTextJustify(CenterText,TopText);
- SetColor(Green);
- OutTextXY(100+LWidth*2-3,300-3,':');
- OutTextXY(100+LWidth*4-2,300,'.');
- SetTextStyle(SansSerifFont,HorizDir,2);
- SetColor(Red);
- SetTextJustify(RightText,TopText);
- OutTextXY(190,275,'Time:');
- OutTextXY(370,270,'Leader:');
- OutTextXY(370,300,'Lead team:');
- Randomize;
- SetTextJustify(LeftText, Centertext);
- SetTextStyle(DefaultFont,HorizDir,1);
- OutTextXY(200,345,'Press any key to start');
- for i := 0 to 3 do with AllRelay[i]^ do
- begin
- SetColor(Magenta);
- OutTextXY(PoolX1+PoolSX+25,PoolY1+i*(PoolSY div 4)+5,Name);
- Draw;
- end;
- end;
- Procedure CWorld.Work;
- var
- maxPos : Real;
- i,j : byte;
- begin
- lTime := 0;
- DrawTime(lTime);
- ReadKey;
- SetFillStyle(SolidFill,Black);
- Bar(200,340,400,349);
- Play := true;
- for i := 0 to 3 do Allrelay[i]^.SwimNext;
- BegTick := Tick;
- repeat
- maxPos := 0;
- Time := (Tick-BegTick) / 18.2;
- for i := 0 to 3 do with AllRelay[i]^ do if not ifDone then
- begin
- Frame(Time-lTime);
- if maxDist > maxPos then
- begin
- Leader:=NextNumber-1;
- LeadTeam := i;
- maxPos := maxDist;
- end;
- end;
- SetColor(Green);
- repeat until (Port[$03DA] and 8) <> 8;
- repeat until (Port[$03DA] and 8) = 8;
- for i := 0 to 3 do if not AllRelay[i]^.ifDone then
- AllRelay[i]^.Draw;
- repeat until (Port[$03DA] and 8) <> 8;
- repeat until (Port[$03DA] and 8) = 8;
- DrawLeader;
- DrawTime(lTime);
- DrawTime(Time);
- lTime := Time;
- until not play;
- SetColor(LightRed);
- SetFillStyle(SolidFill,Black);
- Bar(100,130,400,220);
- SetTextStyle(SansSerifFont,HorizDir,2);
- SetTextJustify(RightText,TopText);
- OutTextXY(250,130,'First place:');
- OutTextXY(250,150,'Second place:');
- OutTextXY(250,170,'Third place:');
- OutTextXY(250,190,'Fourth place:');
- SetTextJustify(LeftText,TopText);
- SetColor(LightGreen);
- OutTextXY(252,130,AllRelay[Table[1]]^.Name);
- OutTextXY(252,150,AllRelay[Table[2]]^.Name);
- OutTextXY(252,170,AllRelay[Table[3]]^.Name);
- OutTextXY(252,190,AllRelay[Table[4]]^.Name);
- ReadKey;
- CloseGraph;
- End;
- var
- Wrld : PWorld;
- begin
- New(Wrld,Init);
- Wrld^.Work;
- Dispose(Wrld);
- end.
|