POOL2.PAS 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. uses Graph,CRT;
  2. CONST
  3. TeamSize = 4;
  4. SwimmerRad=4;
  5. PoolX1 = 30;
  6. PoolY1 = 50;
  7. PoolSX = 500;
  8. PoolSY = 200;
  9. var
  10. Tick : longint Absolute $0040:$006c;
  11. type
  12. EDo = (WAITING, SWIM_NEXT, SWIMMING_F, SWIMMING_B, DONE);
  13. PTeam = ^CTeam;
  14. CSwimmer = object
  15. Name : String[40];
  16. Team : PTeam;
  17. Number : Integer;
  18. Speed : real;
  19. V0,V1 : real;
  20. Doing : EDo;
  21. Pos : real;
  22. Constructor Init(aName:String;aT:PTeam;aNum:integer);
  23. Procedure SetSpeed(aV0,aV1:real);
  24. Procedure Frame(aT:Real);
  25. Procedure Draw(aOrder:integer);
  26. Procedure Return;
  27. Procedure Swim;
  28. end;
  29. PSwimmer = ^CSwimmer;
  30. PWorld = ^CWorld;
  31. CTeam = object
  32. Name : string[30];
  33. Number : integer;
  34. World : PWorld;
  35. TotalDist : real;
  36. maxDist : real;
  37. Swimmers : array [1..TeamSize] of PSwimmer;
  38. NextNumber: integer;
  39. ifDone : boolean;
  40. AllTime : real;
  41. Constructor Init(aW:PWorld;aName:string;aNum:word);
  42. Procedure Draw;
  43. Procedure Frame(aTime:real);
  44. Procedure SwimNext;
  45. end;
  46. TLetter = record
  47. Width : word;
  48. Height : word;
  49. Data : pointer;
  50. Size : word;
  51. end;
  52. CWorld = object
  53. Numbers : array [0..9] of TLetter;
  54. AllRelay : array [0..3] of PTeam;
  55. LWidth : word;
  56. LeadTeam,Leader : byte;
  57. Time,LTime: real;
  58. BegTick : longint;
  59. Play : boolean;
  60. Table : array [1..4] of Byte;
  61. TPos : word;
  62. Constructor Init;
  63. Procedure DrawPool;
  64. Procedure InitLetters;
  65. Procedure DrawTime(aTime:real);
  66. Procedure DrawLeader;
  67. Procedure Work;
  68. Procedure FinishTeam(aNum:word);
  69. end;
  70. Procedure CWorld.DrawPool;
  71. var i,j : integer;
  72. begin
  73. SetFillStyle(SolidFill,White);
  74. Bar(PoolX1-20,PoolY1-20,PoolX1+PoolSX+20,PoolY1+PoolSY+20);
  75. SetColor(LightGray);
  76. Line(PoolX1-20,PoolY1-10,PoolX1+PoolSX+20,PoolY1-10);
  77. Line(PoolX1-20,PoolY1+PoolSY+10,PoolX1+PoolSX+20,PoolY1+PoolSY+10);
  78. Line(PoolX1-10,PoolY1-20,PoolX1-10,PoolY1+PoolSY+20);
  79. Line(PoolX1+PoolSX+10,PoolY1-20,PoolX1+PoolSX+10,PoolY1+PoolSY+20);
  80. for j := 1 to (PoolSX div 10)+1 do
  81. begin
  82. Line(PoolX1-10+j*10,PoolY1-20,PoolX1-10+j*10,PoolY1);
  83. Line(PoolX1-10+j*10,PoolY1+PoolSY,PoolX1-10+j*10,PoolY1+PoolSY+20);
  84. end;
  85. for j := 1 to (PoolSY div 10)+1 do
  86. begin
  87. Line(PoolX1-20,PoolY1-10+j*10,PoolX1,PoolY1-10+j*10);
  88. Line(PoolX1+PoolSX,PoolY1-10+j*10,PoolX1+PoolSX+20,PoolY1-10+j*10);
  89. end;
  90. SetFillStyle(SolidFill,LightBlue);
  91. Bar(PoolX1,PoolY1,PoolX1+PoolSX,PoolY1+PoolSY);
  92. for i := 1 to 3 do
  93. for j := 1 to 24 do
  94. begin
  95. if odd(i+j) then SetFillStyle(SolidFill,Red) else SetFillStyle(SolidFill,White);
  96. FillEllipse(PoolX1+j*(PoolSX div 25),PoolY1+i*(PoolSY div 4),3,3);
  97. end;
  98. end;
  99. Procedure CWorld.InitLetters;
  100. var
  101. i : integer;
  102. pos : word;
  103. s : string[4];
  104. begin
  105. SetTextStyle(SansSerifFont,HorizDir,4);
  106. SetTextJustify(LeftText,TopText);
  107. SetColor(Green);
  108. LWidth := TextWidth('8');
  109. s[0] := #1;
  110. pos := 0;
  111. for i := 0 to 9 do
  112. begin
  113. s[1] := chr(i+$30);
  114. OutTextXY(pos,100,S);
  115. with numbers[i] do
  116. begin
  117. Width := TextWidth(S);
  118. Height := TextHeight(S);
  119. Size := ImageSize(pos,100,pos+Width,100+Height);
  120. GetMem(Data,Size);
  121. GetImage(pos,100,pos+Width,100+Height,Data^);
  122. inc(Pos,Width);
  123. end;
  124. end;
  125. ClearDevice;
  126. end;
  127. Procedure CSwimmer.Draw(aOrder:integer);
  128. begin
  129. SetFillStyle(SolidFill,Number+Team^.Number);
  130. case Doing of
  131. SWIM_NEXT:
  132. FillEllipse(PoolX1+PoolSX+5,PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)),
  133. SwimmerRad,SwimmerRad);
  134. WAITING :
  135. FillEllipse(PoolX1+PoolSX+25,PoolY1+round((Team^.Number+0.2)*PoolSY/4)+aOrder*8,
  136. SwimmerRad,SwimmerRad);
  137. SWIMMING_F:
  138. FillEllipse(round(PoolX1+PoolSX-SwimmerRad-(PoolSX-2*SwimmerRad)/50.0*Pos),
  139. PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)), SwimmerRad,SwimmerRad);
  140. SWIMMING_B:
  141. FillEllipse(round(PoolX1+SwimmerRad+(PoolSX-2*SwimmerRad)/50*(Pos - 50.0)),
  142. PoolY1+round((Team^.Number+0.5)*(PoolSY/4.0)), SwimmerRad,SwimmerRad)
  143. end;
  144. end;
  145. Procedure CWorld.DrawTime(aTime:real);
  146. var
  147. tt : real;
  148. begin
  149. tt := aTime - trunc(aTime/60)*60.0;
  150. PutImage(100,300,Numbers[trunc(aTime/600) mod 10].Data^,XORPut);
  151. PutImage(100+Lwidth,300,Numbers[trunc(aTime/60) mod 10].Data^,XORPut);
  152. PutImage(100+2*LWidth,300,Numbers[trunc(tT/10) mod 10].Data^,XORPut);
  153. PutImage(100+3*LWidth,300,Numbers[trunc(tT) mod 10].Data^,XORPut);
  154. PutImage(100+4*LWidth,300,Numbers[trunc(tT*10) mod 10].Data^,XORPut);
  155. PutImage(100+5*LWidth,300,Numbers[round(tT*100) mod 10].Data^,XORPut);
  156. end;
  157. Procedure CWorld.DrawLeader;
  158. begin
  159. SetFillStyle(SolidFill,Black);
  160. Bar(400,273,640,349);
  161. SetColor(LightGreen);
  162. SetTextStyle(TriplexFont,HorizDir,2);
  163. SetTextJustify(LeftText,TopText);
  164. OutTextXY(400,273,AllRelay[LeadTeam]^.Swimmers[Leader]^.Name);
  165. OutTextXY(400,303,AllRelay[LeadTeam]^.Name);
  166. end;
  167. Procedure CTeam.Draw;
  168. var
  169. i : byte;
  170. begin
  171. SetFillStyle(SolidFill,LightBlue);
  172. Bar(PoolX1,PoolY1+round((Number+0.5)*PoolSY/4 - SwimmerRad*1.1),
  173. PoolX1+PoolSX,PoolY1+round((Number+0.5)*PoolSY/4 + SwimmerRad*1.1));
  174. SetFillStyle(SolidFill,Black);
  175. Bar(PoolX1+PoolSX+21,PoolY1+Number *PoolSY div 4+10,
  176. PoolX1+PoolSX+40,PoolY1+(Number+1)*PoolSY div 4);
  177. SetFillStyle(SolidFill,White);
  178. Bar(PoolX1+PoolSX+5-SwimmerRad,PoolY1+round((Number+0.5)*(PoolSY/4.0))-SwimmerRad,
  179. PoolX1+PoolSX+5+SwimmerRad,PoolY1+round((Number+0.5)*(PoolSY/4.0))+SwimmerRad);
  180. for i := 1 to TeamSize do
  181. Swimmers[i]^.Draw(i);
  182. end;
  183. Constructor CSwimmer.Init;
  184. begin
  185. Name := aName;
  186. Number:= aNum;
  187. Team := aT;
  188. Speed := 0;
  189. Doing := WAITING;
  190. Pos := 0;
  191. end;
  192. Procedure CSwimmer.Frame(aT:real);
  193. begin
  194. Pos := Pos + Speed*aT;
  195. if (Pos >= 50.0) and (Doing = SWIMMING_F) then
  196. begin
  197. Doing := SWIMMING_B;
  198. Team^.Swimmers[Team^.NextNumber]^.Doing := SWIM_NEXT;
  199. end;
  200. end;
  201. Procedure CSwimmer.Return;
  202. begin
  203. Doing := DONE;
  204. Pos := 0;
  205. end;
  206. Procedure CSwimmer.Swim;
  207. begin
  208. Doing := SWIMMING_F;
  209. Speed := V0 + random*(v1-v0);
  210. Pos := 0;
  211. end;
  212. Constructor CTeam.Init(aW:PWorld;aName:string;aNum:word);
  213. var
  214. j : byte;
  215. begin
  216. Name := aName;
  217. Number := aNum;
  218. World := aW;
  219. AllTime:=0;
  220. ifDone := false;
  221. TotalDist:=0;
  222. NextNumber:= 1;
  223. for j := 1 to TeamSize do
  224. begin
  225. New(Swimmers[j],Init('',@self,j));
  226. Swimmers[j]^.SetSpeed(5, 8);
  227. end;
  228. end;
  229. Procedure CTeam.SwimNext;
  230. begin
  231. if NextNumber > TeamSize then Exit;
  232. Swimmers[NextNumber]^.Swim;
  233. Inc(NextNumber);
  234. end;
  235. Procedure CWorld.FinishTeam(aNum:word);
  236. begin
  237. Table[TPos] := aNum;
  238. Inc(TPos);
  239. if TPos = 5 then Play := false;
  240. end;
  241. Procedure CTeam.Frame(aTime:real);
  242. var
  243. i : byte;
  244. begin
  245. for i := 1 to TeamSize do if Swimmers[i]^.Doing in [SWIMMING_F,SWIMMING_B] then
  246. begin
  247. Swimmers[i]^.Frame(aTime);
  248. MaxDist := Swimmers[i]^.Pos;
  249. if MaxDist >= 100.0 then
  250. begin
  251. TotalDist := TotalDist + MaxDist;
  252. if NextNumber <= TeamSize then
  253. begin
  254. Swimmers[i]^.Return;
  255. SwimNext;
  256. end
  257. else
  258. begin
  259. Swimmers[i]^.Return;
  260. AllTime := World^.Time;
  261. ifDone := true;
  262. World^.FinishTeam(Number);
  263. end;
  264. end;
  265. end;
  266. MaxDist := MaxDist + TotalDist;
  267. end;
  268. Procedure CSwimmer.SetSpeed;
  269. begin
  270. V0:=aV0;v1:=aV1;
  271. end;
  272. Constructor CWorld.Init;
  273. var
  274. grDriver: Integer;
  275. grMode: Integer;
  276. ErrCode: Integer;
  277. i : byte;
  278. begin
  279. grDriver := VGA;
  280. grMode := VGAMed;
  281. InitGraph(grDriver, grMode,' ');
  282. ErrCode := GraphResult;
  283. if ErrCode <> grOk then
  284. begin
  285. Writeln('Graphics error:', GraphErrorMsg(ErrCode));
  286. Halt(1);
  287. end;
  288. InitLetters;
  289. DrawPool;
  290. TPos := 1;
  291. for i := 0 to 3 do
  292. New(AllRelay[i],Init(@Self,'',i));
  293. Allrelay[0]^.Name := 'Team RUS';
  294. AllRelay[0]^.Swimmers[1]^.Name := 'Ivanov I';
  295. AllRelay[0]^.Swimmers[2]^.Name := 'Petrov P';
  296. AllRelay[0]^.Swimmers[3]^.Name := 'Sidorov A';
  297. AllRelay[0]^.Swimmers[4]^.Name := 'Vatulin B';
  298. Allrelay[1]^.Name := 'Team FRA';
  299. AllRelay[1]^.Swimmers[1]^.Name := 'Jaquot J-M';
  300. AllRelay[1]^.Swimmers[2]^.Name := 'Sevuit B';
  301. AllRelay[1]^.Swimmers[3]^.Name := 'Beliniu S';
  302. AllRelay[1]^.Swimmers[4]^.Name := 'Moneu G';
  303. AllRelay[2]^.Name := 'Team GB';
  304. AllRelay[2]^.Swimmers[1]^.Name := 'Johnson Jr';
  305. AllRelay[2]^.Swimmers[2]^.Name := 'Smith B';
  306. AllRelay[2]^.Swimmers[3]^.Name := 'Debian K';
  307. AllRelay[2]^.Swimmers[4]^.Name := 'Vesson R';
  308. Allrelay[3]^.Name := 'Team USA';
  309. AllRelay[3]^.Swimmers[1]^.Name := 'Stivenson A';
  310. AllRelay[3]^.Swimmers[2]^.Name := 'Brewing B';
  311. AllRelay[3]^.Swimmers[3]^.Name := 'Robertini F';
  312. AllRelay[3]^.Swimmers[4]^.Name := 'Stpanson L';
  313. SetTextStyle(SansSerifFont,HorizDir,4);
  314. SetTextJustify(CenterText,TopText);
  315. SetColor(Green);
  316. OutTextXY(100+LWidth*2-3,300-3,':');
  317. OutTextXY(100+LWidth*4-2,300,'.');
  318. SetTextStyle(SansSerifFont,HorizDir,2);
  319. SetColor(Red);
  320. SetTextJustify(RightText,TopText);
  321. OutTextXY(190,275,'Time:');
  322. OutTextXY(370,270,'Leader:');
  323. OutTextXY(370,300,'Lead team:');
  324. Randomize;
  325. SetTextJustify(LeftText, Centertext);
  326. SetTextStyle(DefaultFont,HorizDir,1);
  327. OutTextXY(200,345,'Press any key to start');
  328. for i := 0 to 3 do with AllRelay[i]^ do
  329. begin
  330. SetColor(Magenta);
  331. OutTextXY(PoolX1+PoolSX+25,PoolY1+i*(PoolSY div 4)+5,Name);
  332. Draw;
  333. end;
  334. end;
  335. Procedure CWorld.Work;
  336. var
  337. maxPos : Real;
  338. i,j : byte;
  339. begin
  340. lTime := 0;
  341. DrawTime(lTime);
  342. ReadKey;
  343. SetFillStyle(SolidFill,Black);
  344. Bar(200,340,400,349);
  345. Play := true;
  346. for i := 0 to 3 do Allrelay[i]^.SwimNext;
  347. BegTick := Tick;
  348. repeat
  349. maxPos := 0;
  350. Time := (Tick-BegTick) / 18.2;
  351. for i := 0 to 3 do with AllRelay[i]^ do if not ifDone then
  352. begin
  353. Frame(Time-lTime);
  354. if maxDist > maxPos then
  355. begin
  356. Leader:=NextNumber-1;
  357. LeadTeam := i;
  358. maxPos := maxDist;
  359. end;
  360. end;
  361. SetColor(Green);
  362. repeat until (Port[$03DA] and 8) <> 8;
  363. repeat until (Port[$03DA] and 8) = 8;
  364. for i := 0 to 3 do if not AllRelay[i]^.ifDone then
  365. AllRelay[i]^.Draw;
  366. repeat until (Port[$03DA] and 8) <> 8;
  367. repeat until (Port[$03DA] and 8) = 8;
  368. DrawLeader;
  369. DrawTime(lTime);
  370. DrawTime(Time);
  371. lTime := Time;
  372. until not play;
  373. SetColor(LightRed);
  374. SetFillStyle(SolidFill,Black);
  375. Bar(100,130,400,220);
  376. SetTextStyle(SansSerifFont,HorizDir,2);
  377. SetTextJustify(RightText,TopText);
  378. OutTextXY(250,130,'First place:');
  379. OutTextXY(250,150,'Second place:');
  380. OutTextXY(250,170,'Third place:');
  381. OutTextXY(250,190,'Fourth place:');
  382. SetTextJustify(LeftText,TopText);
  383. SetColor(LightGreen);
  384. OutTextXY(252,130,AllRelay[Table[1]]^.Name);
  385. OutTextXY(252,150,AllRelay[Table[2]]^.Name);
  386. OutTextXY(252,170,AllRelay[Table[3]]^.Name);
  387. OutTextXY(252,190,AllRelay[Table[4]]^.Name);
  388. ReadKey;
  389. CloseGraph;
  390. End;
  391. var
  392. Wrld : PWorld;
  393. begin
  394. New(Wrld,Init);
  395. Wrld^.Work;
  396. Dispose(Wrld);
  397. end.