Advertisement
Luz_Azevedo

2048.3 -quase certo

Jul 11th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. #define TAM 4
  6.  
  7. typedef struct
  8. {
  9.     int linha, coluna;
  10. } Posicao;
  11.  
  12. typedef struct
  13. {
  14.     int mat[TAM][TAM];
  15.     int maiorNum[1];
  16.     int menorNum[1];
  17. } Tabuleiro;
  18.  
  19. typedef struct
  20. {
  21.     char nome[3];
  22.     double tempo;
  23. } Player;
  24.  
  25. void removeEnter(char v[])
  26. {
  27.     int i;
  28.     for(i = 0; v[i] != '\0'; i++)
  29.         if(v[i] == '\n')
  30.         {
  31.             v[i] = '\0';    // substitui o '\n' por '\0'
  32.             break;
  33.         }
  34. }
  35.  
  36. //retorta 1 caso sejam iguais, 0 caso não
  37. int matrizesIguais(int mat1[][TAM], int mat2[][TAM])
  38. {
  39.     int i, j;
  40.     for(i = 0; i < TAM; i++)
  41.         for(j = 0; j < TAM; j++)
  42.             if(mat1[i][j] != mat2[i][j])
  43.                 return 0;
  44.     return 1;
  45. }
  46.  
  47. //retorta 1 caso sejam iguais, 0 caso não
  48. int stringsIguais(char v[], char s[])
  49. {
  50.     int i;
  51.     for(i = 0; v[i] != '\0' && s[i] != '\0'; i++)
  52.         if (v[i] != s[i])
  53.             return 0;
  54.     return 1;
  55. }
  56.  
  57. Tabuleiro atualizaTabuleiro(Tabuleiro tab, char opcao)
  58. {
  59.     int i, j, k;
  60.     switch(opcao)
  61.     {
  62.     case 'w':
  63.     case 'W':
  64.         for(j = 0; j < TAM ; j++)   //lê as colunas da esquerda para a direita
  65.         {
  66.             for(i = 0; i < TAM ; i++) //lê as linhas de cima para baixo
  67.             {
  68.                 if(!tab.mat[i][j])  //caso o elemento seja nulo
  69.                 {
  70.                     for(k = i + 1; k < TAM ; k++) //percorre aquela coluna ate achar um elemento nao-nulo
  71.                         if(tab.mat[k][j])
  72.                         {
  73.                             tab.mat[i][j] = tab.mat[k][j]; //coloca o elemento nao nulo no primeiro elemento nulo daquela coluna
  74.                             tab.mat[k][j] = 0;      //o lugar do elemento nao nulo torna-se nulo
  75.                             break;
  76.                         }
  77.                 }
  78.             }
  79.             for(i = 0; i < TAM - 1; i++) // soma os numeros caso eles sejam iguais
  80.             {
  81.                 if(tab.mat[i + 1][j] == tab.mat[i][j])
  82.                 {
  83.                     tab.mat[i][j] *= 2;
  84.                     for(k = i + 1; k < TAM - 1 && tab.mat[k + 1][j] != 0; k++)
  85.                         tab.mat[k][j] = tab.mat[k + 1][j];
  86.                     tab.mat[k][j] = 0;
  87.                 }
  88.             }
  89.         }
  90.  
  91.         break;
  92.  
  93.     case 'a':
  94.     case 'A':
  95.         for(i = 0; i < TAM ; i++)// lê as linhas de cima para baixo
  96.         {
  97.             for(j = 0; j < TAM ; j++)   //lê as colunas da esquerda para a direita
  98.             {
  99.                 if(!tab.mat[i][j])    //caso o elemento seja nulo
  100.                 {
  101.                     for(k = j + 1; k < TAM ; k++) //percorre aquela linha ate achar um elemento nao-nulo
  102.                         if(tab.mat[i][k])
  103.                         {
  104.                             tab.mat[i][j] = tab.mat[i][k];  //coloca o elemento nao nulo no primeiro elemento nulo daquela linha
  105.                             tab.mat[i][k] = 0;        //o lugar do elemento nao nulo torna-se nulo
  106.                             break;
  107.                         }
  108.                 }
  109.             }
  110.             for(j = 0; j < TAM - 1; j++)
  111.             {
  112.                 if(tab.mat[i][j + 1] == tab.mat[i][j])
  113.                 {
  114.                     tab.mat[i][j] *= 2;
  115.                     for(k = j + 1; k < TAM - 1 && tab.mat[i][k + 1] != 0; k++)
  116.                         tab.mat[i][k] = tab.mat[i][k + 1];
  117.                     tab.mat[i][k] = 0;
  118.                 }
  119.             }
  120.         }
  121.  
  122.         break;
  123.  
  124.     case 's':
  125.     case 'S':
  126.         for(j = 0; j < TAM ; j++)  //lê as colunas da esquerda para a direita
  127.         {
  128.             for(i = TAM - 1; i >= 0 ; i--)  //lê as linhas da baixo para cima
  129.             {
  130.                 if(!tab.mat[i][j])    //caso o elemento seja nulo
  131.                 {
  132.                     for(k = i - 1 ; k >= 0 ; k--) //percorre aquela coluna de baixo para cima ate achar um elemento nao-nulo
  133.                         if(tab.mat[k][j])
  134.                         {
  135.                             tab.mat[i][j] = tab.mat[k][j]; //coloca o elemento nao nulo no ultimo elemento nulo daquela coluna
  136.                             tab.mat[k][j] = 0;        //o lugar do elemento nao nulo torna-se nulo
  137.                             break;
  138.                         }
  139.                 }
  140.             }
  141.             for(i = TAM - 1; i > 0 ; i--)
  142.             {
  143.                 if(tab.mat[i - 1][j] == tab.mat[i][j])
  144.                 {
  145.                     tab.mat[i][j] *= 2;
  146.                     for(k = i - 1; k > 0 && tab.mat[k - 1][j] != 0; k--)
  147.                         tab.mat[k][j] = tab.mat[k - 1][j];
  148.                     tab.mat[k][j] = 0;
  149.                 }
  150.             }
  151.         }
  152.  
  153.         break;
  154.  
  155.     case 'd':
  156.     case 'D':
  157.         for(i = 0; i < TAM ; i++)  // lê as linhas de cima para baixo
  158.         {
  159.             for(j = TAM - 1; j >= 0 ; j--)  //lê as colunas da direita para a esquerda
  160.             {
  161.                 if(!tab.mat[i][j])    //caso o elemento seja nulo
  162.                 {
  163.                     for(k = j - 1; k >= 0; k--) //percorre aquela linha da direita para a esquerda ate achar um elemento nao-nulo
  164.                         if(tab.mat[i][k])
  165.                         {
  166.                             tab.mat[i][j] = tab.mat[i][k]; //coloca o elemento nao nulo no ultimo elemento nulo daquela linha
  167.                             tab.mat[i][k] = 0;        //o lugar do elemento nao nulo torna-se nulo
  168.                             break;
  169.                         }
  170.                 }
  171.             }
  172.             for(j = TAM - 1; j > 0 ; j--)
  173.             {
  174.                 if(tab.mat[i][j - 1] == tab.mat[i][j])
  175.                 {
  176.                     tab.mat[i][j] *= 2;
  177.                     for(k = j - 1; k > 0 && tab.mat[i][k - 1] != 0; k--)
  178.                         tab.mat[i][k] = tab.mat[i][k - 1];
  179.                     tab.mat[i][k] = 0;
  180.                 }
  181.             }
  182.         }
  183.  
  184.         break;
  185.     }
  186.     return tab;
  187. }
  188.  
  189. void imprimeTabuleiro(int mat[][TAM])
  190. {
  191.     printf("\n");
  192.     printf("\t\t2048\n");
  193.     printf("\t       ======\n\n");
  194.     int i, j;
  195.     for(i = 0; i < TAM; i++)
  196.     {
  197.         printf("\t ");
  198.         for(j = 0; j < TAM; j++)
  199.             if (mat[i][j] != 0)
  200.             {
  201.                 printf("|%3d ", mat[i][j]);
  202.             }
  203.             else
  204.                 printf("|    ");
  205.         printf("|\n");
  206.     }
  207.     printf("\n\n");
  208.     printf("\t\t^\n");
  209.     printf("\t\tw\n");
  210.     printf("\t    <a     d>\n");
  211.     printf("\t\ts\n");
  212.     printf("\t\tv");
  213. }
  214.  
  215.  
  216. //percorre a matriz até achar o maior e o menor numero dela
  217. Tabuleiro checaMaiorMenor(Tabuleiro tab)
  218. {
  219.     int i, j;
  220.     tab.maiorNum[0] = 0;
  221.     tab.menorNum[0] = 0;
  222.     for(i = 0; i < TAM; i++)
  223.     {
  224.         for(j = 0; j < TAM; j++)
  225.         {
  226.             if (tab.maiorNum[0] < tab.mat[i][j])
  227.                 tab.maiorNum[0] = tab.mat[i][j];
  228.             if (tab.menorNum[0] > tab.mat[i][j])
  229.                 tab.menorNum[0] = tab.mat[i][j];
  230.         }
  231.     }
  232.     return tab;
  233. }
  234.  
  235. int acabouJogo(int mat[][TAM])
  236. {
  237.     int i, j, aux = 1;
  238.     for(i = 0; i < TAM; i++)
  239.         for(j = 0; j < TAM; j++)
  240.         {
  241.             if(mat[i][j] == 2048)
  242.                 return 1;
  243.             if(aux == 1)
  244.             {
  245.                 if(mat[i][j] == 0)
  246.                     aux = 0;
  247.                 else if(aux == 1)
  248.                 {
  249.                     if(i - 1 >= 0)
  250.                         if(mat[i - 1][j] == mat[i][j])
  251.                             aux = 0;
  252.                     if(i + 1 < TAM)
  253.                         if(mat[i + 1][j] == mat[i][j])
  254.                             aux = 0;
  255.                     if(j - 1 >= 0)
  256.                         if(mat[i][j - 1] == mat[i][j])
  257.                             aux = 0;
  258.                     if(j + 1 < TAM)
  259.                         if(mat[i][j + 1] == mat[i][j])
  260.                             aux = 0;
  261.                 }
  262.             }
  263.         }
  264.     if(aux)
  265.         return -1;
  266.     return 0;
  267. }
  268.  
  269. Tabuleiro jogo()
  270. {
  271.     Tabuleiro tab, controle, controle1; //variavel do tabuleiro e duas variaveis de controle para comparação
  272.     char direcao; //direção de rotação do tabuleiro escolhida pelo jogador
  273.  
  274.     //variaveis auxiliares
  275.     int novoNum;
  276.     int i, j;
  277.     Posicao posicao;
  278.  
  279.     srand(time(NULL));
  280.  
  281.  
  282.     //preenche o tabuleiro com 0
  283.     for(i = 0; i < TAM; i++)
  284.     {
  285.         for(j = 0; j < TAM; j++)
  286.         {
  287.             tab.mat[i][j] = 0;
  288.         }
  289.     }
  290.     controle = tab;
  291.  
  292.     /*
  293.  
  294.         Creio que o problema está nesse próximo do-while
  295.         quando o tabuleiro está cheio, ao invés de ele simplesmente sair do do-while
  296.         e dar game over ele trava e fica parado aqui mesmo
  297.  
  298.         */
  299.     do
  300.     {
  301.         tab = checaMaiorMenor(tab);
  302.  
  303.         //gera um 2 ou um 4 para colocar no tabuleiro
  304.         novoNum = rand() % 2 + 1;
  305.         novoNum *= 2;
  306.  
  307.         //procura uma posição nula aleatória para armazenar o novo numero gerado
  308.         if (tab.menorNum[0] == 0)
  309.         {
  310.             do
  311.             {
  312.                 posicao.linha = rand() % TAM;
  313.                 posicao.coluna = rand() % TAM;
  314.             }
  315.             while(tab.mat[posicao.linha][posicao.coluna]);
  316.         }
  317.         tab.mat[posicao.linha][posicao.coluna] = novoNum;
  318.  
  319.  
  320.         printf("\n\n");
  321.         system("cls");
  322.         imprimeTabuleiro(tab.mat);
  323.  
  324.         controle = tab;
  325.         do
  326.         {
  327.             scanf("%c%*c", &direcao);
  328.             while(direcao != 'w' && direcao != 'a' && direcao != 's' && direcao != 'd' && direcao != 'W' && direcao != 'A' && direcao != 'S' && direcao != 'D')
  329.             {
  330.                 scanf("%c%*c", &direcao);
  331.             }
  332.             tab = atualizaTabuleiro(tab, direcao);
  333.  
  334.             //rotaciona controle1 para verificar se existe algum movimento possivel
  335.             controle1 = tab;
  336.             controle1 = atualizaTabuleiro(controle1, 'w');
  337.             controle1 = atualizaTabuleiro(controle1, 'a');
  338.             controle1 = atualizaTabuleiro(controle1, 's');
  339.             controle1 = atualizaTabuleiro(controle1, 'd');
  340.  
  341.         }
  342.         //faz tudo isso enquanto há movimentos possíveis e a movimentação não mudar o tabuleiro
  343.         //(ex.: a pessoa aperta w 500x mesmo não existindo mais nenhum movimento apertando a tecla w)
  344.         while(matrizesIguais(tab.mat, controle.mat) && !(matrizesIguais(tab.mat, controle1.mat)));
  345.  
  346.  
  347.         //imprime o novo tabuleiro rotacionado
  348.         system("cls");
  349.         imprimeTabuleiro(tab.mat);
  350.         tab = checaMaiorMenor(tab);
  351.     }
  352.     //verifica se a pessoa terminou o jogo ou se não há mais movimentos possíveis
  353.     while(!acabouJogo(tab.mat));
  354.     system("cls");
  355.     return tab;
  356. }
  357.  
  358.  
  359.  
  360. void salvaRank(Player player[], double tempo_de_cpu)
  361. {
  362.     FILE *ranking;
  363.     int i, j, numJogadores, aux;
  364.  
  365.     for(numJogadores = 0; player[numJogadores].tempo != -1 ; numJogadores++);// conta o numero de nomes que ja foram salvos
  366.  
  367.     //caso o numero de jogadores no rank ja seja maximo e o tempo da pessoa foi maior que o ultimo colocado
  368.     if(numJogadores == 5 && tempo_de_cpu > player[5].tempo)
  369.         return;
  370.  
  371.     //adiciona o player na sua posição no board já ordenado
  372.     aux = 1;
  373.     for(i = 0; i < numJogadores; i++)
  374.         if(tempo_de_cpu < player[i].tempo)
  375.             for(j = numJogadores; j > i; j--)
  376.             {
  377.                 if(j < 5)
  378.                     player[j] = player[j - 1];
  379.  
  380.                 printf("\n\n\tDigite 3 letras: ");
  381.                 fgets(player[i].nome, 4, stdin);
  382.                 player[i].tempo = tempo_de_cpu;
  383.                 aux = 0;
  384.                 numJogadores++;
  385.                 break;
  386.             }
  387.     //caso o nome da pessoa não tenha sido adicionado, coloca-o em ultimo
  388.     if(aux)
  389.     {
  390.         printf("\n\n\tDigite 3 letras: ");
  391.         fgets(player[i].nome, 4, stdin);
  392.         player[i].tempo = tempo_de_cpu;
  393.         numJogadores++;
  394.     }
  395.  
  396.     //salva o novo board de ranking no .txt
  397.     ranking = fopen("Ranking.txt", "w");
  398.     if(ranking == NULL)
  399.     {
  400.         system("cls");
  401.         printf("Erro");
  402.         system("pause");
  403.         exit(-1);
  404.     }
  405.  
  406.  
  407.     for(i = 0; i < numJogadores && i < 5; i++)
  408.     {
  409.         fprintf(ranking, "%s\n", player[i].nome);
  410.         fprintf(ranking, "%lf\n", player[i].tempo);
  411.     }
  412. }
  413.  
  414. void imprimeRank(Player player[])
  415. {
  416.     //imprime o ranking atual
  417.     int i;
  418.     system("cls");
  419.     printf("\n\n\t\t  2048\n");
  420.     printf("\t         ======\n\n");
  421.     printf("\t      FIM DE JOGO!\n");
  422.     printf("\t     ==============\n\n");
  423.     printf("\n\t\tRANKING:\n");
  424.     printf("\t       ==========\n\n");
  425.     printf("\tLUGAR     NOME      TEMPO\n");
  426.     for(i = 0; i < 5; i++)
  427.     {
  428.         if(player[i].tempo < 0)
  429.             break;
  430.         printf("\t");
  431.         printf("   %d      %-10s   ", i + 1, player[i].nome);
  432.         printf("%-10.3lf", player[i].tempo);
  433.         printf("\n");
  434.     }
  435. }
  436.  
  437. void rank(Player player[])
  438. {
  439.     /*
  440.  
  441.     Talvez o outro erro que mencionei esteja aqui, não faço ideia tho, deem uma olhada por essas funções de ranking
  442.     a logica delas é meio estranha, entao se precisarem que eu explique, só me chamar
  443.  
  444.     */
  445.     // abre e coleta os dados no .txt
  446.     int i, aux;
  447.     FILE *ranking;
  448.     ranking = fopen("Ranking.txt", "a");
  449.  
  450.     if(ranking == NULL)
  451.     {
  452.         system("cls");
  453.         printf("Erro");
  454.         system("pause");
  455.         exit(-1);
  456.     }
  457.     fprintf(ranking, "\n%c", EOF);
  458.     fclose(ranking);
  459.     ranking = fopen("Ranking.txt", "r");
  460.     if(ranking == NULL)
  461.     {
  462.         system("cls");
  463.         printf("Erro");
  464.         system("pause");
  465.         exit(-1);
  466.     }
  467.  
  468.     for(i = 0; i < 5 ; i++)
  469.         player[i].tempo = -1;
  470.  
  471.     for (i = 0; i < 5 && (aux = fgetc(ranking)) != EOF; i++)
  472.     {
  473.         fgets(player[i].nome, 5, ranking);
  474.         fscanf(ranking, "%lf", &player[i].tempo);
  475.     }
  476. }
  477.  
  478. int main(int argc, char** argv)
  479. {
  480.     Tabuleiro tab;
  481.     clock_t inicio, fim;
  482.     double tempo_de_cpu;
  483.     Player player[5];
  484.  
  485.     //conta o tempo de jogo
  486.     inicio = clock();
  487.  
  488.     tab = jogo();
  489.  
  490.     fim  = clock();
  491.     tempo_de_cpu = ((double)(fim - inicio)) / CLOCKS_PER_SEC;
  492.  
  493.  
  494.     //chama as funções de exibição de fim de jogo
  495.     if(tab.maiorNum[0] == 2048)
  496.     {
  497.         rank(player);
  498.         salvaRank(player, tempo_de_cpu);
  499.         imprimeRank(player);
  500.     }
  501.     else
  502.         imprimeRank(player);
  503.     return 0;
  504. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement