#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define TAM 4
#define TAM_POP 10
#define SIM 1
#define NAO 0
#define ERRO 0

#define SEG1 1
#define SEG2 2
#define TER1 3
//termina em #define SEX2 11

#define P1 1
#define P2 2

#define FECHINE "00"
#define FRED "01"
#define NILTON "10"
#define D1 "000"
#define D2 "001"
#define D3 "010"

// um professor P pode ensinar uma ou mais disciplinas D
// a relacao eh de 1-N, entretanto, uma disciplina soh tem um professor
#define ensina(P,D) if ( (strcmp(individuo[i].prof,P)!=0) &&  (strcmp(individuo[i].disc,D)==0) ) resultado--
// se o professor P esta indisponivel no horario H, entao ja deu erro (relacao 1-1)
#define indisponivel(P,H) if ( (strcmp(individuo[i].prof,P)==0) &&  Horario(i)==(H) ) resultado--
// uma disciplina D so pode pertencer a um PERIODO (relacao 1-1)
#define pertence(D,PERIODO) if ( (strcmp(individuo[i].disc,D)==0) &&  P(i)!=PERIODO ) resultado--


/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 15/08/2006
 * Última Alteração: 15/08/2006
 *
 * Objetivo: Função que retorna um numero aleatorio entre INFERIOR e SUPERIOR
 * Entrada: o limite inferior (inferior) e o limite superior (superior)
 * Retorno: numero aleatorio entre inferior e superior. Ex. aleatorio(30,31) retorna 30 ou 31
 * Saida: nenhuma
 */
long aleatorio(long inferior, long superior){
     srand(time(NULL));
     return (rand()%(superior+1-inferior)+inferior);
}


/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 14/08/2006
 * Última Alteração: 14/08/2006
 *
 * Objetivo: Função que retorna o período da disciplina
 * Entrada: indice do vetor (de individuo)
 * Retorno: 1, se for P1
 *          2, se for P2
 * Saida: nenhuma
 */
int P(int indice){
	if (indice>=0 && indice<=5) return P1;  //primeiro periodo
	if (indice>=6 && indice<=11) return P2; //segundo periodo
}

/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 14/08/2006
 * Última Alteração: 14/08/2006
 *
 * Objetivo: Função que retorna o horario da disciplina
 * Entrada: indice do vetor (do individuo)
 * Retorno: 1 (SEG1), se 0 ou 6
 *          2 (SEG2), se 1 ou 7
 *          3 (TER1), se 2 ou 8
 * Saida: nenhuma
 */
int Horario(int indice){
	if (indice==0 || indice==6) return SEG1;  //essa eh a seg, primeiro horario do P1 e P2
	if (indice==1 || indice==7) return SEG2;
	if (indice==2 || indice==8) return TER1;
}

/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 14/08/2006
 * Última Alteração: 15/08/2006
 *
 * Estrutura que define um gene. Ex: {"01","010"}, que representa (Fred,d1)
 */
typedef struct {
	 char prof[10];
	 char disc[4];
} tDisciplina;


void imprime4Char(char nome[]){
     printf("%c%c%c%c",nome[0],nome[1],nome[2],nome[3]);     
}

/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 14/08/2006
 * Última Alteração: 14/08/2006
 *
 * Objetivo: Função que imprime um individuo na forma de grade horaria
 * Entrada: um individuo do problema, que eh um vetor de tamanho TAM do tipo tDisciplina
 * Retorno: nenhum
 * Saida: impressão do indivíduo em forma de grade horária
 */
void imprimirGrade(tDisciplina vetor[]){
	  int i;
	  for(i=0;i<TAM;i++){
			if (i%6==0){
				printf("\n\n\nP%d",P(i));
				printf("\n|---SEG---|---TER---|---QUA---|");
			}

			if (i%3==0) {
				printf("\n");
				if (i%6!=0) printf("|---------|---------|---------|\n");
			}

			printf("| ");
			imprime4Char(vetor[i].prof);
			
			printf(" %s",vetor[i].disc);

	  }
}

/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 15/08/2006
 * Última alteração: 15/08/2006
 *
 * Objetivo: Função que procura o individuo mais adaptado
 * Entrada: um individuo, que eh um vetor de tamanho TAM do tipo tDisciplina
 * Retorno: 0,            igual ao valor máximo = ponto de parada = indivíduo ótimo
 *          negativo,     indivíduos que possuem algum problema
 * Saida: nenhuma
 */
int fitness(tDisciplina individuo[]){
	int i, disparouRegra=0, resultado=0;
	for(i=0;i<TAM;i++){

		ensina(NILTON,D2);
		ensina(FRED,D3);
		ensina(NILTON,D2);
		indisponivel(FECHINE,SEG2);
		pertence(D1,P1);

	}
	return resultado;
}


/*******************************
 * Autor: Frederico Brito Fernandes
 * Data: 15/08/2006
 * Última Alteração: 15/08/2006
 *
 * Objetivo: Função que imprime um individuo na forma binaria
 * Entrada: um individuo do problema, que eh um vetor de tamanho TAM do tipo tDisciplina
 * Retorno: nenhum
 * Saida: impressão dos bits do individuo na tela
 */
void imprimirIndividuo(tDisciplina individuo[TAM]){
    int i,j;

    for (i=0;i<TAM;i++){
        printf("%s%s",individuo[i].prof,individuo[i].disc);    
        }
}


main(){

	 tDisciplina individuo[TAM] = {{FECHINE,D1},{FRED,D3},{FECHINE,D1},{NILTON,D2}};
     
     imprimirIndividuo(individuo);
	 //clrscr();
	 printf(", cujo fitness() = %d \n",fitness(individuo));
	 //imprimirGrade(individuo);
	 getch();

}
