Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define TAM 4
- int tab[TAM][TAM], pontuacao, movimento_preso;
- int selecionar_movimento();
- void iniciar_pesos();
- void resetar_tabuleiro()
- {
- pontuacao = 0;
- int i, j;
- for(i = 0; i < TAM; i++)
- {
- for(j = 0; j < TAM; j++)
- {
- tab[i][j] = 0;
- }
- }
- }
- int existem_casas_vazias()
- {
- int existe = 0;
- int i, j;
- for(i = 0; i < TAM && !existe; i++)
- {
- for(j = 0; j < TAM && !existe; j++)
- {
- if(!tab[i][j])
- {
- existe = 1;
- }
- else
- {
- if(i > 0 && tab[i - 1][j] == tab[i][j])
- existe = 1;
- if(j > 0 && tab[i][j - 1] == tab[i][j])
- existe = 1;
- if(j < (TAM -1) && tab[i][j + 1] == tab[i][j])
- existe = 1;
- if(i < (TAM - 1) && tab[i + 1][j] == tab[i][j])
- existe = 1;
- }
- }
- }
- return existe;
- }
- void gerar_casa()
- {
- int gerouCasa = 0;
- do
- {
- int randomX = rand() % TAM;
- int randomY = rand() % TAM;
- if(tab[randomX][randomY] == 0)
- {
- tab[randomX][randomY] = 2;
- gerouCasa = 1;
- }
- }
- while(gerouCasa == 0);
- }
- void imprimir_tabuleiro()
- {
- printf("\nPontuacao: %17d\n\n", pontuacao);
- int i, j;
- for(i = 0; i < TAM; i++)
- {
- for(j = 0; j < TAM; j++)
- {
- printf("[%4d]", tab[i][j]);
- }
- printf("\n");
- }
- }
- void fundir_casas(int comando)
- {
- switch (comando)
- {
- case 0: //Ir para baixo
- {
- int j;
- for(j = 0; j < TAM; j++)
- {
- int linha_pivot = TAM - 1;
- while(linha_pivot > 0)
- {
- int pivot = tab[linha_pivot][j];
- if(pivot == 0)
- {
- linha_pivot--;
- }
- else
- {
- int i;
- for(i = linha_pivot - 1; i >= 0; i--)
- {
- if(tab[i][j] != 0 && tab[linha_pivot][j] != tab[i][j])
- {
- break;
- }
- else if(tab[linha_pivot][j] == tab[i][j])
- {
- pontuacao += tab[linha_pivot][j] + tab[i][j];
- tab[linha_pivot][j] += tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- linha_pivot--;
- }
- }
- }
- break;
- }
- case 1: //Ir para cima
- {
- int j;
- for(j = 0; j < TAM; j++)
- {
- int linha_pivot = 0;
- while(linha_pivot < TAM - 1)
- {
- int pivot = tab[linha_pivot][j];
- if(pivot == 0)
- {
- linha_pivot++;
- }
- else
- {
- int i;
- for(i = linha_pivot + 1; i <= TAM - 1; i++)
- {
- if(tab[i][j] != 0 && tab[linha_pivot][j] != tab[i][j])
- {
- break;
- }
- else if(tab[linha_pivot][j] == tab[i][j])
- {
- pontuacao += tab[linha_pivot][j] + tab[i][j];
- tab[linha_pivot][j] += tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- linha_pivot++;
- }
- }
- }
- break;
- }
- case 2: //Ir para esquerda
- {
- int i;
- for(i = 0; i < TAM; i++)
- {
- int coluna_pivot = 0;
- while(coluna_pivot < TAM - 1)
- {
- int pivot = tab[i][coluna_pivot];
- if(pivot == 0)
- {
- coluna_pivot++;
- }
- else
- {
- int j;
- for(j = coluna_pivot + 1; j <= TAM - 1; j++)
- {
- if(tab[i][j] != 0 && tab[i][coluna_pivot] != tab[i][j])
- {
- break;
- }
- else if(tab[i][coluna_pivot] == tab[i][j])
- {
- pontuacao += tab[i][coluna_pivot] + tab[i][j];
- tab[i][coluna_pivot] += tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- coluna_pivot++;
- }
- }
- }
- break;
- }
- case 3: //Ir para direita
- {
- int i;
- for(i = 0; i < TAM; i++)
- {
- int coluna_pivot = TAM - 1;
- while(coluna_pivot > 0)
- {
- int pivot = tab[i][coluna_pivot];
- if(pivot == 0)
- {
- coluna_pivot--;
- }
- else
- {
- int j;
- for(j = coluna_pivot - 1; j >= 0; j--)
- {
- if(tab[i][j] != 0 && tab[i][coluna_pivot] != tab[i][j])
- {
- break;
- }
- else if(tab[i][coluna_pivot] == tab[i][j])
- {
- pontuacao += tab[i][coluna_pivot] + tab[i][j];
- tab[i][coluna_pivot] += tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- coluna_pivot--;
- }
- }
- }
- break;
- }
- }
- }
- void aplicar_gravidade(int comando)
- {
- switch(comando)
- {
- case 0: //Ir para baixo
- {
- int j;
- for(j = 0; j < TAM; j++)
- {
- int linha_pivot = TAM - 1;
- while(linha_pivot > 0)
- {
- int pivot = tab[linha_pivot][j];
- if(pivot != 0)
- {
- linha_pivot--;
- }
- else
- {
- int i;
- for(i = linha_pivot - 1; i >= 0; i--)
- {
- if(tab[i][j] != 0)
- {
- tab[linha_pivot][j] = tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- linha_pivot--;
- }
- }
- }
- break;
- }
- case 1: //Ir para cima
- {
- int j;
- for(j = 0; j < TAM; j++)
- {
- int linha_pivot = 0;
- while(linha_pivot < TAM - 1)
- {
- int pivot = tab[linha_pivot][j];
- if(pivot != 0)
- {
- linha_pivot++;
- }
- else
- {
- int i;
- for(i = linha_pivot + 1; i <= TAM - 1; i++)
- {
- if(tab[i][j] != 0)
- {
- tab[linha_pivot][j] = tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- linha_pivot++;
- }
- }
- }
- break;
- }
- case 2: //Ir para esquerda
- {
- int i;
- for(i = 0; i < TAM; i++)
- {
- int coluna_pivot = 0;
- while(coluna_pivot < TAM - 1)
- {
- int pivot = tab[i][coluna_pivot];
- if(pivot != 0)
- {
- coluna_pivot++;
- }
- else
- {
- int j;
- for(j = coluna_pivot + 1; j <= TAM - 1; j++)
- {
- if(tab[i][j] != 0)
- {
- tab[i][coluna_pivot] = tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- coluna_pivot++;
- }
- }
- }
- break;
- }
- case 3: //Ir para direita
- {
- int i;
- for(i = 0; i < TAM; i++)
- {
- int coluna_pivot = TAM - 1;
- while(coluna_pivot > 0)
- {
- int pivot = tab[i][coluna_pivot];
- if(pivot != 0)
- {
- coluna_pivot--;
- }
- else
- {
- int j;
- for(j = coluna_pivot - 1; j >= 0; j--)
- {
- if(tab[i][j] != 0)
- {
- tab[i][coluna_pivot] = tab[i][j];
- tab[i][j] = 0;
- movimento_preso = 0;
- break;
- }
- }
- coluna_pivot--;
- }
- }
- }
- break;
- }
- }
- }
- void aplicar(int comando)
- {
- fundir_casas(comando);
- aplicar_gravidade(comando);
- }
- int main()
- {
- srand(time(NULL));
- iniciar_pesos();
- resetar_tabuleiro();
- gerar_casa();
- movimento_preso = 0;
- while(existem_casas_vazias())
- {
- if(!movimento_preso)
- {
- gerar_casa();
- }
- movimento_preso = 1;
- imprimir_tabuleiro();
- int comando = -1;
- do
- {
- comando = selecionar_movimento();
- printf("\nComando: %d", comando);
- //scanf("%d", &comando);
- } while(comando < 0 || comando > 3);
- aplicar(comando);
- }
- printf("\n\nGameover! Sua pontuacao final foi: %d", pontuacao);
- // desafio: gere uma sequencia de movimentos (IA)
- // simulando-a com o seu programa
- // envie para tpshc2@cin.ufpe.br o seu programa.
- // se ela atingir 1024 em uma execucao,
- // do monitor, voce ganha bonus (se tiver
- // a maior pontuacao dentre os que enviaram).
- // ATENCAO: se a regra do jogo nao estiver implementada
- // corretamente, perde 1 ponto na prova.
- system("pause");
- return 0;
- }
- // AI***AI***AI***AI***AI***AI***AI***AI***AI***AI***AI***AI***AI***AI***AI
- #define PROFUNDIDADE 50
- //int node_percentual(int arr[TAM][TAM], int cmd, int profundidade);
- //int node_max(int arr[TAM][TAM], int profundidade, int i2, int j2);
- double non_terminal_score(int arr[TAM][TAM], int cmd, int profundidade);
- double terminal_score(int arr[TAM][TAM]);
- //esse comando irá verificar se um comando {0, 1, 2, 3} pode ser executado em
- //uma dada matriz que representa um tabuleira
- int comando_valido(int arr[TAM][TAM])
- {
- //printf("iniciando comando_valido\n");
- int i, j, resposta = 0;
- for(i = 0; i < TAM; i++)
- for(j = 0; j < TAM; j++)
- {
- if(i < (TAM - 1) && arr[i][j] && (arr[i][j] == arr[i + 1][j] || !arr[i + 1][j]))
- resposta |= 1 << 0;
- if(i > 0 && arr[i][j] && (arr[i][j] == arr[i - 1][j] || !arr[i - 1][j]))
- resposta |= 1 << 1;
- if(j > 0 && arr[i][j] && (arr[i][j] == arr[i][j - 1] || !arr[i][j - 1]))
- resposta |= 1 << 2;
- if(j < (TAM - 1) && arr[i][j] && (arr[i][j] == arr[i][j + 1] || !arr[i][j + 1]))
- resposta |= 1 << 3;
- }
- //printf("encerrando comando_valido\n");
- return resposta;
- }
- int selecionar_movimento()
- {
- int maior = -1, validos = comando_valido(tab);
- double maior_valor = 0;
- double temp;
- if(validos)
- {
- int i;
- for(i = 0; i < 4; i++)
- {
- if(validos & (1 << i))
- {
- temp = non_terminal_score(tab, i, PROFUNDIDADE);
- if(maior == -1 || maior_valor < temp)
- {
- maior = i;
- maior_valor = temp;
- }
- }
- }
- }
- else
- {
- return 0;
- }
- return maior;
- }
- double non_terminal_score(int arr[TAM][TAM], int cmd, int profundidade)
- {
- printf("%d\n", profundidade);
- if(!profundidade)
- return terminal_score(arr);
- int array[TAM][TAM], i, j;
- double score = 0;
- switch(cmd)
- {
- case 0:
- {
- int last_added, ja_unido = 0;
- for(j = 0; j < TAM; j++)
- {
- last_added = -1;
- for(i = TAM - 1; i >= 0; i--)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == array[last_added][j] && !ja_unido)
- {
- array[last_added][j] = 2*arr[i][j];
- //score += array[last_added][j];
- ja_unido = 1;
- }
- else
- {
- last_added += 1;
- array[last_added][j] = arr[i][j];
- ja_unido = 0;
- }
- }
- }
- }
- break;
- }
- case 1:
- {
- int last_added, ja_unido = 0;
- for(j = 0; j < TAM; j++)
- {
- last_added = -1;
- for(i = 0; i < TAM; i++)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == array[last_added][j] && !ja_unido)
- {
- array[last_added][j] = 2*arr[i][j];
- //score += array[last_added][j];
- ja_unido = 1;
- } else
- {
- last_added += 1;
- array[last_added][j] = arr[i][j];
- ja_unido = 0;
- }
- }
- }
- }
- break;
- }
- case 2:
- {
- int last_added, ja_unido = 0;
- for(i = 0; i < TAM; i++)
- {
- last_added = -1;
- for(j = 0; j < TAM; j++)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == array[i][last_added] && !ja_unido)
- {
- array[i][last_added] = 2*arr[i][j];
- //score += array[i][last_added];
- ja_unido = 1;
- } else
- {
- last_added += 1;
- array[i][last_added] = arr[i][j];
- ja_unido = 0;
- }
- }
- }
- }
- break;
- }
- case 3:
- {
- int last_added, ja_unido = 0;
- for(i = 0; i < TAM; i++)
- {
- last_added = -1;
- for(j = TAM - 1; j >= 0; j--)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == array[i][last_added] && !ja_unido)
- {
- array[i][last_added] = 2*arr[i][j];
- //score += array[i][last_added];
- ja_unido = 1;
- } else
- {
- last_added += 1;
- array[i][last_added] = arr[i][j];
- ja_unido = 0;
- }
- }
- }
- }
- break;
- }
- }
- int k, validos, qtd_score = 0, sum_score = 0;
- for(i = 0; i < TAM; i++)
- {
- for(j = 0; j < TAM; j++)
- {
- if(!array[i][j])
- {
- printf("Entrou, segunda parte do non terminal\n");
- array[i][j] = 2;
- validos = comando_valido(array);
- if(validos)
- {
- int maior_valor_score, maior_score = -1, temp_score;
- for(k = 0; k < 4; k++) if(validos & (1 << k))
- {
- temp_score = non_terminal_score(array, k, profundidade - 1);
- if(maior_score == -1 || temp_score > maior_valor_score){
- maior_valor_score = temp_score;
- maior_score = k;
- }
- }
- sum_score += maior_valor_score;
- }
- else
- {
- sum_score += terminal_score(array);
- }
- array[i][j] = 0;
- qtd_score += 1;
- }
- }
- }
- if(qtd_score) score += sum_score/qtd_score;
- return score;
- }
- double weight[8][TAM][TAM];
- void iniciar_pesos(){
- weight[0][0][0] = 0.135759; weight[0][0][1] = 0.121925; weight[0][0][2] = 0.102812; weight[0][0][3] = 0.099937;
- weight[0][1][0] = 0.0997992; weight[0][1][1] = 0.0888405; weight[0][1][2] = 0.076711; weight[0][1][2] = 0.0724143;
- weight[0][2][0] = 0.060654; weight[0][2][1] = 0.0562579; weight[0][2][2] = 0.037116; weight[0][2][3] = 0.0161889;
- weight[0][3][0] = 0.0125498; weight[0][3][1] = 0.00992495; weight[0][3][2] = 0.00575871; weight[0][3][3] = 0.00335193;
- /*
- weight[0][0][0] = 7; weight[0][0][1] = 6; weight[0][0][2] = 5; weight[0][0][3] = 4;
- weight[0][1][0] = 6; weight[0][1][1] = 5; weight[0][1][2] = 4; weight[0][1][2] = 3;
- weight[0][2][0] = 5; weight[0][2][1] = 4; weight[0][2][2] = 3; weight[0][2][3] = 2;
- weight[0][3][0] = 4; weight[0][3][1] = 3; weight[0][3][2] = 2; weight[0][3][3] = 1;
- */
- int i, j, k, l;
- for(i = 0; i < TAM; i++)
- for(j = 0; j < TAM; j++)
- weight[4][i][TAM - j - 1] = weight[0][i][j];
- for(i = 0; i < 2; i++)
- {
- for(j = 1; j < 4; j++)
- {
- for(k = 0; k < TAM; k++)
- for(l = 0; l < TAM; l++)
- {
- weight[i*4 + j][l][TAM - (k + 1)] = weight[i*4 + j - 1][k][l];
- }
- }
- }
- }
- double terminal_score(int arr[TAM][TAM])
- {
- printf("Entrou\n");
- int i, j, k;
- double maior = -1, atual;
- for(k = 0; k < 8; k++)
- {
- atual = 0;
- for(i = 0; i < TAM; i++)
- for(j = 0; j < TAM; j++)
- {
- atual += weight[k][i][j]*arr[i][j];
- }
- if(maior == -1 || atual > maior) maior = atual;
- }
- return maior;
- }
- /*
- //esse comando representa a primeira MAX node do expectmax algorithm
- //ela irá transformar o valor maior do passo em um comando válido
- int selecionar_movimento()
- {
- //printf("iniciando selecionar_movimento\n");
- int maior = -1, maior_valor = 0,i;
- int validos = comando_valido(tab);
- for(i = 0; i < 4; i++)
- {
- if(validos & (1 << i))
- {
- int temp = node_percentual(tab, i, PROFUNDIDADE);
- if(maior == -1 || maior_valor < temp)
- maior = i;
- maior_valor = temp;
- }
- }
- if(maior == -1)
- maior = 0;
- //printf("encerrando selecionar_movimento\n");
- return maior;
- }
- //esse comando representa todas as nodes percentuais da arvore
- int node_percentual(int arr[TAM][TAM], int cmd, int profundidade)
- {
- //printf("iniciando node_percentual\n");
- int array[TAM][TAM], resposta = 0, i, j;
- for(i = 0; i < TAM; i++)
- memset(array[i], 0, TAM);
- //printf("%d\n", cmd);
- switch(cmd)
- {
- case 0:
- {
- //printf("1\n");
- int last_added;
- for(j = 0; j < TAM; j++)
- {
- last_added = -1;
- for(i = TAM - 1; i >= 0; i--)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == arr[last_added][j])
- {
- array[last_added][j] *= 2;
- resposta += array[last_added][j];
- last_added += 1;
- } else
- {
- last_added += 1;
- array[last_added][j] = arr[i][j];
- }
- }
- }
- }
- break;
- }
- case 1:
- {
- //printf("1\n");
- int last_added;
- for(j = 0; j < TAM; j++)
- {
- last_added = -1;
- for(i = 0; i < TAM; i++)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == arr[last_added][j])
- {
- array[last_added][j] *= 2;
- resposta += array[last_added][j];
- last_added += 1;
- } else
- {
- last_added += 1;
- array[last_added][j] = arr[i][j];
- }
- }
- }
- }
- break;
- }
- case 2:
- {
- //printf("1\n");
- int last_added;
- for(i = 0; i < TAM; i++)
- {
- last_added = -1;
- for(j = 0; j < TAM; j++)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == arr[i][last_added])
- {
- array[i][last_added] *= 2;
- resposta += array[i][last_added];
- last_added += 1;
- } else
- {
- last_added += 1;
- array[i][last_added] = arr[i][j];
- }
- }
- }
- }
- break;
- }
- case 3:
- {
- //printf("1\n");
- int last_added;
- for(i = 0; i < TAM; i++)
- {
- last_added = -1;
- for(j = TAM; j >= 0; j--)
- {
- if(arr[i][j])
- {
- if(last_added != -1 && arr[i][j] == arr[i][last_added])
- {
- array[i][last_added] *= 2;
- resposta += array[i][last_added];
- last_added += 1;
- } else
- {
- last_added += 1;
- array[i][last_added] = arr[i][j];
- }
- }
- }
- }
- break;
- }
- }
- //printf("1\n");
- int temp = 0, qtd = 0;
- for(i = 0; i < TAM; i++)
- {
- for(j = 0; j < TAM; j++)
- {
- if(!array[i][j])
- {
- temp += node_max(array, profundidade - 1, i, j);
- qtd += 1;
- }
- }
- }
- if(qtd) resposta += (int)(temp / qtd);
- //printf("encerrando node_percentual\n");
- return resposta;
- }
- int node_max(int arr[TAM][TAM], int profundidade, int i2, int j2)
- {
- //printf("iniciando node_max\n");
- if(!profundidade)
- return 0;
- int i, j, array[TAM][TAM];
- for(i = 0; i < TAM; i++)
- for(j = 0; j < TAM; j++)
- array[i][j] = arr[i][j];
- array[i2][j2] = 2;
- int maior = -1, maior_valor;
- int validos = comando_valido(array);
- if(validos == 0)
- return -5000000;
- for(i = 0; i < 4; i++)
- {
- if(validos & (1 << i))
- {
- int temp = node_percentual(array, i, profundidade);
- if(maior == -1 || maior_valor < temp)
- maior = i;
- maior_valor = temp;
- }
- }
- //printf("encerrando node_max\n");
- return maior;
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement