pool.pas 10 KB

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