Advertisement
Dalacul

Untitled

Dec 4th, 2019
526
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.91 KB | None | 0 0
  1. #include <ncurses.h>
  2. #include <stdbool.h>
  3. #include <stdarg.h>
  4. #include <unistd.h>
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #define xMax 80
  8. #define height_m 10
  9. #define width_m 20
  10. #define start_y_m 3
  11. #define start_x_m ((xMax - width_m) / 2 - 1)
  12. #define height_g 16
  13. #define width_g 50
  14. #define start_y_g 3
  15. #define start_x_g ((xMax - width_g) / 2 - 1)
  16.  
  17. struct matrix1010
  18. {
  19.     char m[10][10];
  20. };
  21.  
  22. struct nava
  23. {
  24.     int dim, id;//dim - dimensiune - de la 1 la 4
  25.                 //id - identificatorul barcii - de la 1 la 10
  26.     int dir;    //directia: 1 vertical | 0 orizontal | -1 nu are directie
  27.     int intacte;//cate parti intacte are nava. 0 daca nava este distrusa
  28.     char status[4];//maxim 4 patratele. 1 - intact, 0 - lovit
  29. };
  30.  
  31. /*
  32. TODO: ADD FUNCTION DECLARATION
  33.  
  34. */
  35.  
  36. //TODO: ADD comp_ppov TO LOGS, READ comp_ppov FROM LOGS
  37.  
  38.  
  39.  
  40.  
  41. void start_ncurses(void)
  42. {
  43.     initscr();
  44.     cbreak();
  45.     noecho();
  46.     start_color();
  47.     curs_set(0);
  48.     srand(time(0)); //nu face parte din ncurses, dar tot e initializare
  49.     refresh();
  50. }
  51.  
  52. WINDOW *start_win(const int h, const int w, const int y, const int x,
  53.                   const char lr, const char tb, const char cor)
  54. {
  55.     WINDOW *win = newwin(h, w, y, x);
  56.     wborder(win, lr, lr, tb, tb, cor, cor, cor, cor);
  57.     //wborder(win, left, right, top, bottom, tlc, trc, blc, brc)
  58.     keypad(win, true);
  59.     return win;
  60. }
  61.  
  62. void clrwin(WINDOW *win)
  63. {
  64.     win = newwin(0, 0, 0, 0);
  65.     wrefresh(win);
  66. }
  67.  
  68. bool open_files(int nr_files, FILE **fin, char *arg[], struct matrix1010 map[])
  69. {
  70.     //1 - eroare
  71.     int k = 0;
  72.     for(k = 0; k < nr_files; ++k) {
  73.         fin[k] = fopen(arg[k + 1], "r");
  74.         if(fin[k] == NULL)
  75.         {
  76.             fprintf(stderr, "[Eroare]: Fisierul %s nu poate fi deschis.\n",
  77.                     arg[k]);
  78.             return 1;
  79.         }
  80.         int i = 0, j = 0;
  81.         for(i = 0; i < 10; ++i)
  82.         {
  83.             for(j = 0; j < 10; ++j)
  84.             {
  85.                 fscanf(fin[k], "|%c", &map[k].m[i][j]);
  86.             }
  87.             fscanf(fin[k], "|\n");
  88.         }
  89.     }
  90.     return 0;
  91. }
  92.  
  93. void close_files(FILE *logs, FILE *scores, int nr_files, FILE **fin)
  94. {
  95.     fclose(logs);
  96.     fclose(scores);
  97.     int i;
  98.     for(i = 0; i < nr_files; ++i)
  99.         fclose(fin[i]);
  100.     //free(fin);
  101. }
  102.  
  103. void read_logs(FILE *logs, struct nava ship[2][10],
  104.                 int *nave_pl, int *nave_cmp,
  105.                 struct matrix1010 *player, struct matrix1010 *computer,
  106.                 struct matrix1010 *comp_ppov)
  107. {
  108.     fclose(logs);
  109.     logs = fopen("logs", "r");
  110.     fscanf(logs, "1\n");//citim valoarea de resume, pe care o stim ca este 1
  111.     fscanf(logs, "%d %d\n", &(*nave_pl), &(*nave_cmp));
  112.     int i, j, k, value;
  113.     for(i = 0; i < 2; ++i)
  114.         for(j = 0; j < 10; ++j)
  115.         {
  116.             ship[i][j].id = j + 1;
  117.             fscanf(logs, "%d %d %d ", &ship[i][j].dim, &ship[i][j].intacte,
  118.                                         &ship[i][j].dir);
  119.             for(k = 0; k < ship[i][j].dim; ++k)
  120.             {
  121.                 fscanf(logs, "%d ", &value);
  122.                 ship[i][j].status[k] = value;
  123.                 //printw("val: %d | stat[%d]: %d\n", value, k, ship[i][j].status[k]);
  124.             }
  125.             fscanf(logs, "\n");
  126.         }
  127.     for(i = 0; i < 10; ++i)
  128.     {
  129.         for(j = 0; j < 10; ++j)
  130.         {
  131.             fscanf(logs, "%d ", &value);
  132.             (*player).m[i][j] = value;
  133.         }
  134.         fscanf(logs, "\n");
  135.     }
  136.     for(i = 0; i < 10; ++i)
  137.     {
  138.         for(j = 0; j < 10; ++j)
  139.         {
  140.             fscanf(logs, "%d ", &value);
  141.             (*computer).m[i][j] = value;
  142.         }
  143.         fscanf(logs, "\n");
  144.     }
  145.     for(i = 0; i < 10; ++i)
  146.     {
  147.         for(j = 0; j < 10; ++j)
  148.         {
  149.             fscanf(logs, "%d ", &value);
  150.             (*comp_ppov).m[i][j] = value;
  151.         }
  152.         fscanf(logs, "\n");
  153.     }
  154. }
  155.  
  156. void write_logs(FILE *logs, int resume, struct nava ship[2][10],
  157.                 int nave_pl, int nave_cmp,
  158.                 struct matrix1010 player, struct matrix1010 computer,
  159.                 struct matrix1010 comp_ppov)
  160. {
  161.     fclose(logs);
  162.     logs = fopen("logs", "w");
  163.     fprintf(logs, "%d\n", resume);
  164.     fprintf(logs, "%d %d\n", nave_pl, nave_cmp);
  165.     int i, j, k;
  166.     for(i = 0; i < 2; ++i)
  167.         for(j = 0; j < 10; ++j)
  168.         {
  169.             fprintf(logs, "%d %d %d ", ship[i][j].dim, ship[i][j].intacte,
  170.                                         ship[i][j].dir);
  171.             for(k = 0; k < ship[i][j].dim; ++k)
  172.                 fprintf(logs, "%d ", ship[i][j].status[k]);
  173.             fprintf(logs, "\n");
  174.         }
  175.     for(i = 0; i < 10; ++i)
  176.     {
  177.         for(j = 0; j < 10; ++j)
  178.             fprintf(logs, "%d ", player.m[i][j]);
  179.         fprintf(logs, "\n");
  180.     }
  181.     for(i = 0; i < 10; ++i)
  182.     {
  183.         for(j = 0; j < 10; ++j)
  184.             if(computer.m[i][j] != -1)
  185.                 fprintf(logs, "%d ", computer.m[i][j]);
  186.             else
  187.                 fprintf(logs, "0 ");
  188.         fprintf(logs, "\n");
  189.     }
  190.     for(i = 0; i < 10; ++i)
  191.     {
  192.         for(j = 0; j < 10; ++j)
  193.             fprintf(logs, "%d ", comp_ppov.m[i][j]);
  194.         fprintf(logs, "\n");
  195.     }
  196.     return;
  197. }
  198.  
  199. void read_scores(FILE *scores)
  200. {
  201.     fclose(scores);
  202.     scores = fopen("scores", "r");
  203.     int Pships, Cships, Pwins = 0, Cwins = 0, Twins, TPships = 0, TCships = 0;
  204.     while(fscanf(scores, "%d - %d\n", &Pships, &Cships) != EOF)
  205.     if(Pships == 10)
  206.         ++Pwins;
  207.     else
  208.         ++Cwins;
  209.     Twins = Pwins + Cwins;
  210.     fclose(scores);
  211.     scores = fopen("scores", "r");
  212.  
  213.     WINDOW *menuwin = start_win(10, 28, start_y_g, start_x_g - 12,
  214.                                 '|', '~', '+');
  215.     mvwprintw(menuwin, 1, 1, " P  -  C");
  216.     mvwprintw(menuwin, 2, 1, "~~~~~~~~~~~~~~~~~~~~~~~~~~");
  217.     mvwprintw(menuwin, 3, 1, "%3d - %3d wins", Pwins, Twins);
  218.     int i;
  219.     for(i = 0; i < Twins; ++i)
  220.     {
  221.         fscanf(scores, "%d - %d\n", &Pships, &Cships);
  222.         //mvwprintw(menuwin, i + 3, 1, "%2d - %2d", Pships, Cships);
  223.         TPships += Pships;
  224.         TCships += Cships;
  225.     }
  226.     mvwprintw(menuwin, 4, 1, "%3d - %3d total destroyed", TPships, TCships);
  227.     mvwprintw(menuwin, 5, 1, "~~~~~~~~~~~~~~~~~~~~~~~~~~");
  228.     wrefresh(menuwin);
  229. }
  230.  
  231. void write_scores(FILE *scores, bool whowin, int nave_distruse)
  232. {
  233.     fclose(scores);
  234.     scores = fopen("scores", "a");
  235.     if(whowin == 1) //player win
  236.         fprintf(scores, "\n10 - %d", nave_distruse);
  237.     else            //computer win
  238.         fprintf(scores, "\n%d - 10", nave_distruse);
  239. }
  240.  
  241. void setplayership(struct nava *ship, const int dim,
  242.                     const int index, const int dir)
  243. {
  244.     (*ship).dim = dim;
  245.     (*ship).intacte = dim;
  246.     (*ship).dir = dir;
  247.     (*ship).id = index;
  248.     int i;
  249.     for(i = 0; i < dim; ++i)
  250.         (*ship).status[i] = 1;
  251. }
  252.  
  253. void visual_to_value(struct matrix1010 *A, struct nava ship[])
  254. {
  255.     int i, j, index = 0;
  256.     for(i = 0; i < 10; ++i)
  257.         for(j = 0; j < 10; ++j)
  258.         {
  259.             if((*A).m[i][j] == ' ')
  260.                 (*A).m[i][j] = 0;
  261.             else if((*A).m[i][j] == 'X')
  262.             {
  263.                 ++index;
  264.                 (*A).m[i][j] = index;
  265.                 int k;
  266.                 k = j + 1;
  267.                 while(k < 10 && (*A).m[i][k] == 'X')//nava este pe orizontal
  268.                 {
  269.                     (*A).m[i][k] = index;  
  270.                     ++k;
  271.                 }
  272.                 if(k - 1 != j)
  273.                     setplayership(&ship[index-1], k - j, index, 0);
  274.                 else
  275.                 {
  276.                     k = i + 1;
  277.                     while(k < 10 && (*A).m[k][j] == 'X')//nava este pe vertical
  278.                     {
  279.                         (*A).m[k][j] = index;
  280.                         ++k;
  281.                     }
  282.                     if(k - 1 != i)
  283.                         setplayership(&ship[index-1], k - i, index, 1);
  284.                     else//nava are dimensiunea 1
  285.                         setplayership(&ship[index-1], 1, index, -1);
  286.                 }
  287.             }
  288.         }
  289. }
  290.  
  291. void init_matrix(struct matrix1010 *A)
  292. {
  293.     int i, j;
  294.     for(i = 0; i < 10; ++i)
  295.         for(j = 0; j < 10; ++j)
  296.             (*A).m[i][j] = 0;
  297. }
  298.  
  299. void init_ships(struct nava ship[])
  300. {
  301.     int i, j;
  302.     int dimensions[] = {4, 3, 3, 2, 2, 2, 1, 1, 1, 1};
  303.     for(i = 0; i < 10; ++i)
  304.     {
  305.         ship[i].id = i + 1;
  306.         ship[i].dim = dimensions[i];
  307.         ship[i].intacte = ship[i].dim;
  308.         for(j = 0; j < ship[i].dim; ++j)
  309.             ship[i].status[j] = 1;
  310.     }
  311. }
  312.  
  313. bool check_vertically(int rline, int rcolumn, int dim, struct matrix1010 A)
  314. {
  315.     //verificare peste tot pe teritoriul navei si in jurul ei
  316.     int i;
  317.     int rline1 = rline + dim;
  318.     if(rline > 0)
  319.     {
  320.         if(rcolumn > 0 && A.m[rline-1][rcolumn-1] > 0)
  321.             return 0;
  322.         if(rcolumn < 9 && A.m[rline-1][rcolumn+1] > 0)
  323.             return 0;
  324.         if(A.m[rline-1][rcolumn] > 0)
  325.             return 0;
  326.     }
  327.     if(rline1 < 9)
  328.     {
  329.         if(rcolumn > 0 && A.m[rline1][rcolumn-1] > 0)
  330.             return 0;
  331.         if(rcolumn < 9 && A.m[rline1][rcolumn+1] > 0)
  332.             return 0;
  333.         if(A.m[rline1][rcolumn] > 0)
  334.             return 0;
  335.     }
  336.     if(rcolumn > 0)
  337.         for(i = rline; i < rline1; ++i)
  338.             if(A.m[i][rcolumn-1] > 0)
  339.                 return 0;
  340.     if(rcolumn < 9)
  341.         for(i = rline; i < rline1; ++i)
  342.             if(A.m[i][rcolumn+1] > 0)
  343.                 return 0;
  344.     for(i = rline; i < rline1; ++i)
  345.         if(A.m[i][rcolumn])
  346.             return 0;
  347.     return 1;
  348. }
  349.  
  350. bool check_horizontally(int rline, int rcolumn, int dim, struct matrix1010 A)
  351. {
  352.     int i;
  353.     int rcolumn1 = rcolumn + dim ;
  354.     if(rcolumn > 0)
  355.     {
  356.         if(rline > 0 && A.m[rline-1][rcolumn-1] > 0)
  357.             return 0;
  358.         if(rline < 9 && A.m[rline+1][rcolumn-1] > 0)
  359.             return 0;
  360.         if(A.m[rline][rcolumn-1] > 0)
  361.             return 0;
  362.     }
  363.     if(rcolumn1 < 9)
  364.     {
  365.         if(rline > 0 && A.m[rline-1][rcolumn1] > 0)
  366.             return 0;
  367.         if(rline < 9 && A.m[rline+1][rcolumn1] > 0)
  368.             return 0;
  369.         if(A.m[rline][rcolumn1])
  370.             return 0;
  371.     }
  372.     if(rline > 0)
  373.         for(i = rcolumn; i < rcolumn1; ++i)
  374.             if(A.m[rline-1][i] > 0)
  375.                 return 0;
  376.     if(rline < 9)
  377.         for(i = rcolumn; i < rcolumn1; ++i)
  378.             if(A.m[rline+1][i] > 0)
  379.                 return 0;
  380.     for(i = rcolumn; i < rcolumn1; ++i)
  381.         if(A.m[rline][i])
  382.             return 0;
  383.     return 1;
  384. }
  385.  
  386. void place_vertically(const int rline, const int rcolumn, const int dim,
  387.                         const int ship_id, struct matrix1010 *A)
  388. {
  389.     //se cunoaste faptul ca se poate plasa
  390.     int i;
  391.     int rline1 = rline + dim;
  392.     for(i = rline; i < rline1; ++i)
  393.         (*A).m[i][rcolumn] = ship_id;
  394.     if(rline > 0)
  395.     {
  396.         if(rcolumn > 0)
  397.             (*A).m[rline-1][rcolumn-1] = -1;
  398.         if(rcolumn < 9)
  399.             (*A).m[rline-1][rcolumn+1] = -1;
  400.         (*A).m[rline-1][rcolumn] = -1;
  401.     }
  402.     if(rline1 < 9)
  403.     {
  404.         if(rcolumn > 0)
  405.             (*A).m[rline1][rcolumn-1] = -1;
  406.         if(rcolumn < 9)
  407.             (*A).m[rline1][rcolumn+1] = -1;
  408.         (*A).m[rline1][rcolumn] = -1;
  409.     }
  410.     if(rcolumn > 0)
  411.         for(i = rline; i < rline1; ++i)
  412.             (*A).m[i][rcolumn-1] = -1;
  413.     if(rcolumn < 9)
  414.         for(i = rline; i < rline1; ++i)
  415.             (*A).m[i][rcolumn+1] = -1;
  416. }
  417.  
  418. void place_horizontally(const int rline, const int rcolumn, const int dim,
  419.                         const int ship_id, struct matrix1010 *A)
  420. {
  421.     //se cunoaste faptul ca se poate plasa
  422.     int i;
  423.     int rcolumn1 = rcolumn + dim;
  424.     for(i = rcolumn; i < rcolumn1; ++i)
  425.         (*A).m[rline][i] = ship_id;
  426.     if(rcolumn > 0)
  427.     {
  428.         if(rline > 0)
  429.             (*A).m[rline-1][rcolumn-1] = -1;
  430.         if(rline < 9)
  431.             (*A).m[rline+1][rcolumn-1] = -1;
  432.         (*A).m[rline][rcolumn-1] = -1;
  433.     }
  434.     if(rcolumn1 < 9)
  435.     {
  436.         if(rline > 0)
  437.             (*A).m[rline-1][rcolumn1] = -1;
  438.         if(rcolumn < 9)
  439.             (*A).m[rline+1][rcolumn1] = -1;
  440.         (*A).m[rline+1][rcolumn] = -1;
  441.     }
  442.     if(rline > 0)
  443.         for(i = rcolumn; i < rcolumn1; ++i)
  444.             (*A).m[rline-1][i] = -1;
  445.     if(rline < 9)
  446.         for(i = rcolumn; i < rcolumn1; ++i)
  447.             (*A).m[rline+1][i] = -1;
  448. }
  449.  
  450. bool random_place(struct nava *ship, struct matrix1010 *A)
  451. {
  452.     //return 1 - eroare
  453.     //return 0 - OK
  454.     int rline, rcolumn, rdirection, tries = 0;
  455.     bool placed = false;
  456.     do
  457.     {
  458.         ++tries;
  459.         if(tries == 100)
  460.         {
  461.             tries = 0;
  462.             return 1;
  463.         }
  464.         rline = rand() % 10;
  465.         rcolumn = rand() % 10;
  466.         rdirection = rand() % 2;
  467.         // 1 vertical in jos, 0 orizontal in dreapta
  468.         if(rdirection && rline + (*ship).dim < 10)
  469.             if(check_vertically(rline, rcolumn, (*ship).dim, *A))
  470.             {
  471.                 //verificam adiacenta pe verticala
  472.                 place_vertically(rline, rcolumn, (*ship).dim, (*ship).id, A);
  473.                 placed = true;
  474.             }
  475.         if(!rdirection && rcolumn + (*ship).dim < 10)
  476.             if(check_horizontally(rline, rcolumn, (*ship).dim, *A))
  477.             {
  478.                 //verificam adiacenta pe orizontala
  479.                 place_horizontally(rline, rcolumn, (*ship).dim, (*ship).id, A);
  480.                 placed = true;
  481.             }
  482.     }while(!placed);
  483.     (*ship).dir = rdirection;
  484.     return 0;
  485. }
  486.  
  487. struct matrix1010 random_map(struct nava ship[])
  488. {
  489.     /*
  490.     ship[0-0] - dimensiune 4
  491.     ship[1-2] - dimensiune 3
  492.     ship[3-5] - dimensiune 2
  493.     ship[6-9] - dimensiune 1
  494.     */
  495.     struct matrix1010 map;
  496.     init_matrix(&map);
  497.     init_ships(ship);
  498.     int i;
  499.     for(i = 0; i < 10; ++i)
  500.         if(random_place(&ship[i], &map))
  501.         {  
  502.             init_matrix(&map);
  503.             i = -1;
  504.         }
  505.     return map;
  506. }
  507.  
  508. int highlighter(WINDOW *win, const int nr_choices, char *choices[])
  509. {
  510.     int choice;
  511.     int highlight = 0;
  512.     while(true)
  513.     {
  514.         int i;
  515.         for(i = 0; i < nr_choices; ++i)
  516.         {
  517.             if(i == highlight)
  518.                 wattron(win, A_REVERSE);
  519.             mvwprintw(win, i + 1, 1, choices[i]);
  520.             wattroff(win, A_REVERSE);
  521.         }
  522.         choice = wgetch(win);
  523.         switch(choice)
  524.         {
  525.             case KEY_UP:
  526.                 --highlight;
  527.                 if(highlight == -1)
  528.                     highlight = 0;
  529.                 break;
  530.             case KEY_DOWN:
  531.                 ++highlight;
  532.                 if(highlight == nr_choices)
  533.                     highlight = nr_choices - 1;
  534.                 break;
  535.             default:
  536.                 break;
  537.         }
  538.         if(choice == 'q' || choice == 'Q')
  539.             return -1;
  540.         if(choice == 10)//ENTER
  541.             break;
  542.     }
  543.     win = newwin(0, 0, 0, 0);
  544.     clrwin(win);
  545.     return highlight;
  546. }
  547.  
  548. int menu(const int resume)
  549. {
  550.     WINDOW *menuwin = start_win(height_m, width_m, start_y_m, start_x_m,
  551.                                 '|', '~', '+');
  552.     mvwprintw(menuwin, 0, 5, "Battleship");
  553.  
  554.     int highlight = 0;
  555.     /*
  556.     RETURN CODES:
  557.     0 - Quit
  558.     1 - New Game
  559.     2 - Resume Game
  560.     3 - Score
  561.     */
  562.     if(!resume)
  563.     {
  564.         char *choices[] = {
  565.             "New Game",
  566.             "Score",
  567.             "Quit"
  568.         };
  569.         highlight = highlighter(menuwin, 3, choices);
  570.         if(highlight == 1)
  571.             return 3;
  572.         return (highlight + 1) % 3; //se verifica codurile de mai sus
  573.     }
  574.     else
  575.     {
  576.         char *choices[] = {
  577.             "New Game",
  578.             "Resume Game",
  579.             "Score",
  580.             "Quit"
  581.         };
  582.         highlight = highlighter(menuwin, 4, choices);
  583.         return (highlight + 1) % 4; //se verifica codurile de mai sus
  584.     }
  585. }
  586.  
  587. int choosemap_menu()
  588. {
  589.     WINDOW *menuwin = start_win(height_m, width_m, start_y_m, start_x_m,
  590.                                 '|', '~', '+');
  591.     mvwprintw(menuwin, 0, 5, "Battleship");
  592.     char *choices[] = {
  593.         "Alege harta",
  594.         "Harta aleatorie"  
  595.     };
  596.     clrwin(menuwin);
  597.     return highlighter(menuwin, 2, choices);
  598. }
  599.  
  600. int choose_map(FILE **fin, const int nr_maps, struct matrix1010 map[])
  601. {
  602.     int hl = choosemap_menu();
  603.     if(hl == 1)//alegere aleatorie a hartii
  604.         return (rand() % nr_maps);
  605.     if(hl == -1)//ne intoarcem in meniul principal
  606.         return -1;
  607.     //else -> jucatorul isi alege harta
  608.     WINDOW *game = start_win(height_g, width_g, start_y_g, start_x_g,
  609.                              '|', '~', '+');
  610.     keypad(game, true);
  611.     mvwprintw(game, 0, 20, "Battleship");
  612.     mvwprintw(game, 1, 6, "Alege configuratia predefinita de nave");
  613.     mvwprintw(game, 2, 1, "================================================");
  614.     mvwprintw(game, 14, 9, "Apasa sageata stanga sau dreapta");
  615.     wrefresh(game);
  616.     int selected = 0;
  617.     while(true)
  618.     {
  619.         int i, j;
  620.         for(i = 3; i <= 12; ++i)
  621.         {
  622.             for(j = 1; j <= 10; ++j)
  623.             {
  624.                 char ch = map[selected].m[i - 3][j - 1];
  625.                 if(ch != ' ' && ch != 0)
  626.                         mvwprintw(game, i, 13 + 2 * j - 1, "|X");
  627.                 else
  628.                     mvwprintw(game, i, 13 + 2 * j - 1, "| ");
  629.             }
  630.             mvwprintw(game, i, 13 + 21, "|");
  631.         }
  632.         int choice = wgetch(game);
  633.         switch(choice)
  634.         {
  635.             case KEY_LEFT:
  636.                 --selected;
  637.                 if(selected == -1)
  638.                     selected = 0;
  639.                 break;
  640.             case KEY_RIGHT:
  641.                 ++selected;
  642.                 if(selected == nr_maps)
  643.                     selected = nr_maps - 1;
  644.                 break;
  645.             case 'Q':
  646.                 clrwin(game);
  647.                 return -1;
  648.                 break;
  649.             case 'q':
  650.                 clrwin(game);
  651.                 return -1;
  652.                 break;
  653.             default:
  654.                 break;
  655.             wrefresh(game);
  656.         }
  657.         if(choice == 10)//ENTER
  658.             break;
  659.     }
  660.     clrwin(game);
  661.     return selected;
  662. }
  663.  
  664. void print_player_map(WINDOW *game, struct matrix1010 player)
  665. {
  666.     int i, j;
  667.     for(i = 3; i <= 12; ++i)
  668.     {
  669.         for(j = 1; j <= 10; ++j)
  670.         {
  671.             char ch = player.m[i - 3][j - 1];
  672.             //printw("player.m[%d][%d]: %d\n", i-2, j, ch);
  673.             switch(ch)
  674.             {
  675.                 case 0:
  676.                     mvwprintw(game, i, 2 * j - 1, "| ");
  677.                     break;
  678.                 case -2:
  679.                     mvwprintw(game, i, 2 * j - 1, "|#");
  680.                     break;
  681.                 case -3:
  682.                     mvwprintw(game, i, 2 * j - 1, "|-");
  683.                     break;
  684.                 default:
  685.                     //printw("afisat X la: %d\n", ch);
  686.                     mvwprintw(game, i, 2 * j - 1, "|X");
  687.                     break;
  688.             }
  689.         }
  690.         mvwprintw(game, i, 21, "|");
  691.     }
  692. }
  693.  
  694. void print_computer_map(WINDOW *game, struct matrix1010 computer,
  695.                         const int hl_i, const int hl_j)
  696. {
  697.     int i, j;
  698.     for(i = 3; i <= 12; ++i)
  699.         {
  700.             for(j = 1; j <= 10; ++j)
  701.             {
  702.                 char ch = computer.m[i-3][j-1];
  703.                 if(i - 3 == hl_i && j - 1 == hl_j)
  704.                         mvwprintw(game, i, 27 + 2 * j - 1, "|O");
  705.                 else
  706.                     switch(ch)
  707.                     {
  708.                         case -1:
  709.                             mvwprintw(game, i, 27 + 2 * j - 1, "| ");
  710.                             break;
  711.                         case 0:
  712.                             mvwprintw(game, i, 27 + 2 * j - 1, "| ");
  713.                             break;
  714.                         case -2:
  715.                             mvwprintw(game, i, 27 + 2 * j - 1, "|#");
  716.                             break;
  717.                         case -3:
  718.                             mvwprintw(game, i, 27 + 2 * j - 1, "|-");
  719.                             break;
  720.                         default:
  721.                             mvwprintw(game, i, 27 + 2 * j - 1, "|X");
  722.                             break;
  723.                     }
  724.             }
  725.             mvwprintw(game, i, 27 + 21, "|");
  726.         }
  727.     wrefresh(game);
  728. }
  729.  
  730. int player_turn(WINDOW *game, struct nava ship[], int *nave_cmp,
  731.                 struct matrix1010 *computer, struct matrix1010 *comp_ppov,
  732.                 int *highlight_i, int *highlight_j)
  733. {
  734.     int choice = 0;
  735.     int hl_i = *highlight_i;
  736.     int hl_j = *highlight_j;
  737.     while(true)
  738.     {
  739.         print_computer_map(game, *comp_ppov, hl_i, hl_j);
  740.         choice = wgetch(game);
  741.         switch(choice)
  742.         {
  743.             case KEY_UP:
  744.                 --hl_i;
  745.                 if(hl_i == -1)
  746.                     hl_i = 0;
  747.                 break;
  748.             case KEY_RIGHT:
  749.                 ++hl_j;
  750.                 if(hl_j == 10)
  751.                     hl_j = 9;
  752.                 break;
  753.             case KEY_DOWN:
  754.                 ++hl_i;
  755.                 if(hl_i == 10)
  756.                     hl_i = 9;
  757.                 break;
  758.             case KEY_LEFT:
  759.                 --hl_j;
  760.                 if(hl_j == -1)
  761.                     hl_j = 0;
  762.                 break;
  763.             case 'q':
  764.                 return -1;
  765.             case 'Q':
  766.                 return -1;
  767.             default:
  768.                 break;
  769.         }
  770.         if(choice == 10)//ENTER
  771.             break;
  772.     }
  773.     *highlight_i = hl_i;
  774.     *highlight_j = hl_j;
  775.     int value = (*computer).m[hl_i][hl_j];
  776.     if(value > 0)
  777.     {
  778.         //zona intacta
  779.         //TODO: animatie lovit
  780.         //TODO: modify status
  781.         --ship[value-1].intacte;
  782.         if(!ship[value-1].intacte)
  783.             if(!(--(*nave_cmp)))
  784.                 return 2;
  785.         (*computer).m[hl_i][hl_j] = -2;
  786.         (*comp_ppov).m[hl_i][hl_j] = -2;
  787.         return 1;
  788.     }
  789.     if(value == 0 || value == -1)
  790.     {
  791.         //zona apa
  792.         (*comp_ppov).m[hl_i][hl_j] = -3;
  793.     }
  794.     //cazul in care jucatorul alege o zona cu o barca lovita
  795.     //nu este tratat pentru ca nu se intampla absolut nimic
  796.     return 0;
  797. }
  798.  
  799. int computer_turn(struct nava ship[], int *nave_pl, struct matrix1010 *player)
  800. {
  801.     int ri, rj, value;
  802.     do
  803.     {
  804.         ri = rand() % 10;
  805.         rj = rand() % 10;
  806.     }while((*player).m[ri][rj] <= -2); //verificare zona lovit/incercat
  807.     value = (*player).m[ri][rj];
  808.     //TODO: modify status
  809.     //sleep(3);
  810.     if(value > 0)
  811.     {
  812.         --ship[value-1].intacte;
  813.         if(!ship[value-1].intacte)
  814.             if(!(--(*nave_pl)))
  815.                 return 2;
  816.         (*player).m[ri][rj] = -2;
  817.         return 1;
  818.     }
  819.     if(value == 0)
  820.         (*player).m[ri][rj] = -3;
  821.     return 0;
  822. }
  823.  
  824. void player_win(struct nava ship[])
  825. {
  826.     WINDOW *game = start_win(height_g, width_g, start_y_g, start_x_g,
  827.                              '|', '~', '+');
  828.     keypad(game, true);
  829.     mvwprintw(game, 0, 20, "Battleship");
  830.     int i, nave_distruse = 0;
  831.     for(i = 0; i < 10; ++i)
  832.         if(ship[i].intacte == 0)
  833.             ++nave_distruse;
  834.     mvwprintw(game, 1, 1, "Ai castigat! :) Ti-au fost distruse %d nave",
  835.                 nave_distruse);
  836.     mvwprintw(game, 2, 1, "Apasa Q pentru a reveni la meniu");
  837.     while(true)
  838.     {
  839.         int key = wgetch(game);
  840.         if(key == 'q' || key == 'Q')
  841.             return;
  842.     }
  843. }
  844.  
  845. void computer_win(struct nava ship[])
  846. {
  847.     WINDOW *game = start_win(height_g, width_g, start_y_g, start_x_g,
  848.                              '|', '~', '+');
  849.     keypad(game, true);
  850.     mvwprintw(game, 0, 20, "Battleship");
  851.     int i, nave_distruse = 0;
  852.     for(i = 0; i < 10; ++i)
  853.         if(ship[i].intacte == 0)
  854.             ++nave_distruse;
  855.     mvwprintw(game, 1, 1, "Ai pierdut! :( Ai distrus %d nave",
  856.                 nave_distruse);
  857.     mvwprintw(game, 2, 1, "Apasa Q pentru a reveni la meniu");
  858.     while(true)
  859.     {
  860.         int key = wgetch(game);
  861.         if(key == 'q' || key == 'Q')
  862.             return;
  863.     }
  864. }
  865.  
  866. void game(FILE *logs, FILE *scores,
  867.             struct nava ship[2][10], int *nave_pl, int *nave_cmp,
  868.             struct matrix1010 *player, struct matrix1010 *computer,
  869.             struct matrix1010 *comp_ppov)
  870. {
  871.     WINDOW *game = start_win(height_g, width_g, start_y_g, start_x_g,
  872.                              '|', '~', '+');
  873.     keypad(game, true);
  874.     mvwprintw(game, 0, 20, "Battleship");
  875.     mvwprintw(game, 1, 8, "Alege unde ataci folosind sagetile");
  876.     mvwprintw(game, 2, 1, "================================================");
  877.     int hl_i = 0, hl_j = 0;
  878.     bool turn = 1; //1 - player | 0 - computer
  879.     int resume = 0;
  880.     while(true)
  881.     {
  882.         print_player_map(game, *player);
  883.         if(turn)
  884.         {
  885.             int value = player_turn(game, ship[1], nave_cmp,
  886.                                     computer, comp_ppov,
  887.                                     &hl_i, &hl_j);
  888.             if (value == 2)//jucatorul a castigat
  889.             {
  890.                 player_win(ship[0]);
  891.                 write_scores(scores, 1, 10 - *nave_pl);
  892.                 clrwin(game);
  893.                 break;
  894.             }
  895.             if(value == 1)//jucatorul a lovit o barca
  896.                 continue;
  897.             else if(value == 0)//jucatorul nu a lovit
  898.                 turn = 0;
  899.             else //jucatorul doreste a se reintoarce in meniu
  900.             {
  901.                 resume = 1;
  902.                 break;
  903.             }
  904.         }
  905.         if(!turn)
  906.         {
  907.             int value = computer_turn(ship[0], nave_pl, player);
  908.             if(value == 0)
  909.                 turn = 1;
  910.             else if(value == 2)
  911.             {
  912.                 computer_win(ship[1]);
  913.                 write_scores(scores, 0, 10 - *nave_cmp);
  914.                 clrwin(game);
  915.                 break;
  916.             }
  917.         }
  918.     }
  919.     write_logs(logs, resume, ship, *nave_pl, *nave_cmp,
  920.                 *player, *computer, *comp_ppov);
  921.     //scriem in logs date pentru a putea continua in caz ca cineva
  922.     //  doreste sa continue jocul mai tarziu prin functia resume
  923.     //  game din meniu.
  924. }
  925.  
  926. int main(int argc, char *argv[])
  927. {
  928.     //verificare daca exista argumente
  929.     if(argc == 1)
  930.     {  
  931.         fprintf(stderr, "[Eroare]: Nu s-au dat argumente de comanda.\n");
  932.         return 1;
  933.     }
  934.  
  935.     //verificare daca toate fisierele date ca argumente s-au deschis
  936.     FILE **fin = (FILE**)malloc(argc);
  937.  
  938.     struct matrix1010 *map = malloc(argc * sizeof(struct matrix1010));
  939.     struct matrix1010 comp_ppov, cmap;
  940.                 struct matrix1010 pmap;
  941.     //comp_ppov = tabla computerului, asa cum o vede jucatorul
  942.     //cmap = tabla computerului, in realitate
  943.     struct nava ship[2][10];//prima linie este pentru player
  944.                             //cealalta este pentru computer
  945.     int map_index;
  946.     int resume = 0;
  947.  
  948.     //initializare fisiere aditionale
  949.     FILE *logs, *scores;
  950.     logs = fopen("logs", "r");
  951.     scores = fopen("scores", "r");
  952.     if(open_files(argc-1, fin, argv, map))
  953.         return 1;
  954.  
  955.     //initializare module pentru ncurses
  956.     start_ncurses();
  957.  
  958.     //citirea fisierului logs
  959.     fscanf(logs, "%d\n", &resume);
  960.     int nave_pl, nave_cmp;
  961.     while(true)
  962.     {
  963.  
  964.         refresh();
  965.         int choice = menu(resume);
  966.         switch(choice)
  967.         {
  968.             case 0://Quit
  969.                 close_files(logs, scores, argc - 1, fin);
  970.                 endwin();
  971.                 //free(map);
  972.                 return 0;
  973.             case 1://New Game
  974.                 if(open_files(argc-1, fin, argv, map))
  975.                     return 1;
  976.                 map_index = choose_map(fin, argc - 1, map);
  977.                 if(map_index < 0)
  978.                     break;
  979.                 visual_to_value(&map[map_index], ship[0]);
  980.                 //initializarea matricei si navelor jucatorului pentru a putea
  981.                 //  fi folosite in program
  982.                 nave_pl = nave_cmp = 10;
  983.                 //numarul de nave ale jucatorului, respectiv ale computerului
  984.                 init_ships(ship[1]);
  985.                 //initializare standard pentru navele computerului
  986.                 cmap = random_map(ship[1]);
  987.                 init_matrix(&comp_ppov);
  988.                 //harta computerului este generata aleator
  989.                 game(logs, scores, ship, &nave_pl, &nave_cmp, &map[map_index],
  990.                             &cmap, &comp_ppov);
  991.                 close_files(logs, scores, argc - 1, fin);
  992.                 break;
  993.             case 2://Resume Game
  994.                 read_logs(logs, ship, &nave_pl, &nave_cmp,
  995.                             &pmap, &cmap, &comp_ppov);
  996.                 game(logs, scores, ship, &nave_pl, &nave_cmp, &pmap,
  997.                             &cmap, &comp_ppov);
  998.                 close_files(logs, scores, argc - 1, fin);
  999.                 break;
  1000.             case 3://Score
  1001.                 read_scores(scores);
  1002.                 break;
  1003.         }
  1004.     }
  1005. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement