Traffic.pas

Un article de Wikipedia.

Solution minimale du jeu Traffic!

  1. program traffic;
  2. {$i PalmAPI.pas}
  3. {$i PPlib.pas}
  4. {$i Menu.pas}
  5. {$i CPDBSTD4PP.pas}
  6. type position = record
  7. x,y:byte;
  8. end;
  9. direction = (verti,hori);
  10. taille = (deux,trois);
  11. genre = (normal,principal);
  12. pbloc = ^bloc;
  13. bloc = record
  14. pos:position;
  15. dir:direction;
  16. t:taille;
  17. g:genre;
  18. end;
  19. plistebloc = ^listebloc;
  20. listebloc = record
  21. pb:pbloc;
  22. suivant:plistebloc;
  23. end;
  24. pcoup = ^coup;
  25. coup = record
  26. pde,pa:pbloc;
  27. end;
  28. plistecoup = ^listecoup;
  29. listecoup = record
  30. pc:pcoup;
  31. suivant:plistecoup;
  32. end;
  33. pgrille = ^grille;
  34. grille = array [1..6,1..6] of byte;
  35. plistelien = ^listelien;
  36. listelien = record
  37. plb:plistebloc;
  38. via:plistelien;
  39. pc:pcoup;
  40. suivant:plistelien;
  41. end;
  42. var c:char;
  43. // pg est globale car le garbage
  44. // collector semble inactif
  45. pg:pgrille;
  46. procedure bip;
  47. begin
  48. SndPlaySystemSound(snderror);
  49. end;
  50. function memebloc(pba,pbb:pbloc):boolean;
  51. begin
  52. memebloc := false;
  53. if (pba <> nil) and (pbb <> nil) then
  54. begin
  55. if pba^.pos.x = pbb^.pos.x then
  56. if pba^.pos.y = pbb^.pos.y then
  57. if pba^.dir = pbb^.dir then
  58. if pba^.t = pbb^.t then
  59. if pba^.g = pbb^.g then
  60. memebloc := true;
  61. end
  62. else
  63. if (pba = nil) and (pbb = nil) then
  64. memebloc := true;
  65. end;
  66. function memelistebloc(pla,plb:plistebloc):boolean;
  67. var aa,ab:plistebloc;
  68. begin
  69. if (pla <> nil) and (plb <> nil) then
  70. begin
  71. aa := pla;
  72. ab := plb;
  73. memelistebloc := true;
  74. while (aa^.suivant <> nil) and (ab^.suivant <> nil) do
  75. begin
  76. if not memebloc(aa^.pb,ab^.pb) then
  77. memelistebloc := false;
  78. aa := aa^.suivant;
  79. ab := ab^.suivant;
  80. end;
  81. if not memebloc(aa^.pb,ab^.pb) then
  82. memelistebloc := false;
  83. end
  84. else
  85. if (pla = nil) and (plb = nil) then
  86. memelistebloc := true
  87. else
  88. memelistebloc := false;
  89. end;
  90. procedure jouercoup(plb:plistebloc;pc:pcoup);
  91. var actuel:plistebloc;
  92. trouve:boolean;
  93. begin
  94. if (plb <> nil) and (pc <> nil) then
  95. begin
  96. actuel := plb;
  97. trouve := false;
  98. while (actuel^.suivant <> nil) and (not trouve) do
  99. begin
  100. if memebloc(actuel^.pb,pc^.pde) then
  101. trouve := true
  102. else
  103. actuel := actuel^.suivant;
  104. end;
  105. if not trouve then
  106. if memebloc(actuel^.pb,pc^.pde) then
  107. trouve := true;
  108. if trouve then
  109. actuel^.pb := pc^.pa
  110. else
  111. begin
  112. writeln('Erreur : le bloc est introuvab, aucun mouvement');
  113. read(c);
  114. end;
  115. end
  116. else
  117. begin
  118. writeln('Erreur : arguments non transmis');
  119. read(c);
  120. end;
  121. end;
  122. function copierlistebloc(plb:plistebloc):plistebloc;
  123. var aa,ab:plistebloc;
  124. begin
  125. if plb <> nil then
  126. begin
  127. new(ab);
  128. copierlistebloc := ab;
  129. aa := plb;
  130. while aa^.suivant <> nil do
  131. begin
  132. ab^.pb := aa^.pb;
  133. new(ab^.suivant);
  134. ab := ab^.suivant;
  135. aa := aa^.suivant;
  136. end;
  137. ab^.pb := aa^.pb;
  138. ab^.suivant := nil;
  139. end
  140. else
  141. copierlistebloc := nil;
  142. end;
  143. function creerbloc(x,y:byte;d:direction;te:taille;ge:genre):pbloc;
  144. var piece:pbloc;
  145. begin
  146. new(piece);
  147. with piece^ do
  148. begin
  149. pos.x := x;
  150. pos.y := y;
  151. dir := d;
  152. t := te;
  153. g := ge;
  154. end;
  155. creerbloc := piece;
  156. end;
  157. function ajouterbloc(plb:plistebloc;pbl:pbloc):plistebloc;
  158. var actuel:plistebloc;
  159. begin
  160. actuel := plb;
  161. if actuel <> nil then
  162. begin
  163. while actuel^.suivant <> nil do
  164. actuel := actuel^.suivant;
  165. new(actuel^.suivant);
  166. with actuel^.suivant^ do
  167. begin
  168. pb := pbl;
  169. suivant := nil;
  170. end;
  171. ajouterbloc := plb;
  172. end
  173. else
  174. begin
  175. new(actuel);
  176. actuel^.pb := pbl;
  177. actuel^.suivant := nil;
  178. ajouterbloc := actuel;
  179. end;
  180. end;
  181. function ajoutercoup(plc:plistecoup;pcde,pca:pbloc):plistecoup;
  182. var actuel:plistecoup;
  183. begin
  184. actuel := plc;
  185. if actuel <> nil then
  186. begin
  187. while actuel^.suivant <> nil do
  188. actuel := actuel^.suivant;
  189. new(actuel^.suivant);
  190. with actuel^.suivant^ do
  191. begin
  192. new(pc);
  193. pc^.pde := pcde;
  194. pc^.pa := pca;
  195. suivant := nil;
  196. end;
  197. ajoutercoup := plc;
  198. end
  199. else
  200. begin
  201. new(actuel);
  202. new(actuel^.pc);
  203. actuel^.pc^.pde := pcde;
  204. actuel^.pc^.pa := pca;
  205. actuel^.suivant := nil;
  206. ajoutercoup := actuel;
  207. end;
  208. end;
  209. function ajouterlien(plla:plistelien;plba:plistebloc;v:plistelien;vc:pcoup):plistelien;
  210. var actuel:plistelien;
  211. begin
  212. if (plla <> nil) and (plba <> nil) then
  213. begin
  214. actuel := plla;
  215. while actuel^.suivant <> nil do
  216. actuel := actuel^.suivant;
  217. new(actuel^.suivant);
  218. with actuel^.suivant^ do
  219. begin
  220. plb := plba;
  221. via := v;
  222. pc := vc;
  223. suivant := nil;
  224. end;
  225. ajouterlien := plla;
  226. end
  227. else
  228. if plla = nil then
  229. begin
  230. new(actuel);
  231. with actuel^ do
  232. begin
  233. plb := plba;
  234. via := v;
  235. pc := vc;
  236. suivant := nil;
  237. end;
  238. ajouterlien := actuel;
  239. end
  240. else
  241. ajouterlien := plla;
  242. end;
  243. function ajouterliendebut(plla:plistelien;plba:plistebloc;v:plistelien;vc:pcoup):plistelien;
  244. var actuel:plistelien;
  245. begin
  246. if plba <> nil then
  247. begin
  248. new(actuel);
  249. with actuel^ do
  250. begin
  251. plb := plba;
  252. via := v;
  253. pc := vc;
  254. suivant := plla;
  255. end;
  256. ajouterliendebut := actuel;
  257. end
  258. else
  259. ajouterliendebut := plla;
  260. end;
  261. procedure creergrille(plb:plistebloc);
  262. var actuel:plistebloc;
  263. l,c,n,valeur:byte;
  264. procedure ajoute(b:bloc;v:byte);
  265. var px,py,dx,dy,n,nombre:byte;
  266. begin
  267. case b.dir of
  268. verti:begin
  269. dx := 0;
  270. dy := 1;
  271. end;
  272. hori:begin
  273. dx := 1;
  274. dy := 0;
  275. end;
  276. end;
  277. case b.t of
  278. deux: nombre := 2;
  279. trois: nombre := 3;
  280. end;
  281. case b.g of
  282. normal: valeur := v;
  283. principal: valeur := 255;
  284. end;
  285. px := b.pos.x;
  286. py := b.pos.y;
  287. for n:=1 to nombre do
  288. begin
  289. pg^[px,py] := valeur;
  290. px := px+dx;
  291. py := py+dy;
  292. end;
  293. end;
  294. begin
  295. if pg = nil then
  296. new(pg);
  297. for l:=1 to 6 do
  298. for c:=1 to 6 do
  299. pg^[c,l] := 0;
  300. actuel := plb;
  301. if actuel <> nil then
  302. begin
  303. n:=1;
  304. ajoute(actuel^.pb^,n);
  305. while actuel^.suivant <> nil do
  306. begin
  307. n := n+1;
  308. actuel := actuel^.suivant;
  309. ajoute(actuel^.pb^,n);
  310. end;
  311. end;
  312. end;
  313. procedure affichelistebloc(plb:plistebloc);
  314. var actuel:plistebloc;
  315. l,c,n,d1,d2,valeur,mult:byte;
  316. begin
  317. mult := 1;
  318. creergrille(plb);
  319. write('|');
  320. for d1 := 1 to mult*6 do
  321. write('-');
  322. writeln('|');
  323. for l := 6 downto 1 do
  324. for d1 := 1 to mult do
  325. begin
  326. write('|');
  327. for c := 1 to 6 do
  328. for d2 := 1 to mult do
  329. case pg^[c,l] of
  330. 0:write(' ');
  331. 255:write('X');
  332. else
  333. write(chr(pg^[c,l]+64));
  334. end;
  335. write('|');
  336. writeln;
  337. end;
  338. write('|');
  339. for d1 := 1 to mult*6 do
  340. write('-');
  341. writeln('|');
  342. end;
  343. procedure affichecoup(coup:pcoup);
  344. begin
  345. if coup <> nil then
  346. writeln('(',coup^.pde^.pos.x,',',coup^.pde^.pos.y,')->(',coup^.pa^.pos.x,',',coup^.pa^.pos.y,')')
  347. else
  348. writeln('Aucun coup specifie.');
  349. end;
  350. procedure affichelistecoup(plc:plistecoup);
  351. var actuel:plistecoup;
  352. begin
  353. if plc <> nil then
  354. begin
  355. actuel := plc;
  356. while actuel^.suivant <> nil do
  357. begin
  358. affichecoup(actuel^.pc);
  359. actuel := actuel^.suivant;
  360. end;
  361. affichecoup(actuel^.pc);
  362. end
  363. else
  364. writeln('Liste vide');
  365. end;
  366. function coups(plb:plistebloc):plistecoup;
  367. var lba:plistebloc;
  368. lca:plistecoup;
  369. pba,pbt:pbloc;
  370. dx,dy,px,py,nombre,n:byte;
  371. fini,trouve:boolean;
  372. procedure ajoutercoups;
  373. begin
  374. case pba^.dir of
  375. verti:begin
  376. dx := 0;
  377. dy := 1;
  378. end;
  379. hori:begin
  380. dx := 1;
  381. dy := 0;
  382. end;
  383. end;
  384. case pba^.t of
  385. deux: nombre := 2;
  386. trois: nombre := 3;
  387. end;
  388. // vers les coordonnees inferieures
  389. px := pba^.pos.x-dx;
  390. py := pba^.pos.y-dy;
  391. fini := false;
  392. while (px >= 1) and (py >= 1) and (not fini) do
  393. begin
  394. if pg^[px,py] = 0 then
  395. begin
  396. pbt := creerbloc(px,py,pba^.dir,pba^.t,pba^.g);
  397. lca := ajoutercoup(lca,pba,pbt);
  398. end
  399. else
  400. fini := true;
  401. px := px-dx;
  402. py := py-dy;
  403. end;
  404. // vers les coordonnees superieures
  405. px := pba^.pos.x+nombre*dx;
  406. py := pba^.pos.y+nombre*dy;
  407. fini := false;
  408. while (px <= 6) and (py <= 6) and (not fini) do
  409. begin
  410. if pg^[px,py] = 0 then
  411. begin
  412. pbt := creerbloc(px-(nombre-1)*dx,py-(nombre-1)*dy,pba^.dir,pba^.t,pba^.g);
  413. lca := ajoutercoup(lca,pba,pbt);
  414. end
  415. else
  416. fini := true;
  417. px := px+dx;
  418. py := py+dy;
  419. end;
  420. end;
  421. begin
  422. if plb <> nil then
  423. begin
  424. creergrille(plb);
  425. lca := nil;
  426. // verifier si termine ou
  427. // si possible de terminer
  428. lba := plb;
  429. trouve := false;
  430. while (lba^.suivant <> nil) and (not trouve) do
  431. begin
  432. if lba^.pb^.g = principal then
  433. trouve := true;
  434. lba := lba^.suivant;
  435. end;
  436. if lba^.pb^.g = principal then
  437. trouve := true;
  438. fini := false;
  439. if trouve then
  440. begin
  441. if lba^.pb^.pos.x = 5 then
  442. begin
  443. coups := nil;
  444. fini := true;
  445. end
  446. else
  447. begin
  448. nombre := 0;
  449. for n:= lba^.pb^.pos.x+2 to 6 do
  450. if pg^[n,4] = 0 then
  451. nombre := nombre+1;
  452. if nombre = (5-lba^.pb^.pos.x) then
  453. begin
  454. pbt := creerbloc(5,4,hori,deux,principal);
  455. lca := ajoutercoup(nil,lba^.pb,pbt);
  456. coups := lca;
  457. fini := true;
  458. end;
  459. end;
  460. end
  461. else
  462. writeln('Erreur : il manque le bloc principal.');
  463. if not fini then
  464. begin
  465. lba := plb;
  466. while lba^.suivant <> nil do
  467. begin
  468. pba := lba^.pb;
  469. ajoutercoups;
  470. lba := lba^.suivant;
  471. end;
  472. pba := lba^.pb;
  473. ajoutercoups;
  474. coups := lca;
  475. end;
  476. end
  477. else
  478. coups := nil;
  479. end;
  480. {$i trafficsamples.pas}
  481. function existelistebloc(pll:plistelien;plba:plistebloc):boolean;
  482. var actuel:plistelien;
  483. trouve:boolean;
  484. begin
  485. if (pll <> nil) and (plba <> nil) then
  486. begin
  487. trouve := false;
  488. actuel := pll;
  489. while (actuel^.suivant <> nil) and (not trouve) do
  490. begin
  491. if memelistebloc(actuel^.plb,plba) then
  492. trouve := true
  493. else
  494. actuel := actuel^.suivant;
  495. end;
  496. if not trouve then
  497. begin
  498. if memelistebloc(actuel^.plb,plba) then
  499. trouve := true
  500. end;
  501. existelistebloc := trouve;
  502. end
  503. else
  504. existelistebloc := false;
  505. end;
  506. function nbblocs(plba:plistebloc):integer;
  507. var n:integer;
  508. plbc:plistebloc;
  509. begin
  510. if plba <> nil then
  511. begin
  512. n := 1;
  513. plbc := plba;
  514. while plbc^.suivant <> nil do
  515. begin
  516. n := n+1;
  517. plbc := plbc^.suivant;
  518. end;
  519. nbblocs := n;
  520. end
  521. else
  522. nbblocs := 0;
  523. end;
  524. function nbliens(plla:plistelien):integer;
  525. var n:integer;
  526. pllc:plistelien;
  527. begin
  528. if plla <> nil then
  529. begin
  530. n := 1;
  531. pllc := plla;
  532. while pllc^.suivant <> nil do
  533. begin
  534. n := n+1;
  535. pllc := pllc^.suivant;
  536. end;
  537. nbliens := n;
  538. end
  539. else
  540. nbliens := 0;
  541. end;
  542. function zero(n:integer):string;
  543. begin
  544. if n > 9 then
  545. zero:=IntToString(n)
  546. else
  547. zero:='0'+IntToString(n);
  548. end;
  549. function temps(duree:integer):string;
  550. begin
  551. temps:=zero((duree div 3600) mod 100)+':'+zero((duree div 60) mod 60)+':'+zero(duree mod 60);
  552. end;
  553. function existe(n:integer):string;
  554. var nom:string;
  555. begin
  556. nom:='TrafCPDB'+zero(n);
  557. if CPDB_DatabaseExist(nom) = CPDB_ERR_NOEXIST then
  558. existe:=''
  559. else
  560. existe:='+';
  561. end;
  562. procedure restaure(n:integer;var psol:plistelien;var dur,nbg:integer);
  563. const NoError = 0;
  564. var Error: Err;
  565. iHandle: UInt8;
  566. nom:string;
  567. t,v1,v2,v3:Int8;
  568. ta:taille;
  569. d:direction;
  570. g:genre;
  571. di:integer;
  572. lbt:plistebloc;
  573. llt:plistelien;
  574. procedure ajoutebloc;
  575. begin
  576. case v2 div 10 of
  577. 2: ta:=deux;
  578. 3: ta:=trois;
  579. end;
  580. case v2 mod 10 of
  581. 1: d:=hori;
  582. 2: d:=verti;
  583. end;
  584. case v3 of
  585. 0: g:=normal;
  586. 1: g:=principal;
  587. end;
  588. lbt:=ajouterbloc(lbt,creerbloc(v1 div 10,v1 mod 10,d,ta,g));
  589. end;
  590. procedure ajoutecoup;
  591. var lla:plistelien;
  592. lba,lbc:plistebloc;
  593. vx,vy:byte;
  594. trouve:boolean;
  595. pba:pbloc;
  596. pc:pcoup;
  597. begin
  598. if llt = nil then
  599. begin
  600. llt:=ajouterlien(llt,lbt,nil,nil);
  601. end;
  602. // aller a la fin de la liste
  603. lla:=llt;
  604. while lla^.suivant <> nil do
  605. begin
  606. lla:=lla^.suivant;
  607. end;
  608. // rechercher coup de depart
  609. vx:=v1 div 10;
  610. vy:=v1 mod 10;
  611. lba:=lla^.plb;
  612. trouve:=false;
  613. while (lba^.suivant <> nil) and (not trouve) do
  614. begin
  615. if (lba^.pb^.pos.x = vx) and (lba^.pb^.pos.y = vy) then
  616. trouve:=true;
  617. if not trouve then
  618. lba:=lba^.suivant;
  619. end;
  620. if not trouve then
  621. if (lba^.pb^.pos.x = vx) and (lba^.pb^.pos.y = vy) then
  622. trouve:=true;
  623. if trouve then
  624. begin
  625. // creer le coup
  626. with lba^.pb^ do
  627. begin
  628. pba:=creerbloc(v2 div 10,v2 mod 10,dir,t,g);
  629. end;
  630. new(pc);
  631. pc^.pde:=lba^.pb;
  632. pc^.pa:=pba;
  633. // jouer le coup
  634. lbc:=copierlistebloc(lla^.plb);
  635. jouercoup(lbc,pc);
  636. // ajouter le coup
  637. llt:=ajouterlien(llt,lbc,nil,pc);
  638. end
  639. else
  640. writeln('Erreur coup introuvable !');
  641. end;
  642. procedure duree;
  643. begin
  644. di:=((v1 * 60) + v2) * 60 + v3;
  645. end;
  646. procedure nbgrilles;
  647. begin
  648. nbg:=((v1 * 128) + v2) * 128 + v3;
  649. end;
  650. begin
  651. dur:=0;
  652. psol:=nil;
  653. nom:='TrafCPDB'+zero(n);
  654. if CPDB_DatabaseExist(nom) <> CPDB_ERR_NOEXIST then
  655. begin
  656. lbt:=nil;
  657. llt:=nil;
  658. Error:=CPDB_Open(0,nom,dmModeReadOnly,iHandle);
  659. Error:=CPDB_ReadLast(iHandle);
  660. while Error = NoError do
  661. begin
  662. Error:=CPDB_ReadShortInt(iHandle,'TYPE',t);
  663. Error:=CPDB_ReadShortInt(iHandle,'V1',v1);
  664. Error:=CPDB_ReadShortInt(iHandle,'V2',v2);
  665. Error:=CPDB_ReadShortInt(iHandle,'V3',v3);
  666. case t of
  667. 1: ajoutebloc;
  668. 2: ajoutecoup;
  669. 3: duree;
  670. 4: nbgrilles;
  671. end;
  672. Error:=CPDB_ReadPrevious(iHandle);
  673. end;
  674. Error:=CPDB_Close(iHandle);
  675. dur:=di;
  676. psol:=llt;
  677. end;
  678. end;
  679. procedure sauvegarde(n:integer;l:plistelien;duree,nbgrilles:integer);
  680. const DBCreator = $54455354; //TEST
  681. var Error: Err;
  682. iHandle: UInt8;
  683. nom:string;
  684. lbt:plistebloc;
  685. llt:plistelien;
  686. procedure ajouteblocbd;
  687. var dirb,tb,gb:byte;
  688. begin
  689. with lbt^.pb^ do
  690. begin
  691. case dir of
  692. hori: dirb:=1;
  693. verti: dirb:=2;
  694. end;
  695. case t of
  696. deux: tb:=2;
  697. trois: tb:=3;
  698. end;
  699. case g of
  700. normal: gb:=0;
  701. principal: gb:=1;
  702. end;
  703. Error:=CPDB_AddRecord(iHandle);
  704. Error:=CPDB_WriteShortInt(iHandle,'TYPE',1);
  705. Error:=CPDB_WriteShortInt(iHandle,'V1',pos.x * 10 +pos.y);
  706. Error:=CPDB_WriteShortInt(iHandle,'V2',tb * 10 + dirb);
  707. Error:=CPDB_WriteShortInt(iHandle,'V3',gb);
  708. Error:=CPDB_UpdateRecord(iHandle);
  709. end;
  710. end;
  711. procedure ajoutecoupbd;
  712. begin
  713. with llt^.suivant^.pc^ do
  714. begin
  715. Error:=CPDB_AddRecord(iHandle);
  716. Error:=CPDB_WriteShortInt(iHandle,'TYPE',2);
  717. Error:=CPDB_WriteShortInt(iHandle,'V1',pde^.pos.x * 10 + pde^.pos.y);
  718. Error:=CPDB_WriteShortInt(iHandle,'V2',pa^.pos.x * 10 + pa^.pos.y);
  719. Error:=CPDB_WriteShortInt(iHandle,'V3',0);
  720. Error:=CPDB_UpdateRecord(iHandle);
  721. end;
  722. end;
  723. procedure ajoutedureebd;
  724. begin
  725. Error:=CPDB_AddRecord(iHandle);
  726. Error:=CPDB_WriteShortInt(iHandle,'TYPE',3);
  727. Error:=CPDB_WriteShortInt(iHandle,'V1',(duree div 3600) mod 100);
  728. Error:=CPDB_WriteShortInt(iHandle,'V2',(duree div 60) mod 60);
  729. Error:=CPDB_WriteShortInt(iHandle,'V3',duree mod 60);
  730. Error:=CPDB_UpdateRecord(iHandle);
  731. end;
  732. procedure ajoutenbgrillesbd;
  733. begin
  734. Error:=CPDB_AddRecord(iHandle);
  735. Error:=CPDB_WriteShortInt(iHandle,'TYPE',4);
  736. Error:=CPDB_WriteShortInt(iHandle,'V1',(nbgrilles div 128*128) mod 128);
  737. Error:=CPDB_WriteShortInt(iHandle,'V2',(nbgrilles div 128) mod 128);
  738. Error:=CPDB_WriteShortInt(iHandle,'V3',nbgrilles mod 128);
  739. Error:=CPDB_UpdateRecord(iHandle);
  740. end;
  741. begin
  742. if l <> nil then
  743. begin
  744. nom:='TrafCPDB'+zero(n);
  745. if CPDB_DatabaseExist(nom)= CPDB_ERR_NOEXIST then
  746. begin
  747. Error:=CPDB_CreateDatabase(0,nom,DBCreator,'TYPE=SHORTINT;V1=SHORTINT;V2=SHORTINT;V3=SHORTINT;');
  748. Error:=CPDB_Open(0,nom,dmModeReadWrite,iHandle);
  749. //ajoute la grille initiale
  750. lbt:=l^.plb;
  751. if lbt <> nil then
  752. begin
  753. //premierement les blocs normaux
  754. while lbt^.suivant <> nil do
  755. begin
  756. if lbt^.pb^.g = normal then
  757. ajouteblocbd;
  758. lbt:=lbt^.suivant;
  759. end;
  760. if lbt^.pb^.g = normal then
  761. ajouteblocbd;
  762. //dernierement le bloc principal
  763. lbt:=l^.plb;
  764. while lbt^.suivant <> nil do
  765. begin
  766. if lbt^.pb^.g = principal then
  767. ajouteblocbd;
  768. lbt:=lbt^.suivant;
  769. end;
  770. if lbt^.pb^.g = principal then
  771. ajouteblocbd;
  772. end;
  773. // ajouter les coups
  774. llt:=l;
  775. while llt^.suivant <> nil do
  776. begin
  777. ajoutecoupbd;
  778. llt:=llt^.suivant;
  779. end;
  780. //ajouter la duree des calculs;
  781. ajoutedureebd;
  782. ajoutenbgrillesbd;
  783. Error:=CPDB_Close(iHandle);
  784. end;
  785. end;
  786. end;
  787. procedure afficherstatistiques(duree,nbliens,nbblocs,nbgrilles:integer);
  788. begin
  789. writeln('Nombre de blocs  : ',nbblocs:8);
  790. writeln('Nombre grilles diff. : ',nbgrilles:8);
  791. writeln('Duree des calculs  : ',temps(duree));
  792. writeln('Nombre de mouvements : ',nbliens:8);
  793. end;
  794. function cherchesolution(plb:plistebloc;var d,nbg:integer):plistelien;
  795. var pla,plt,plc,plact:plistelien;
  796. lbt:plistebloc;
  797. lc,lca:plistecoup;
  798. pbtermine:pbloc;
  799. n:integer;
  800. termine:boolean;
  801. sol:plistelien;
  802. duree:UInt32;
  803. procedure traiterlien;
  804. begin
  805. lc:=coups(plact^.plb);
  806. lca:=lc;
  807. while (lca^.suivant <> nil) and (not termine) do
  808. begin
  809. if memebloc(lca^.pc^.pa,pbtermine) then
  810. termine:=true
  811. else
  812. begin
  813. lbt:=copierlistebloc(plact^.plb);
  814. jouercoup(lbt,lca^.pc);
  815. if not existelistebloc(plc,lbt) then
  816. begin
  817. plc:=ajouterlien(plc,lbt,plact,lca^.pc);
  818. plt:=ajouterlien(plt,lbt,plact,lca^.pc);
  819. end;
  820. lca:=lca^.suivant;
  821. end;
  822. end;
  823. if memebloc(lca^.pc^.pa,pbtermine) then
  824. termine:=true
  825. else
  826. begin
  827. lbt:=copierlistebloc(plact^.plb);
  828. jouercoup(lbt,lca^.pc);
  829. if not existelistebloc(plc,lbt) then
  830. begin
  831. plc:=ajouterlien(plc,lbt,plact,lca^.pc);
  832. plt:=ajouterlien(plt,lbt,plact,lca^.pc);
  833. end;
  834. lca:=lca^.suivant;
  835. end;
  836. end;
  837. procedure extraitsolution;
  838. var dl:plistelien;
  839. lbct:plistebloc;
  840. begin
  841. sol:=nil;
  842. dl:=plact;
  843. lbct:=copierlistebloc(dl^.plb);
  844. jouercoup(lbct,lca^.pc);
  845. sol:=ajouterlien(sol,lbct,nil,lca^.pc);
  846. if plact <> nil then
  847. begin
  848. while dl^.via <> nil do
  849. begin
  850. with dl^ do
  851. sol:=ajouterliendebut(sol,plb,via,pc);
  852. dl:=dl^.via;
  853. end;
  854. sol:=ajouterliendebut(sol,dl^.plb,nil,lca^.pc);
  855. end;
  856. end;
  857. begin
  858. nbg:=0;
  859. writeln('Recherche de la solution minimale');
  860. writeln('---------------------------------');
  861. writeln;
  862. writeln(' Grilles');
  863. writeln('Niveau Connues A traiter');
  864. duree:=TimGetSeconds;
  865. if plb <> nil then
  866. begin
  867. pla:=ajouterlien(nil,plb,nil,nil);
  868. plc:=ajouterlien(nil,plb,nil,nil);
  869. pbtermine:=creerbloc(5,4,hori,deux,principal);
  870. termine:=false;
  871. n:=0;
  872. while not termine do
  873. begin
  874. plt:=nil;
  875. write(n:4);
  876. write(nbliens(plc):10);
  877. writeln(nbliens(pla):10);
  878. plact:=pla;
  879. while (plact^.suivant <> nil) and (not termine) do
  880. begin
  881. traiterlien;
  882. if not termine then
  883. plact:=plact^.suivant;
  884. end;
  885. if not termine then
  886. begin
  887. traiterlien;
  888. pla:=plt;
  889. end;
  890. n:=n+1;
  891. end;
  892. if termine then
  893. begin
  894. extraitsolution;
  895. cherchesolution:=sol;
  896. end
  897. else
  898. cherchesolution:=sol;
  899. duree:=TimGetSeconds - duree;
  900. d:=duree;
  901. nbg:=nbliens(plc);
  902. write(n:4);
  903. write(nbliens(plc):10);
  904. writeln(nbliens(pla):10);
  905. writeln;
  906. writeln('Solution minimale trouvee !');
  907. writeln;
  908. afficherstatistiques(duree,nbliens(sol)-1,nbblocs(sol^.plb),nbg);
  909. end
  910. else
  911. writeln('Aucune liste de blocs donnee');
  912. bip;
  913. read(c);
  914. end;
  915. procedure affichersolution(ll:plistelien);
  916. var llt:plistelien;
  917. begin
  918. if ll <> nil then
  919. begin
  920. llt:=ll;
  921. while llt^.suivant <> nil do
  922. begin
  923. affichelistebloc(llt^.plb);
  924. read(c);
  925. affichecoup(llt^.suivant^.pc);
  926. llt:=llt^.suivant;
  927. end;
  928. affichelistebloc(llt^.plb);
  929. writeln('Termine');
  930. end
  931. else
  932. writeln('Aucun mouvement.');
  933. end;
  934. procedure menugrille(n:byte;s:string);
  935. var select:integer;
  936. m:menu;
  937. sol:plistelien;
  938. plateau:plistebloc;
  939. menusolexiste:boolean;
  940. duree,nbg:integer;
  941. begin
  942. plateau := nil;
  943. plateau:=initplateau(n);
  944. sol:=nil;
  945. menusolexiste:=false;
  946. duree:=0;
  947. nbg:=0;
  948. restaure(n,sol,duree,nbg);
  949. initmenu(m);
  950. titlemenu(m,'Grille ' + s);
  951. addmenuitem(m,'Voir grille');
  952. addmenuitem(m,'Calculer solution');
  953. repeat
  954. if (sol <> nil) and (not menusolexiste) then
  955. begin
  956. menusolexiste:=true;
  957. initmenu(m);
  958. titlemenu(m,'Grille ' + s);
  959. addmenuitem(m,'Voir grille');
  960. addmenuitem(m,'Calculer solution ('+temps(duree)+')');
  961. addmenuitem(m,'Afficher solution (coups : '+IntToString(nbliens(sol)-1)+')');
  962. addmenuitem(m,'Statistiques');
  963. end;
  964. select:=selectmenu(m);
  965. case select of
  966. 1:
  967. begin
  968. clrscr;
  969. writeln;
  970. writeln('Grille initiale');
  971. writeln('---------------');
  972. affichelistebloc(plateau);
  973. read(c);
  974. end;
  975. 2:
  976. begin
  977. clrscr;
  978. sol:=cherchesolution(plateau,duree,nbg);
  979. sauvegarde(n,sol,duree,nbg);
  980. end;
  981. 3:
  982. begin
  983. if menusolexiste then
  984. begin
  985. clrscr;
  986. if sol = nil then
  987. sol:=cherchesolution(plateau,duree,nbg);
  988. if sol <> nil then
  989. begin
  990. clrscr;
  991. writeln;
  992. writeln('Solution minimale');
  993. writeln('-----------------');
  994. affichersolution(sol);
  995. end
  996. else
  997. begin
  998. writeln;
  999. writeln('Pas de solution trouvee.');
  1000. end;
  1001. read(c);
  1002. end;
  1003. end;
  1004. 4:begin
  1005. if menusolexiste then
  1006. begin
  1007. clrscr;
  1008. writeln('Statistiques');
  1009. writeln('------------');
  1010. writeln;
  1011. afficherstatistiques(duree,nbliens(sol)-1,nbblocs(sol^.plb),nbg);
  1012. read(c);
  1013. end;
  1014. end;
  1015. end;
  1016. until select = 0;
  1017. clrscr;
  1018. end;
  1019. procedure menu2;
  1020. var select:integer;
  1021. m:menu;
  1022. n,nmax:byte;
  1023. begin
  1024. nmax:=40;
  1025.  
  1026. initmenu(m);
  1027. titlemenu(m,'Grilles de Traffic!');
  1028. addmenuitem(m,'Test'+existe(0));
  1029. for n:=1 to nmax do
  1030. addmenuitem(m,'Niveau '+IntToString(n)+existe(n));
  1031.  
  1032. repeat
  1033. select:=selectmenu(m);
  1034. if select in [1..nmax+1] then
  1035. menugrille(select-1,'Niveau ' + IntToString(select-1));
  1036. until select = 0;
  1037. clrscr;
  1038. writeln;
  1039. writeln;
  1040. writeln;
  1041. writeln(' ':5,'A bientot');
  1042. end;
  1043. begin
  1044. CPDB_OPENLIB;
  1045. menu2;
  1046. CPDB_CLOSELIB;
  1047. end.