Advertisement
Guest User

Untitled

a guest
Feb 9th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.09 KB | None | 0 0
  1. #define _WIN32_WINNT 0x0500///imi trebuie pentru procedura MaximizeOutputWindow
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #include <windows.h>
  7. #include <conio.h>
  8.  
  9. class cell
  10. {
  11. public:
  12.  
  13. bool viz;
  14. bool wall;///daca e perete sau nu
  15. bool trav;///daca are calator in el
  16. bool m_start;
  17. bool m_end;
  18. int x;
  19. int y;///coordonate celula
  20. int nod;///ce nod este
  21.  
  22. void ini(int i, int j, int &k)///are rol de constructor
  23. {
  24. viz=false;
  25. trav=false;
  26. m_start=false;
  27. m_end=false;
  28. x=i;
  29. y=j;
  30. nod=0;
  31. if (!(i%2 == 0 && j%2 == 0))
  32. wall=true;
  33. else
  34. {
  35. wall=false;
  36. nod=k;
  37. k++;
  38. }
  39. };
  40. };
  41.  
  42. const int dimmax=77;
  43. const int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
  44.  
  45. struct mcoord
  46. {
  47. int x,y;
  48. };
  49.  
  50. cell mtrx[dimmax+1][dimmax+1];
  51. cell vect[(dimmax)*(dimmax)-(dimmax/2)*(dimmax/2)+1];
  52. int index[dimmax*dimmax-(dimmax/2)*(dimmax/2)+1];
  53. int nrnoduri[(dimmax/2)*(dimmax/2)+1];
  54. int boss[(dimmax/2)*(dimmax/2)+1];
  55. mcoord crd[dimmax+1][dimmax+1];
  56.  
  57. class tools
  58. {
  59. public:
  60.  
  61. static void get_size(int &columns, int &rows)
  62. {
  63. CONSOLE_SCREEN_BUFFER_INFO csbi;
  64. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
  65.  
  66. columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
  67. rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
  68. }
  69.  
  70. static void ClearScreen()
  71. {
  72. HANDLE hStdOut;
  73. CONSOLE_SCREEN_BUFFER_INFO csbi;
  74. DWORD count;
  75. DWORD cellCount;
  76. COORD homeCoords = { 0, 0 };
  77.  
  78. hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  79. if (hStdOut == INVALID_HANDLE_VALUE) return;
  80.  
  81. /* Get the number of cells in the current buffer */
  82. if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
  83. cellCount = csbi.dwSize.X *csbi.dwSize.Y;
  84.  
  85. /* Fill the entire buffer with spaces */
  86. if (!FillConsoleOutputCharacter(
  87. hStdOut,
  88. (TCHAR) ' ',
  89. cellCount,
  90. homeCoords,
  91. &count
  92. )) return;
  93.  
  94. /* Fill the entire buffer with the current colors and attributes */
  95. if (!FillConsoleOutputAttribute(
  96. hStdOut,
  97. csbi.wAttributes,
  98. cellCount,
  99. homeCoords,
  100. &count
  101. )) return;
  102.  
  103. /* Move the cursor home */
  104. SetConsoleCursorPosition( hStdOut, homeCoords );
  105. }
  106.  
  107. static int valid_read()
  108. {
  109. int nr;
  110. unsigned int i;
  111. bool ok,mistake;
  112. char s[100];
  113.  
  114. ok=false;
  115. while (!ok)
  116. {
  117. nr=0;
  118. mistake=false;
  119. scanf("%s",s);
  120. for (i=0; i < strlen(s); i++)
  121. {
  122. if (isdigit(s[i]))
  123. nr=nr*10+s[i]-'0';
  124. else
  125. mistake=true;
  126. }
  127. if ((mistake) || (nr < 5) || (nr > 77) || (nr % 2 == 0))
  128. {
  129. ClearScreen();
  130. printf("\nDate invalide! Introduceti din nou numarul!\n");
  131. }
  132. else
  133. ok=true;
  134. }
  135.  
  136. return nr;
  137. }
  138.  
  139. static void color(int i)
  140. {
  141. HANDLE hConsole;
  142. hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  143. SetConsoleTextAttribute(hConsole,i);
  144. }
  145.  
  146. static void MaximizeOutputWindow()
  147. {
  148. HWND consoleWindow = GetConsoleWindow(); // This gets the value Windows uses to identify your output window
  149. ShowWindow(consoleWindow, SW_MAXIMIZE); // this mimics clicking on its' maximize button
  150. }
  151.  
  152. static void gotoXY(short int x, short int y)
  153. {
  154. //Initialize the coordinates
  155. COORD coord = {x, y};
  156. //Set the position
  157. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
  158. return;
  159. }
  160. };
  161. ///procedurile MaximizeOutputWindow, get_size, ClearScreen, color si gotoXY nu au fost implementate de mine; am gasit codul pe internet
  162.  
  163. class maze
  164. {
  165.  
  166. static const char c = 219;
  167. static const char c1 = 0;
  168.  
  169. static int findboss(int x)
  170. {
  171. while (x != boss[x])
  172. x=boss[x];
  173. return x;
  174. }
  175.  
  176. static void cell_merge(int a, int b)
  177. {
  178. if (nrnoduri[a] > nrnoduri[b])
  179. {
  180. boss[b]=a;
  181. nrnoduri[a]+=nrnoduri[b];
  182. }
  183. else
  184. {
  185. boss[a]=b;
  186. nrnoduri[b]+=nrnoduri[a];
  187. }
  188. }
  189.  
  190. public:
  191.  
  192. static void build (int dim1, int dim2)///initializez labirintul; are rol de constructor
  193. {
  194. int i,j,k;
  195.  
  196. k=1;
  197. for (i=1; i<=dim1; i++)
  198. for (j=1; j<=dim2; j++)
  199. mtrx[i][j].ini(i,j,k);
  200. }
  201.  
  202. static void draw(int dim1, int dim2)///desenez labirintul
  203. {
  204. int i,j,x,y,cl,rw;
  205. short int cr1,cr2;
  206.  
  207. tools::get_size(cl,rw);
  208. x=(cl-dim2)/2;
  209. y=(rw-dim1)/2;
  210. cr1=0;
  211. for (i=1; i <= y; i++)
  212. {
  213. printf("\n");
  214. cr1++;
  215. }
  216. for (i=1; i <= dim1; i++)
  217. {
  218. cr2=-1;
  219. for (j=1; j<=x; j++)
  220. {
  221. printf(" ");
  222. cr2++;
  223. }
  224. for (j=1; j<=dim2; j++)
  225. {
  226. if (mtrx[i][j].wall == true)///e perete
  227. {
  228. tools::color(3);
  229. printf("%c",c);
  230. tools::color(15);
  231. }
  232. else if (mtrx[i][j].trav == true)///are calator
  233. {
  234. tools::color(14);
  235. printf("%c",c);
  236. }
  237. else if (mtrx[i][j].m_start == true)///e inceput de labirint
  238. {
  239. tools::color(12);
  240. printf("S");
  241. }
  242. else if (mtrx[i][j].m_end == true)///e sfarsit de labirint
  243. {
  244. tools::color(12);
  245. printf("E");
  246. }
  247. else///e celula accesibila
  248. printf("%c",c1);
  249. cr2++;
  250. crd[i][j].x=cr1;
  251. crd[i][j].y=cr2;
  252. }
  253. printf("\n");
  254. cr1++;
  255. }
  256. for (i=1; i <= y; i++)
  257. printf("\n");
  258. }
  259.  
  260. static void maze_gen(int dim1, int dim2, int &ls, int &cs, int &le, int &ce)
  261. {
  262. int i,j,k,x,y,nrcconex,aux,boss1,boss2;
  263. cell cwall,v1,v2;
  264. bool ok;
  265.  
  266. x=dim1*dim2-(dim2*(dim1/2+1)+(dim2/2+1)*(dim1/2));
  267. for (i=1; i<=x; i++)
  268. {
  269. boss[i]=i;///paduri de multimi disjuncte
  270. nrnoduri[i]=1;
  271. }
  272. nrcconex=x;///numarul de componente conexe
  273.  
  274. k=1;
  275. for (i=1; i<=dim1; i++)
  276. for (j=1; j<=dim2; j++)
  277. {
  278. if (mtrx[i][j].wall == true)
  279. {
  280. vect[k]=mtrx[i][j];
  281. index[k]=k;
  282. k++;
  283. }
  284. }///pun toti peretii intr-un vector si ii indexez, retinand indicii in vectorul index
  285.  
  286. srand(time(NULL));///se foloseste inainte de a aplica random
  287. x=dim2*(dim1/2+1)+(dim2/2+1)*(dim1/2);
  288. for (i=1; i<=x; i++)
  289. {
  290. k=rand()%x;
  291. k+=1;
  292. aux=index[i];
  293. index[i]=index[k];
  294. index[k]=aux;
  295. }///sortez intr-un mod random peretii
  296.  
  297. k=1;
  298. while (nrcconex != 1)///c.t. nu am drum intre toate celulele ce trebuie sa fie accesibile din labirint
  299. {
  300. cwall=vect[index[k]];///extrag un perete din vectorul de pereti
  301. x=cwall.x;
  302. y=cwall.y;///extrag coordonatele peretelui
  303. ok=false;
  304.  
  305. if (x+1 < dim1 && x-1 > 1)///ma asigur ca nu ies din matrice
  306. {
  307. if (mtrx[x+1][y].wall == false)///peretele desparte pe verticala 2 celule care nu sunt pereti
  308. {
  309. v1=mtrx[x+1][y];
  310. v2=mtrx[x-1][y];
  311. ok=true;
  312. }
  313. }
  314.  
  315. if (y+1 < dim2 && y-1 > 1)///ma asigur ca nu ies din matrice
  316. {
  317. if (mtrx[x][y+1].wall == false)///peretele desparte pe orizontala 2 celule care nu sunt pereti
  318. {
  319. v1=mtrx[x][y+1];
  320. v2=mtrx[x][y-1];
  321. ok=true;
  322. }
  323. }
  324.  
  325. if (ok)///daca peretele pe care l-am extras desparte 2 celule care nu sunt pereti
  326. {
  327. boss1=findboss(v1.nod);
  328. boss2=findboss(v2.nod);
  329. if (boss1 != boss2)///celulele nu fac parte din aceeasi componenta conexa
  330. {
  331. cell_merge(boss1,boss2);///le unesc
  332. mtrx[x][y].wall=false;///daram peretele
  333. nrcconex--;///scad numarul de componente conexe
  334. }
  335. }
  336.  
  337. k++;///trec la urmatorul perete
  338. }
  339.  
  340. k=rand()%4;///incep sa generez intrarea
  341. if (k == 0)
  342. {
  343. boss1=rand()%(dim1-1)+1;
  344. boss2=1;
  345. if (boss1%2 == 1)
  346. boss1++;
  347. }
  348. else if (k == 1)
  349. {
  350. boss1=rand()%(dim1-1)+1;
  351. boss2=dim2;
  352. if (boss1%2 == 1)
  353. boss1++;
  354. }
  355. else if (k == 2)
  356. {
  357. boss1=1;
  358. boss2=rand()%(dim2-1)+1;
  359. if (boss2%2 == 1)
  360. boss2++;
  361. }
  362. else if (k == 3)
  363. {
  364. boss1=dim1;
  365. boss2=rand()%(dim2-1)+1;
  366. if (boss2%2 == 1)
  367. boss2++;
  368. }
  369. mtrx[boss1][boss2].m_start=true;
  370. mtrx[boss1][boss2].wall=false;
  371. ls=boss1;
  372. cs=boss2;
  373. x=boss1;
  374. y=boss2;///termin de generat intrarea
  375. mtrx[boss1][boss2].trav=true;
  376.  
  377. while (boss1 == x && boss2 == y)///ma asigur ca iesirea nu coincide cu intrarea
  378. {
  379. k=rand()%4;
  380. if (k == 0)
  381. {
  382. boss1=rand()%(dim1-1)+1;
  383. boss2=1;
  384. if (boss1%2 == 1)
  385. boss1++;
  386. }
  387. else if (k == 1)
  388. {
  389. boss1=rand()%(dim1-1)+1;
  390. boss2=dim2;
  391. if (boss1%2 == 1)
  392. boss1++;
  393. }
  394. else if (k == 2)
  395. {
  396. boss1=1;
  397. boss2=rand()%(dim2-1)+1;
  398. if (boss2%2 == 1)
  399. boss2++;
  400. }
  401. else if (k == 3)
  402. {
  403. boss1=dim1;
  404. boss2=rand()%(dim2-1)+1;
  405. if (boss2%2 == 1)
  406. boss2++;
  407. }
  408. }
  409. mtrx[boss1][boss2].m_end=true;///termin de generat iesirea
  410. mtrx[boss1][boss2].wall=false;
  411. le=boss1;
  412. ce=boss2;
  413. }
  414.  
  415. static void solve(int dim1, int dim2, int lc, int cc, bool &ok)///ok este fals la apel
  416. {
  417. int i,x,y;
  418.  
  419. for (i=0; i<4; i++)
  420. {
  421. x=lc+d[i][0];
  422. y=cc+d[i][1];
  423.  
  424. if ((x >=1 && x <= dim1) && (y >=1 && y <= dim2))
  425. {
  426. if (mtrx[x][y].wall == false && mtrx[x][y].m_start == false && mtrx[x][y].viz == false && !ok)
  427. {
  428. mtrx[x][y].viz=true;
  429. solve(dim1,dim2,x,y,ok);
  430. }
  431. }
  432. }
  433.  
  434. if (mtrx[lc][cc].m_end == true)
  435. ok=true;
  436. if (ok)
  437. mtrx[lc][cc].trav=true;
  438. }
  439.  
  440. static void game(int dim1, int dim2, int ls, int cs, int le, int ce)
  441. {
  442. bool ok3,ok2,ok4;
  443. char key;
  444. int lc,cc,x,y;
  445.  
  446. ok3=false;
  447. ok2=false;
  448. lc=ls;///linia curenta=lina de start
  449. cc=cs;///coloana curenta=coloana de start
  450. while (ok3 == false && ok2 == false)
  451. {
  452.  
  453. char key = ' ';
  454. key = _getch();
  455. if (key == 'w')///sus
  456. {
  457. if (lc-1 >=1 && mtrx[lc-1][cc].wall == false)///nu ies din matrice si nu dau de un perete
  458. {
  459. x=crd[lc][cc].x;
  460. y=crd[lc][cc].y;
  461. mtrx[lc][cc].trav=false;
  462. tools::gotoXY(y,x);
  463. if (mtrx[lc][cc].m_start == true)///e inceput de labirint
  464. {
  465. tools::color(12);
  466. printf("S");
  467. }
  468. else if (mtrx[lc][cc].m_end == true)///e sfarsit de labirint
  469. {
  470. tools::color(12);
  471. printf("E");
  472. }
  473. else///e celula accesibila
  474. printf("%c",c1);
  475. x=x-1;
  476. mtrx[lc-1][cc].trav=true;
  477. if (mtrx[lc-1][cc].m_end == true)
  478. ok3=true;
  479. tools::gotoXY(y,x);
  480. tools::color(14);
  481. printf("%c",c);
  482. lc--;
  483. }
  484. }
  485. if (key == 's')///jos
  486. {
  487. if (lc+1 <= dim1 && mtrx[lc+1][cc].wall == false)///nu ies din matrice si nu dau de un perete
  488. {
  489. x=crd[lc][cc].x;
  490. y=crd[lc][cc].y;
  491. mtrx[lc][cc].trav=false;
  492. tools::gotoXY(y,x);
  493. if (mtrx[lc][cc].m_start == true)///e inceput de labirint
  494. {
  495. tools::color(12);
  496. printf("S");
  497. }
  498. else if (mtrx[lc][cc].m_end == true)///e sfarsit de labirint
  499. {
  500. tools::color(12);
  501. printf("E");
  502. }
  503. else///e celula accesibila
  504. printf("%c",c1);
  505. x=x+1;
  506. mtrx[lc+1][cc].trav=true;
  507. if (mtrx[lc+1][cc].m_end == true)
  508. ok3=true;
  509. tools::gotoXY(y,x);
  510. tools::color(14);
  511. printf("%c",c);
  512. lc++;
  513. }
  514. }
  515. if (key == 'a')///stanga
  516. {
  517. if (cc-1 >= 1 && mtrx[lc][cc-1].wall == false)///nu ies din matrice si nu dau de un perete
  518. {
  519. x=crd[lc][cc].x;
  520. y=crd[lc][cc].y;
  521. mtrx[lc][cc].trav=false;
  522. tools::gotoXY(y,x);
  523. if (mtrx[lc][cc].m_start == true)///e inceput de labirint
  524. {
  525. tools::color(12);
  526. printf("S");
  527. }
  528. else if (mtrx[lc][cc].m_end == true)///e sfarsit de labirint
  529. {
  530. tools::color(12);
  531. printf("E");
  532. }
  533. else///e celula accesibila
  534. printf("%c",c1);
  535. y=y-1;
  536. mtrx[lc][cc-1].trav=true;
  537. if (mtrx[lc][cc-1].m_end == true)
  538. ok3=true;
  539. tools::gotoXY(y,x);
  540. tools::color(14);
  541. printf("%c",c);
  542. cc--;
  543. }
  544. }
  545. if (key == 'd')///dreapta
  546. {
  547. if (cc+1 <= dim2 && mtrx[lc][cc+1].wall == false)///nu ies din matrice si nu dau de un perete
  548. {
  549. x=crd[lc][cc].x;
  550. y=crd[lc][cc].y;
  551. mtrx[lc][cc].trav=false;
  552. tools::gotoXY(y,x);
  553. if (mtrx[lc][cc].m_start == true)///e inceput de labirint
  554. {
  555. tools::color(12);
  556. printf("S");
  557. }
  558. else if (mtrx[lc][cc].m_end == true)///e sfarsit de labirint
  559. {
  560. tools::color(12);
  561. printf("E");
  562. }
  563. else///e celula accesibila
  564. printf("%c",c1);
  565. y=y+1;
  566. mtrx[lc][cc+1].trav=true;
  567. if (mtrx[lc][cc+1].m_end == true)
  568. ok3=true;
  569. tools::gotoXY(y,x);
  570. tools::color(14);
  571. printf("%c",c);
  572. cc++;
  573. }
  574. }
  575. if (key == 'h')
  576. ok2=true;
  577. }
  578. tools::ClearScreen();
  579. tools::color(15);
  580. if (ok3)
  581. printf("Bravo!");
  582. else
  583. {
  584. ok4=false;
  585. solve(dim1,dim2,lc,cc,ok4);
  586. draw(dim1,dim2);
  587. }
  588.  
  589. }
  590. };
  591.  
  592. int main()
  593. {
  594. int dim1,dim2,ls,cs,le,ce;
  595. bool ok;
  596. char c;
  597.  
  598. tools::MaximizeOutputWindow();
  599. tools::color(15);
  600. printf("MAZE GENERATOR\n\n\n\n");
  601. printf("1)Alegeti dimensiunile labirintului.\n");
  602. printf("2)Jucati! (va miscati pe w,a,s,d, iar daca vreti rezolvarea, apasati tasta h)\n\n\n\n");
  603. printf("Care sunt dimensiunile labirintului?\n");
  604. printf("(numere ");
  605. tools::color(12);
  606. printf("impare");
  607. tools::color(15);
  608. printf(" mai mari decat ");
  609. tools::color(12);
  610. printf("3");
  611. tools::color(15);
  612. printf(" si mai mici decat ");
  613. tools::color(12);
  614. printf("79");
  615. tools::color(15);
  616. printf(")\n");
  617. printf("Care este prima dimensiune?\n");
  618. dim1=tools::valid_read();
  619. printf("Care este a doua dimensiune?\n");
  620. dim2=tools::valid_read();
  621. tools::ClearScreen();
  622.  
  623. maze::build(dim1,dim2);
  624. maze::maze_gen(dim1,dim2,ls,cs,le,ce);
  625. maze::draw(dim1,dim2);
  626. maze::game(dim1,dim2,ls,cs,le,ce);
  627. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement