domingo, 8 de junho de 2014

Jogo da Vida com Zoom


O exercício proposto foi achar um modo de dar um zoom no jogo da vida para melhor visualização dos comportamentos. Descobri que já existia uma função no processing que fazia isso automaticamente. A scale() onde pode-se passar por parametro a quantidade de vezes que pretende dar um zoom.

//A tela terá dimensão tam x tam
int tam = 100;
//Como o tipo PImage é armazenado em vetor, então...
int vtam = tam*tam;
//Imagem a ser exibida
PImage mundo = createImage(tam, tam, RGB);
//Imagem auxiliar para criar uma geração
PImage mundoTemp = createImage(tam, tam, RGB);

int geracao = 0;
int maiorPopulacao = 0;
int menorPopulacao = 0;

void setup() {
  size(800, 800);
  background(0);
  frameRate(5);
  criaMundo();
}

void draw() {
 
 
  scale(8);
  //Criando gerações
  evoluiMundo();
  //Exibindo
  image(mundo, 0, 0);
  geracao++;
  maiorPopulacao = maiorPopulacao(maiorPopulacao);
  menorPopulacao = menorPopulacao(menorPopulacao);
  println("Numero de células vivas " + contaCelulas() + " na geração " + geracao);
  println("Maior população: " + maiorPopulacao);
  println("Menor população: " + menorPopulacao);
}

//cria uma geração
void evoluiMundo() {
  /*A nova geração será guardada em mundoTemp, então
   é necessário copiar a geração atual para mundoTemp */
  for (int i=0; i<vtam; i++)
    mundoTemp.pixels[i] =  mundo.pixels[i];

  //Contador de vizinhos 
  int vizinhos;
  //Para cada célula aplicar as regras do jogo da vida
  for (int i=1; i<tam-1; i++)
    for (int j=1; j<tam-1; j++) {
      vizinhos = contaVizinhos(i, j); //Qtde de vizinhos de uma célula i,j     
      //Se a célula viva, ...
      if (mundo.pixels[pos(i, j)] == color (0, 255, 0)) {
        //Menor que 2 vizinhos ou maior que 3, morra
        if ((vizinhos < 2) ||(vizinhos > 3))
          mundoTemp.pixels[pos(i, j)] = color (0, 0, 0);
      }
      //Se morta, mas com 3 vizinhos, viva
      else if (vizinhos == 3)
        mundoTemp.pixels[pos(i, j)] = color (0, 255, 0);
    }

  //Depois de geração criada, atualizar o mundo, copiando de mundoTemp
  mundo.loadPixels();
  for (int i=0; i<vtam; i++)
    mundo.pixels[i] = mundoTemp.pixels[i];
  mundo.updatePixels();
}

//Conta quantos vizinhos a célula possui
int contaVizinhos(int i, int j) {
  int vizinhos=0;
  vizinhos = celula(i-1, j-1) + celula(i-1, j) + celula(i-1, j+1)
    +celula(i, j-1) + celula(i, j+1) + celula(i+1, j-1)
      +celula(i+1, j) + celula(i+1, j+1);
  return vizinhos;
}

//Se a célula for viva (cor 0,255,0 - verde), retorna 1, senão 0
int celula(int i, int j) {
  if (mundo.pixels[pos(i, j)] == color(0, 255, 0))
    return 1;
  return 0;
}

//Mapeia a posição da matriz em um vetor
int pos(int i, int j) {
  return j * tam + i;
}

//Conta células vivas
int contaCelulas()
{
  int c = 0;

  for (int i = 0; i < vtam; i++)
  {
    if (mundo.pixels[i] == color(0, 255, 0))
    {
      c++;
    }
  }
  return c;
}

//Verifica a maior populacao existente
int maiorPopulacao(int maior)
{
  if (contaCelulas() > maior)
  {
    maior = contaCelulas();
  }
  return maior;
}

//Verifica a menor populacao existente
int menorPopulacao(int menor)
{
  if (menor == 0)
  {
    menor = contaCelulas();
  }
  else if (contaCelulas() < menor)
  {
    menor = contaCelulas();
  }
  return menor;
}


//Cria um mundo aleatório em um quadrado central que vai de 1/3 a 2/3 da tela
void criaMundo() {

  for (int i=0; i<vtam; i++)
  {
    int x = int(random(tam/3, 2*tam/3));
    int y = int(random(tam/3, 2*tam/3));
    mundo.pixels[pos(x, y)] = color(0, 255, 0);
  }
}

Nenhum comentário:

Postar um comentário