Advertisement
Luz_Azevedo

2048.4 - sem falhas :)

Jul 12th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.49 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\t16\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] == 16)
  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. do
  293. {
  294. tab = checaMaiorMenor(tab);
  295.  
  296. //gera um 2 ou um 4 para colocar no tabuleiro
  297. novoNum = rand() % 2 + 1;
  298. novoNum *= 2;
  299.  
  300. //procura uma posição nula aleatória para armazenar o novo numero gerado
  301. if (tab.menorNum[0] == 0)
  302. {
  303. do
  304. {
  305. posicao.linha = rand() % TAM;
  306. posicao.coluna = rand() % TAM;
  307. }
  308. while(tab.mat[posicao.linha][posicao.coluna]);
  309. }
  310. tab.mat[posicao.linha][posicao.coluna] = novoNum;
  311.  
  312.  
  313. printf("\n\n");
  314. system("cls");
  315. imprimeTabuleiro(tab.mat);
  316.  
  317. controle = tab;
  318. do
  319. {
  320. scanf("%c%*c", &direcao);
  321. while(direcao != 'w' && direcao != 'a' && direcao != 's' && direcao != 'd' && direcao != 'W' && direcao != 'A' && direcao != 'S' && direcao != 'D')
  322. {
  323. scanf("%c%*c", &direcao);
  324. }
  325. tab = atualizaTabuleiro(tab, direcao);
  326.  
  327. //rotaciona controle1 para verificar se existe algum movimento possivel
  328. controle1 = tab;
  329. controle1 = atualizaTabuleiro(controle1, 'w');
  330. controle1 = atualizaTabuleiro(controle1, 'a');
  331. controle1 = atualizaTabuleiro(controle1, 's');
  332. controle1 = atualizaTabuleiro(controle1, 'd');
  333.  
  334. }
  335. //faz tudo isso enquanto há movimentos possíveis e a movimentação não mudar o tabuleiro
  336. //(ex.: a pessoa aperta w 500x mesmo não existindo mais nenhum movimento apertando a tecla w)
  337. while(matrizesIguais(tab.mat, controle.mat) && !(matrizesIguais(tab.mat, controle1.mat)));
  338.  
  339.  
  340. //imprime o novo tabuleiro rotacionado
  341. system("cls");
  342. imprimeTabuleiro(tab.mat);
  343. tab = checaMaiorMenor(tab);
  344. }
  345. //verifica se a pessoa terminou o jogo ou se não há mais movimentos possíveis
  346. while(!acabouJogo(tab.mat));
  347. system("cls");
  348. return tab;
  349. }
  350.  
  351.  
  352.  
  353. void salvaRank(Player player[], double tempo_de_cpu)
  354. {
  355. FILE *ranking;
  356. int i, j, numJogadores, aux;
  357.  
  358. for(numJogadores = 0; player[numJogadores].tempo != -1 ; numJogadores++);// conta o numero de nomes que ja foram salvos
  359.  
  360. //caso o numero de jogadores no rank ja seja maximo e o tempo da pessoa foi maior que o ultimo colocado
  361. if(numJogadores == 5 && tempo_de_cpu > player[5].tempo)
  362. return;
  363.  
  364. //adiciona o player na sua posição no board já ordenado
  365. aux = 1;
  366. for(i = 0; i < numJogadores; i++)
  367. {
  368. if(tempo_de_cpu < player[i].tempo)
  369. for(j = numJogadores; j > i; j--)
  370. {
  371. if(j < 5)
  372. player[j] = player[j - 1];
  373.  
  374. printf("\n\n\tDigite 3 letras: a");
  375. fgets(player[i].nome, 4, stdin);
  376. removeEnter(player[i].nome);
  377. player[i].tempo = tempo_de_cpu;
  378. aux = 0;
  379. numJogadores++;
  380. break;
  381. }
  382. if (aux == 0)
  383. break;
  384. }
  385.  
  386. //caso o nome da pessoa não tenha sido adicionado, coloca-o em ultimo
  387. if(aux)
  388. {
  389. printf("\n\n\tDigite 3 letras: b");
  390. fgets(player[i].nome, 4, stdin);
  391. removeEnter(player[i].nome);
  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 16\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(" %.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;
  447. FILE *ranking;
  448. ranking = fopen("Ranking.txt", "a");
  449.  
  450. //preenche o tempo de todos os players com -1 para contagem do numero de players futuramente
  451. for(i = 0; i < 5 ; i++)
  452. player[i].tempo = -1;
  453.  
  454.  
  455. //coloca um EOF no final para comparações futuras
  456. if(ranking == NULL)
  457. {
  458. system("cls");
  459. printf("Erro");
  460. system("pause");
  461. exit(-1);
  462. }
  463. fprintf(ranking, "\n%c", EOF);
  464. fclose(ranking);
  465.  
  466. ranking = fopen("Ranking.txt", "r");
  467. if(ranking == NULL)
  468. {
  469. system("cls");
  470. printf("Erro");
  471. system("pause");
  472. exit(-1);
  473. }
  474.  
  475. for (i = 0; i < 5 && (int)ranking != EOF; i++)
  476. {
  477. fgets(player[i].nome, 5, ranking);
  478. removeEnter(player[i].nome);
  479. fscanf(ranking, "%lf%*c", &player[i].tempo);
  480. }
  481. fclose(ranking);
  482. }
  483.  
  484. int main(int argc, char** argv)
  485. {
  486. Tabuleiro tab;
  487. clock_t inicio, fim;
  488. double tempo_de_cpu;
  489. Player player[5];
  490.  
  491. //conta o tempo de jogo
  492. inicio = clock();
  493.  
  494. tab = jogo();
  495.  
  496. fim = clock();
  497. tempo_de_cpu = ((double)(fim - inicio)) / CLOCKS_PER_SEC;
  498.  
  499.  
  500. //chama as funções de exibição de fim de jogo
  501. if(tab.maiorNum[0] == 16)
  502. {
  503. rank(player);
  504. salvaRank(player, tempo_de_cpu);
  505. imprimeRank(player);
  506. }
  507. else
  508. {
  509. rank(player);
  510. imprimeRank(player);
  511. }
  512.  
  513. return 0;
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement