Simulação
Ir para navegação
Ir para pesquisar
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
/* declaracao de funcoes */
void passo(FILE *arq);
void inicializacao(FILE *arq);
void atualizar_posicao(void);
int mudar_velocidade(int(v));
int calculo_distancia(void);
/* declaracao var global */
#define tempo_max 100
#define num_carros 30
#define comprimento_rua 60
#define veloc_max 6
/* velocidade: numero de posições */
/* que o carro andará num passo */
int rua[comprimento_rua], vel[num_carros];
int prim_carro, dist;
int i, j, t;
//probab_vel = probabilidade de reduzir a velocidade
double probab_vel = 0.3;
void main(void)
{
//srand48(time(NULL));
FILE *arq;
arq = fopen("1_lane.dat", "w+");
inicializacao(arq);
for(t = 0; t < tempo_max; t++)
{
passo(arq);
}
fclose(arq);
}
void inicializacao(FILE *arq){
// zerando vetores
//-1 significa que a posicao esta vazia
for(i = 0; i < comprimento_rua; i++){
rua[i] = -1;
}
//iniciando os carros - rua[i] representa o indice do carro, atraves do qual acessaremos sua velocidade em vel[rua[i]]
for(i = 0; i < num_carros; i++)
{
vel[i] = 0;
rua[i*comprimento_rua/num_carros] = i;
}
//printando a condição inicial, no terminal e no arquivo
for (i = 0; i < comprimento_rua; i++){
if(rua[i] == -1){
printf(".");
fprintf(arq, "-1 ");
}
else{
printf("%d", vel[rua[i]]);
fprintf(arq, "%d ", vel[rua[i]]);
}
}
printf("\n");
fprintf(arq, "\n");
}
void passo(FILE *arq)
{
i = 0;//posicoes na rua
prim_carro = -1; //para que caso ainda nao haja um primeiro carro, prim_carro assuma um valor que nao se confunda com nenhum indice de carro (que vao de 0 a num_carros)
while(i < comprimento_rua){
/* Para descobrir a posicao do primeiro carro */
/* tem carro na posição 'i'? */
if (rua[i] == -1){
/* não, não tem carro em 'i' */
/* vai pra prox posicao 'i' */
i++;
printf(".");
fprintf(arq, "-1 ");
}
else{
/* caso for o primeiro carro, */
/* salvar sua posicao para */
/* calcularmos a distancia do */
/* ultimo carro ao primeiro */
if(prim_carro == -1){
prim_carro = i;
}
//calculando distancia ate o proximo carro
dist = calculo_distancia();
//mudando velocidades
vel[rua[i]] = mudar_velocidade(vel[rua[i]]);
printf("%d", vel[rua[i]]);
fprintf(arq, "%d ", vel[rua[i]]);
for(j = i+1; (j < i+dist) && (j < comprimento_rua); j++)
{
printf(".");
fprintf(arq, "-1 ");
}
//atualizando posicoes
atualizar_posicao();
//pula para o proximo carro
i+= dist;
}
}
printf("\n");
fprintf(arq, "\n");
}
void atualizar_posicao(void){
/* atualiza apenas se a velocidade */
/* for diferente de zero */
if( vel[rua[i]] != 0 ){
//para o ultimo carro, condicoes de contorno periodicas
if( i + vel[rua[i]] >= comprimento_rua ){
rua[(i+ vel[rua[i]]) % comprimento_rua] = rua[i];
}
else{
rua[i + vel[rua[i]]] = rua[i];
}
rua[i] = -1;
}
}
int calculo_distancia(void){
/* RETORNA A DISTANCIA ENTRE O */
/* CARRO 'i' E O QUE ESTA NA */
/* SUA FRENTE NA FAIXA */
/* caso não for o ultimo carro */
/* procura posição do prox. e */
/* calcula a distancia até ele */
/* temos que isolar o caso i = comprimento_rua - 1, */
/* já que seria j = i + 1 = comprimento_rua, e usamos */
/* rua[j], sendo que j deve ser < comprimento_rua. */
if( i + 1 < comprimento_rua ){
j = i + 1;
while ( (rua[j] == -1) && (j < comprimento_rua) ){
j++;
}
if ( j != comprimento_rua ){
dist = j - i;
}
}
/* para o ultimo carro a distan- */
/* cia é calculada em relacao ao */
/* primeiro, pois são C.C. perio- */
/* dicas. */
//ultimo carro, e existe um primeiro carro
if( ((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro != -1)){
dist = comprimento_rua - (i - prim_carro);
}
//caso so haja um carro ou a pista esteja vazia
else if(((i == comprimento_rua - 1) || (j == comprimento_rua)) && (prim_carro == -1))
{
dist = comprimento_rua;
}
return dist;
}
int mudar_velocidade(int(v)){
int x;
/* RETORNA NOVA VELOCIDADE */
/* Regra 1 */
/* caso dê pra acelerar, acelere */
if( ( v < veloc_max ) && ( dist > v + 1 ) ){
x = v + 1;
}
/* Regra 2 */
/* caso pouco espaço, desacelere */
else if( dist < v + 1 ){
x = dist - 1;
}
else
{
x = v;
}
/* Regra 3 */
/* redução de velocidade randomica */
if( ( x > 0 ) && ( drand48() < probab_vel )){
x--;
}
return x;
}