Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef MAC
- #include <GLUT/glut.h>
- #else
- #include <GL/gl.h>
- #include <GL/glut.h>
- #endif
- /**Faz a inclusao de todas as bibliotecas necessarias a execussao do programa.*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <string.h>
- #include <ctype.h>
- /**Carrega o ficheiro def.h, tambem necessario para a execussao do programa.*/
- #include "def.h"
- char *fmapa;
- char *fregras;
- char *regra;
- char *strdelc (char *s, char ch);
- char strfstc (char *s);
- int estado_valido(char est);
- int regra_valida(char *regra);
- void display(void);
- void init(void);
- void ler_mapa(FILE *file_map);
- void ler_regra(FILE *file_rules);
- char *fmapa, *fregras;
- int getx, gety; /**Vai permitir ler os valores X e Y da matriz do mapa, para que sejam utilizados por todo o programa*/
- char *tmp_board; /**Board temporario para posteriormente ser subsituido pelo outro board*/
- char linha[100]; /**Array para armazenar uma linha do ficheiro de regras*/
- typedef struct /**Estrutura de dados correspondente aos valores das cores RGB a ser atribuídas aos vizinhos*/
- {
- float red;
- float green;
- float blue;
- } COR;
- typedef struct /**Estrutura de dados correspondente aos valores dos diferentes vizinhos*/
- {
- int R;
- int C;
- int E;
- int A;
- int F;
- int G;
- } VIZINHOS;
- typedef struct Reg { /**Estrutura de dados referente a leitura das regras*/
- char *condicao;
- char hipotese;
- struct Reg *next;
- } REGRA, *REGRAS;
- int is_vazia(REGRAS r);
- void ver_regras(REGRAS regras);
- REGRAS inserir(char *condicao, char hipotese, REGRAS regras);
- REGRAS inverter_l(REGRAS regras);
- //Função Main
- int main (int argc, char **argv)
- {
- if(argc != 4)
- { printf("\nO argumento introduzido não é permitido!\nUtilize: ./simul -[vizinhanca] [cidade] [regras]\n");
- return 0;
- }
- regra = strtok(argv[1], "-"); /**Argumento que le a tipo de vizinhanca. O strtok vai remover o caracter "-"*/
- fmapa=argv[2]; /**Argumento que le o comando referente ao mapa a ser utilizado*/
- fregras=argv[3]; /**Argumento que le o comando referente as regras a serem utlizadas*/
- if(!regra_valida(regra))
- { printf("\nRegra não permitida!\n\nRegras permitidas:\n-cruz\n-quad\n-circ\n");
- return 0;
- }
- FILE *file_map = fopen(fmapa, "r");
- if(file_map == NULL)
- { fprintf(stderr, "\nErro ao abrir o ficheiro de mapa '%s'\n", fmapa);
- return 0;
- }
- else
- ler_mapa(file_map);
- /** Para manter a proporcao XLEN/YLEN */
- float aspect_ratio = (float) getx / (float) gety;
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
- /** A janela vai ter 600 de altura e o comprimento vai depender da proporcao */
- glutInitWindowSize(aspect_ratio * 600, 600);
- glutInitWindowPosition(10, 10);
- glutCreateWindow("Simul");
- /** Inicializar o gerador de numeros aleatorios */
- srandom(time(NULL));
- init();
- /** Definir qual e a função que actualiza a janela */
- glutDisplayFunc(display);
- glutIdleFunc(display);
- glutMainLoop();
- return 0;
- }
- void init(void)
- {
- float aspect_ratio = (float) getx / (float) gety;
- float x = 10.0 * aspect_ratio;
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glColor3f(1.0, 1.0, 1.0);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- /** Qual e a janela que vemos */
- glOrtho(-x, x, -10.0, 10.0, -10.0, 10.0);
- }
- void get_color(char estado, COR *cor) /**Funcao que vai atribuir uma determinada cor consoante o estado*/
- {
- switch (estado)
- { case 'R' : cor-> red = 1.00;
- cor-> green = 0.70;
- cor-> blue = 0.10;
- break;
- case 'C' : cor-> red = 0.50;
- cor-> green = 0.30;
- cor-> blue = 0.50;
- break;
- case 'E' : cor-> red = 0.00;
- cor-> green = 0.00;
- cor-> blue = 0.00;
- break;
- case 'A' : cor-> red = 0.00;
- cor-> green = 0.50;
- cor-> blue = 1.00;
- break;
- case 'F' : cor-> red = 0.00;
- cor-> green = 0.25;
- cor-> blue = 0.00;
- break;
- case 'G' : cor-> red = 0.40;
- cor-> green = 0.20;
- cor-> blue = 0.00;
- break;
- default : cor-> red = 0.20;
- cor-> green = 0.20;
- cor-> blue = 0.20;
- break;
- }
- }
- void initialize_board(char board[XLEN][YLEN])
- {
- int i, j, k=0;
- for (i=0; i<gety; i++)
- { for (j=0; j<getx; j++)
- { board[i][j] = tmp_board[k];
- k++;
- }
- }
- free(tmp_board);
- }
- /**
- * Actualizacao das celulas
- */
- void update_cell (char board[XLEN][YLEN], int x, int y)
- {
- FILE *file_rules = fopen(fregras, "r");
- if(file_rules == NULL)
- { fprintf(stderr, "\nErro ao abrir o ficheiro de regras '%s'\n", fregras);
- exit(1);
- }
- ler_regra(file_rules);
- }
- /**
- * Actualizacao do tabuleiro
- */
- void update_board(char board[XLEN][YLEN])
- {
- int x, y;
- for (x = 0; x < getx; x++)
- for (y = 0; y < gety; y++)
- update_cell(board, x, y);
- }
- /**
- * Funcao que actualiza a janela e e invocada automaticamente pelo openGL
- */
- void display(void)
- {
- static int is_init = 0;
- static char board[XLEN][YLEN];
- if(!is_init)
- { is_init = 1;
- initialize_board(board);
- }
- glClear(GL_COLOR_BUFFER_BIT);
- float aspect_ratio = (float) getx / (float) gety;
- float x = -10.0 * aspect_ratio;
- float y = 10;
- float dx = aspect_ratio * 20 / (float)getx;
- float dy = -20 / (float)gety;
- int i, j;
- for(j = 0; j < gety; j++)
- { for(i = 0; i < getx; i++)
- { COR cor;
- get_color(board[j][i], &cor);
- glColor3f(cor.red, cor.green, cor.blue);
- glRectf(x + i * dx, y + j * dy, x + (i + 1) * dx, y + (j + 1) * dy);
- }
- }
- /** Invocar a actualização do tabuleiro */
- update_board(board);
- glutSwapBuffers();
- }
- /**Funcao que limpa todos os campos referentes aos vizinhos*/
- void limpar_vizinhos (VIZINHOS *vizinhos)
- {
- vizinhos-> R = 0;
- vizinhos-> C = 0;
- vizinhos-> E = 0;
- vizinhos-> A = 0;
- vizinhos-> F = 0;
- vizinhos-> G = 0;
- }
- /**Funcao que calcula quantos vizinhos de cada estado uma determinada casa tem. Vizinhanca em cruz*/
- void viz_cruz (char board[XLEN][YLEN], int x, int y, VIZINHOS *vizinhos)
- {
- int i;
- limpar_vizinhos (vizinhos);
- i=-1;
- while(i<=1)
- { switch(board[x+i][y])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=2;
- }
- i=-1;
- while(i<=1)
- { switch(board[x][y+i])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=2;
- }
- }
- /**Funcao que calcula quantos vizinhos de cada estado uma determinada casa tem. Vizinhanca em quadrado*/
- void viz_quad (char board[XLEN][YLEN], int x, int y, VIZINHOS *vizinhos)
- {
- int i;
- viz_cruz(board, x, y, vizinhos);
- i=-1;
- while(i<=1)
- { switch(board[x+i][y+i])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=2;
- }
- i=-1;
- while(i<=1)
- { switch(board[x+i][y-i])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=2;
- }
- }
- /**Funcao que calcula quantos vizinhos de cada estado uma determinada casa tem. Vizinhanca em circulo*/
- void viz_circ (char board[XLEN][YLEN], int x, int y, VIZINHOS *vizinhos)
- {
- int i;
- viz_quad(board, x, y, vizinhos);
- i=-2;
- while(i<=2)
- { switch(board[x+i][y])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=4;
- }
- i=-2;
- while(i<=2)
- { switch(board[x][y+i])
- { case 'R' : vizinhos-> R++; break;
- case 'C' : vizinhos-> C++; break;
- case 'E' : vizinhos-> E++; break;
- case 'A' : vizinhos-> A++; break;
- case 'F' : vizinhos-> F++; break;
- case 'G' : vizinhos-> G++; break;
- }
- i+=4;
- }
- }
- /**Verifica se o tipo de vizinhanca introduzida e valida*/
- int regra_valida(char *regra)
- {
- if (strcmp(regra, "cruz")!=0 && strcmp(regra, "quad")!=0 && strcmp(regra, "circ")!=0)
- return 0;
- else
- return 1;
- }
- /**Verifica se o valor atribuido a uma determinada casa e valido*/
- int estado_valido(char est)
- {
- if((est != 'R') && (est != 'C') && (est != 'E') && (est != 'A') != (est == 'F') != (est == 'G'))
- return 0;
- else
- return 1;
- }
- /**Funcao que le o ficheiro referente ao mapa e atribui os valores ao board temporario*/
- void ler_mapa(FILE *file_map)
- {
- int i;
- int get[2];
- for(i=0;i<2;i++)
- fscanf(file_map, "%d", &get[i]);
- getx = get[0];
- gety = get[1];
- if(getx>XLEN || getx<=0 || gety>YLEN || gety<=0)
- { printf("\nAs dimensoes da matriz nao sao permitidas!\n");
- exit(1);
- }
- tmp_board = (char *) malloc(getx * gety * sizeof(char));
- for (i = 0; i < (getx * gety); i++)
- { fscanf(file_map, "%c", &tmp_board[i]);
- if(isspace(tmp_board[i]))
- { i--;
- continue;
- }
- /*fscanf(file_map, "%c", &tmp_board[i]);*/
- if(!estado_valido(tmp_board[i]))
- { fprintf(stderr, "Foi encontrado um caracter invalido: ('%c')\n", tmp_board[i]);
- exit(1);
- }
- }
- fclose(file_map);
- }
- /**Funcao que le o ficheiro das regras e as armazena na struct correspondente as regras*/
- void ler_regra(FILE *file_rules)
- {
- int i = 0, j, x;
- REGRAS regras = NULL;
- char tmp_array[100][100];
- char linha[100];
- char ant[100][100], nvalor[100][1];
- char ant2[100][100], nvalor2[100][1];
- while (fgets(linha, 100, file_rules) != NULL)
- { strcpy(tmp_array[i], linha);
- strcpy(ant[i], strtok(tmp_array[i], ":")); /* Antes de : */
- strcpy(nvalor[i], strtok(NULL, ":")); /* Depois de : */
- strcpy(nvalor2[i], nvalor[i]);
- for(j = 0; j < strlen(nvalor[i]); j++)
- if(isspace(nvalor[i][j]) != 0)
- strcpy(nvalor[i], strdelc(nvalor2[i], nvalor2[i][j]));
- strcpy(nvalor[i], strdelc(nvalor[i], '\n'));
- i++;
- }
- for(x = 0; x < i; x++)
- { strcpy(ant2[x], ant[x]);
- for(j = 0; j < strlen(nvalor[i]); j++)
- if(isspace(ant[i][j]) != 0)
- strcpy(ant[i], strdelc(ant2[i], ant2[i][j])); /* antes do : */
- nvalor[i][0] = strfstc(nvalor[i]);
- regras = inserir(ant[i], nvalor[i][0], regras);
- }
- inverter_l(regras);
- fclose(file_rules);
- }
- /**Funcao auxiliar para retirar o caracter finalizador '\0'*/
- char *strdelc (char *s, char ch)
- {
- int i,j;
- for(i=j=0; s[i] != '\0'; i++)
- if (s[i] != ch)
- s[j++] = s[i];
- s[j] = '\0';
- return s;
- }
- /**Funcao auxiliar que vai retornar o primeiro caracter da string*/
- char strfstc (char *s)
- {
- return s[0];
- }
- /**Insere os valores que lhe sao passados, na cabeca da lista*/
- REGRAS inserir(char *ant, char nvalor, REGRAS regras)
- {
- REGRAS n = (REGRAS) malloc(sizeof(REGRA));
- if(is_vazia(regras))
- { n->condicao = ant;
- n->hipotese = nvalor;
- n->next = NULL;
- }
- else
- { n->condicao = ant;
- n->hipotese = nvalor;
- n->next = regras;
- }
- return n;
- }
- /**Verifica se a lista esta vazia*/
- int is_vazia(REGRAS r)
- {
- return r == NULL;
- }
- /**Inverte a ordem de uma lista ligada*/
- REGRAS inverter_l(REGRAS regras)
- {
- REGRAS n = regras;
- REGRAS aux = NULL;
- while(!is_vazia(n))
- { aux = inserir(n->condicao, n->hipotese, aux);
- n = n->next;
- }
- free(n);
- return aux;
- }
Add Comment
Please, Sign In to add comment