1
RELATÓRIO PARCIAL DE INICIAÇÃO CIENTÍFICA
CAMPUS PIRACICABA
CONSTRUÇÃO DE UM AMBIENTE VIRTUAL PARA
SIMULAÇÃO DE APLICAÇÕES DE VIDA ARTIFICIAL
ALUNO: HÉLLEN CAROLINE SALVATO ORIENTADOR: MARCIO KASSOUF CROCOMO
2
RESUMO
Este projeto tem como objetivo o desenvolvimento de um ambiente virtual para simulação de aplicações de vida artificial utilizando como base estudos feitos dentro do contexto de inteligência artificial, algoritmos genéticos e computação evolutiva, onde os agentes (ou “criaturas”) criadas durante a simulação terão a capacidade de sobreviver a partir de um algoritmo evolutivo utilizado. Com isso, através de testes e observações, serão coletados dados para análise e avaliação da capacidade de sobrevivência e evolução dos mesmos. Ao final é esperado que os resultados do trabalho tragam contribuições para as áreas de desenvolvimento de jogos, inteligência artificial e vida artificial.
3
ABSTRACT
This project aims to develop a virtual environment for simulation of artificial life applications using as a basis studies within the context of artificial intelligence, genetic algorithms and evolutionary computation, where the agents (or "creatures") created during the simulation will have the ability to survive using an evolutionary algorithm. Thus, through testing and observation, we will collect data for analysis and evaluation of survivability and evolution of the agents. At the end of the process, we expect to be able to use the resulting software in the fields of Game Development, Artificial Intelligence and Artificial Life.
4
SUMÁRIO
CAPÍTULO 1 ...8 INTRODUÇÃO ...8 CAPÍTULO 2 ... 12 TRABALHOS RELACIONADOS ... 12 CAPÍTULO 3 ... 13 METODOLOGIA DO DESENVOLVIMENTO ... 13 CAPÍTULO 4 ... 15CRONOGRAMA E ATIVIDADES PROPOSTAS NO PROJETO INICIAL ... 15
ATIVIDADES REALIZADAS ... 17
ATIVIDADES FUTURAS... 18
CONSIDERAÇÕES FINAIS ... 19
5
LISTA DE FIGURAS
6
LISTA DE TABELAS
Tabela 1 – Metas estabelecidas para a pesquisa. 16
7
LISTA DE ABREVIATURAS
IA: Inteligência Artificial VA: Vida Artificial
AG: Algoritmos Genéticos AE: Algoritmos Evolutivos
8
CAPÍTULO 1
Este Capítulo apresenta uma introdução ao tema do projeto, apresentando campos de estudo que se conectam ao trabalho em questão, a importância e usabilidade do mesmo nas varias áreas que se aplica.
INTRODUÇÃO
Este projeto envolve diversos assuntos, como Computação Evolutiva, Vida Artificial, Inteligência Artificial, Algoritmos Genéticos, e suas aplicações nas mais variadas áreas, como jogos eletrônicos, resolução de problemas a simulações biológicas.
A Computação Evolutiva é um conceito que utiliza um algoritmo evolutivo, baseando-se em conceitos biológicos de evolução, para a busca de variadas soluções para um determinado problema, com isso, espera-se a cada geração obter soluções candidatas mais eficazes, porem não existe a garantia de se chegar a uma solução ótima ao final do processo evolutivo (ZUBEN, 2000).
O objetivo do campo de estudo de Vida Artificial (VA) como o nome sugere, é o estudo da vida através do conceito de vidas artificiais (MAES, 1995). O termo surge em 1987, com o 1º Workshop de Vida Artificial, organizado por Christopher Langton (LANGTON, 1995), considerado o fundador da área.
Recentemente, um avanço na área tem ocorrido graças ao numero de pesquisas relacionadas e a simulações criadas, algumas contendo elementos visuais em duas ou três dimensões, outras não. Os principais objetivos dessas simulações é simular e avaliar a evolução e a capacidade de sobrevivência e reprodução de criaturas artificiais em diferentes ambientes, podendo aplicar isso em diversas áreas, como na busca por soluções de um problema, onde o problema é o cenário da simulação e as soluções candidatas são as criaturas. Alguns exemplos de simulações já existentes são o Avida (OFRIA; BRYSON; WILKE, 2009), breve (KLEIN, 2003), e Tierra (LANGTON, 1995) entre outros.
As áreas onde se aplicam os conceitos de VA são diversas como, por exemplo, na autonomia de personagens e criaturas de filmes, animações ou jogos, ambientes mais realistas para os mesmos, realização de experimentos científicos biológicos, ecológicos, físicos entre outros (NETTO; RINALDI, 2011). Em especial, a área de entretenimento é apontada em
9 (MAES, 1995) como promissora para este campo, embora pouco explorada até o ano em que a afirmação foi feita.
Um interesse compartilhado pelos campos de VA e inteligência artificial, é criação de agentes autônomos capazes de se adaptar em ambientes complexos, podendo tomar diferentes formas e/ou apresentar diferentes comportamentos dependendo do ambiente em que habitam (MAES, 1995).
São várias as definições de Inteligência Artificial (IA), dividindo assim os pesquisadores da área. As definições são divididas em quatro grupos: “Pensando como um humano”, “Pensando racionalmente”, “Agindo como seres humanos” e “Agindo racionalmente” (RUSSELL; NORVIG, 2009).
As definições que começam com “Agindo” ligam a IA ao comportamento, e as que começam com “Pensando” se referem a processos de pensamento e raciocínio. Já as definições que possuem a palavra “humano” avalia a IA com base na proximidade que a mesma apresenta em comparação ao desempenho humano, enquanto as que possuem a palavra “racionalidade” ligam a um conceito ideal de inteligência, sendo que um sistema é considerado racional se “faz a coisa certa” (RUSSELL; NORVIG, 2009). Outra definição presente em (POOLE; MACKWORTH; GOEBEL, 1998) diz “Inteligência Computacional é o estudo do projeto de agentes inteligentes”.
Diversas técnicas são utilizadas no campo de Inteligência Artificial como, por exemplo, Redes Neurais, Árvores de Decisão, Algoritmos Evolutivos, entre outras (RUSSELL; NORVIG, 2009). Dado a grande quantidade de técnicas existentes, a pesquisa com foco em encontrar trabalhos envolvendo diferentes técnicas demandaria um tempo maior do que o planejado para as atividades de pesquisa nos meses iniciais do projeto. Por esta razão, embora trabalhos envolvendo diferentes técnicas possam ser encontrados durante esta etapa, o foco principal será no estudo de Algoritmos Evolutivos, por estes já estarem inseridos no campo de VA, permitindo assim a simulação de organismos vivos.
Os Algoritmos Evolutivos (AEs) são baseados na teoria da evolução de Charles Darwin, esses funcionam gerando inicialmente, de forma aleatória uma população de indivíduos, na qual cada indivíduo possui um cromossomo, que representa uma solução candidata para um problema a ser resolvido. Em seguida, cada cromossomo é avaliado, recebendo assim um valor de aptidão, que indica a qualidade da solução. Com base nesta pontuação, um grupo de indivíduos é selecionado e, através de operadores evolutivos como crossover e mutação, novos cromossomos são gerados, criando assim um novo conjunto de soluções candidatas que representam a próxima geração de indivíduos do algoritmo. Este processo é repetido, com
10 uma tendência de, a cada geração, selecionar cromossomos que representem soluções mais aptas para o problema sendo tratado. Diferentes critérios de parada podem ser utilizados, buscando parar quando uma solução aceitável é encontrada. A Figura 1 ilustra o funcionamento de um possível AE.
Figura 1 - Funcionamento de um possível Algoritmo Evolutivo
A área de IA visualiza os produtos de AEs como sendo soluções para problemas, enquanto VA visualiza tais produtos como organismos (RUSSELL; NORVIG, 2009), o que se aproxima mais do objetivo do presente trabalho, que busca criar organismos com comportamentos de seres vivos para aumentar a imersão do jogador no ambiente virtual, como é proposto em (MAES, 1995). Assim, uma possível forma de se utilizar um AE no Ambiente Virtual criado neste trabalho é o de definir cromossomos para as criaturas responsáveis por definir o comportamento das mesmas, e utilizar como métrica de aptidão (função de fitness) o tempo de sobrevivência da criatura no ambiente. Sendo assim, a primeira geração de criaturas apresentaria comportamentos aleatórios, e criaturas com melhor aptidão (as que conseguem sobreviver mais tempo) possuem uma maior probabilidade de passar seu código genético para as gerações futuras. De forma similar, em (CROCOMO; MIAZAKI; SIMOES, 2007) uma população de criaturas evolui utilizando um Algoritmo Evolutivo para desenvolver comportamentos de perseguição (perseguir presas) e fuga (fugir de predadores).
Como já foi dito anteriormente uma das áreas mais promissoras para essa aplicação é o mercado de jogos eletrônicos. Segundo boletim divulgado pelo SEBRAE (SEBRAE, 2012a), o mercado de jogos movimenta bilhões de dólares no mundo, tendo sido gastos US$ 58,2 bilhões com software e publicidade para jogos em 2010, e com a previsão de atingir US$ 91,2 bilhões até 2015. Esse aumento acontece graças aos avanços tecnológicos e a melhoria da qualidade e quantidade de jogos que vem sendo produzidos. O Brasil não está de fora, mesmo com toda a pirataria que é o um fator muito prejudicial a esse mercado, seus números vêm
11 crescendo, o que tem atraído à atenção de grandes empresas estrangeiras, assim como incentivos por meio de investimentos e apoios governamentais (SEBRAE, 2012b).
Vale ressaltar que alguns jogos além do puro entretenimento possuem outras aplicações, são os chamados jogos sérios (SUSI; JOHANNESSON; BACKLUND, 2007). Esses possuem diversas finalidades como, por exemplo, fins militares, governamentais, educativos, corporativos, de saúde entre outros. Uma das vantagens é a possibilidade do usuário vivenciar situações que são impossíveis ou difíceis no mundo real por razões de segurança, custo tempo, entre outras.
Devido à grande variedade de finalidades as quais os jogos podem possuir, e também a grande movimentação financeira do mercado de jogos, pesquisas são desenvolvidas envolvendo jogos em diversas áreas da computação, como em Redes (SHEA et al., 2013), Computação Gráfica (BITTENCOURT, J. R. ; OSÓRIO, 2006) e Inteligência Artificial (CROCOMO; SIMÕES, 2008; POLICARPO; URBANO; LOUREIRO, 2010). Assim, em (MAES, 1995) jogos são apontados como uma área promissora para o desenvolvimento de pesquisa com agentes autônomos, combinando as áreas de IA e VA, e com essa ideia é proposto esse projeto.
12
CAPÍTULO 2
Aqui é apresentado um pouco de alguns dos trabalhos pesquisados e usados como referência para a criação desse projeto, suas ideias principais e resultados.
TRABALHOS RELACIONADOS
Os trabalhos relacionados pesquisados para compor esse projeto, foram todos aqueles ligados a vida artificial, a simulações de vida artificial, criação de ambientes utilizando a mesma e aplicações. Alguns exemplos de simulação são o Avida (OFRIA; BRYSON; WILKE, 2009), breve (KLEIN, 2003), e Tierra (LANGTON, 1995).
Uma população de criaturas que evolui utilizando um Algoritmo Evolutivo é proposto por (CROCOMO; MIAZAKI; SIMOES, 2007) onde é esperado o desenvolvimento dos comportamentos de perseguição (perseguir presas) e fuga (fugir de predadores). É importante ressaltar que em (CROCOMO; MIAZAKI; SIMOES, 2007) o objetivo principal do AE implementado é obter diferentes estratégias no jogo para competir diretamente com o jogador sendo assim possui um foco maior em IA.
Em (INFORM, 2012) é proposta a criação de um jogo que simula a geração de planetas e vida nos mesmos, nesse projeto os autores também utilizam o Unity 3D e o Blender 3D para modelagem, e o objetivo deste trabalho além do aprendizado em criação de jogos, também foi criado um gerador processual de planetas e no sistema o jogador deve construir estruturas que proporcionem recursos capazes de sustentar o ecossistema do planeta.
No trabalho (KLEIN, 2003) é desenvolvido um ambiente de simulação em 3D chamado de BREVE, esse foi projetado para simular sistemas descentralizados e vida artificial. O objetivo final do sistema é permitir que simulações sejam implementadas rapidamente e facilmente, proporcionando uma poderosa estrutura que facilita a construção avançada de simulações de vida artificial.
O trabalho (ANDRADE; SILVA; CROCOMO, 2004) foi desenvolvido um AE, e elaborado um jogo em que as estratégias adotadas pelos personagens não controlados por jogadores (NPC) se adaptavam de acordo com as estratégias utilizadas por jogadores a cada batalha, aumentando a atratividade do software utilizando o AE.
13
CAPÍTULO 3
Neste Capítulo são apresentados os materiais e métodos utilizados para pesquisa, estudo, planejamento e desenvolvimento do software.
METODOLOGIA DO DESENVOLVIMENTO
Para uma maior facilidade e agilidade no desenvolvimento, foi selecionada uma ferramenta com a qual o proponente do projeto já possui certa experiência, facilitando assim essa etapa. Esse software é o Unity 3D (UNITY, 2015), uma ferramenta para criação de jogos 3D e 2D, que torna o desenvolvimento de aplicações gráficas mais rápida e simples, e também disponibiliza muitos modelos, códigos entre outras ferramentas iniciais gratuitas que facilitam o desenvolvimento. Essa ferramenta possui uma versão gratuita e suporta as linguagens de programação C# e JavaScript, que estarão sendo utilizadas na escrita dos códigos desse projeto.
Os modelos 3D utilizados nesse projeto foram baixados gratuitamente na própria asset
store do Unity que disponibiliza modelos para uso gratuito. Algumas prefabs entre outras
ferramentas padrões disponibilizadas pelo Unity estão sendo utilizadas. Enquanto os principais códigos, relacionados a geração de mapas, geração de plantas, e a vida artificial em si, estão sendo criados, nas linguagens de programação C# e/ou JavaScript, utilizando o editor presente no Unity (MonoDevelop).
As pesquisas para o desenvolvimento desse projeto foram feitas utilizando como principais meios, a revista Artificial Life do MIT (MIT, 2015) e o Google Scholar, e alguns projetos e simulações já existentes foram estudados.
Técnicas de algoritmos evolutivos foram estudadas com o objetivo de criar um Algoritmo Evolutivo capaz de evoluir os agentes no ambiente virtual criado nesse projeto. A construção desse algoritmo é uma das principais funcionalidades do software proposto nesse projeto.
Para alcançar os objetivos deste projeto, encontram-se listadas abaixo, na ordem em que estão sendo executadas, as etapas, com os respectivos números de meses em que serão priorizadas, e os materiais e métodos que estão sendo utilizados em cada uma.
14 Pesquisa e estudo (2 meses): Nesta etapa, foi feita a pesquisa por trabalhos relacionados com o tema do projeto, o que envolve trabalhos sobre vida artificial, jogos, e criação de ecossistemas artificiais. Embora seja de interesse nessa etapa a pesquisa e estudo por diferentes técnicas de IA para a programação dos agentes autônomos, isso poderia tornar o projeto impraticável dentro do período disponível para execução do mesmo, já que grandes quantidades de técnicas de Inteligência Artificial encontram-se disponíveis na literatura. Dessa forma, com a finalidade de limitar os trabalhos pesquisados e estudados, os estudos foram concentrados nesta etapa as pesquisas por trabalhos similares envolvendo AEs para serem utilizados no ambiente criado. Como foi dito anteriormente o Google Scholar foi utilizado nesta etapa para buscar trabalhos relevantes, sendo algumas fontes promissoras de informação o Journal of Artificial Life, e artigos publicados no SBGames, mas não ficando a pesquisa limitada a estas fontes.
Planejamento (1 mês): Com base nos trabalhos pesquisados na etapa anterior, o ambiente artificial, as criaturas e o algoritmo evolutivo a serem implementados foram planejados buscando criar um ambiente artificial adequado, e promissor para trazer contribuições para a literatura nas áreas de VA e no desenvolvimento de jogos.
Implementação (3 meses): O ambiente virtual planejado na etapa anterior está sendo implementado e testado com a finalidade de encontrar e corrigir possíveis erros ainda durante a implementação. As ferramentas e linguagem de programação a serem utilizadas foram decididas durante as pesquisas realizadas, as escolhidas como já dito no inicio dessa capitulo são a Unity 3D (UNITY, 2015) e as linguagens de programação que a mesma suporta que são JavaScript e C#. Foram priorizadas as ferramentas com as quais já havia familiaridade da parte dos realizadores do projeto, para que fosse dedicado mais tempo à implementação do sistema do que estudando tecnologias que desconhece.
Realização de testes, coleta e verificação dos dados (2 meses): Testes deverão ser realizados com o objetivo de verificar a evolução das criaturas no ambiente. Dessa forma, será objeto de estudo a evolução das criaturas e possíveis comportamentos emergentes, sendo a análise dos dados orientada pelas seguintes perguntas:
1 – É possível verificar a evolução dos agentes?
15 3 – Tais comportamentos podem colaborar na construção de ambientes em jogos comerciais, trazendo contribuições para a experiência do jogador?
4 – Os resultados trazem colaboração para o campo de vida artificial ao reproduzir e/ou permitir melhor entendimento da vida biológica como conhecemos?
É importante ressaltar que as questões 1 e 2 cabem dentro do prazo de nove meses previsto para este projeto, no entanto, as questões 3 e 4 poderão ser melhor desenvolvidas após a execução do projeto, quando o ambiente artificial, que é o principal objetivo deste projeto, estará funcionando e, assim, experimentos mais elaborados poderão ser planejados.
Escrita do relatório final (1 mês): O relatório final deverá ser escrito contendo os principais resultados do trabalho.
No Anexo 1 é possível observar detalhadamente toda a parte de planejamento e implementação da geração de mapas proposto já em funcionamento, enquanto a geração e reprodução das plantas que também já está em funcionamento, é explicada no Anexo 2. Os Anexos 3 e 4 mostram respectivamente o planejamento das criaturas e do funcionamento do software.
CAPÍTULO 4
Neste capítulo são relatadas as atividades do projeto como planejadas originalmente, as atividades realizadas até a entrega deste relatório, e as que ainda deverão ser concluídas até a finalização deste projeto, também é apresentada nesse capitulo as considerações finais sobre o andamento do projeto.
CRONOGRAMA E ATIVIDADES PROPOSTAS NO PROJETO
INICIAL
A tabela a seguir mostra a lista em ordem cronológica das atividades a serem realizadas, em seguida, a segunda tabela mostra o cronograma proposto a ser cumprido, de acordo com as atividades listadas, em um período de 9 meses.
16 Tabela 1 – Metas estabelecidas para a pesquisa.
METAS DESCRIÇÃO
1 Pesquisa de trabalhos relacionados à simulação de vida artificial, envolvendo a criação de ecossistemas, criaturas, ou outras formas de vida artificial.
2 Estudo de Algoritmos Evolutivos e pesquisa por trabalhos utilizando os mesmos em jogos.
3 Planejamento do ambiente, das criaturas, e do algoritmo evolutivo a ser implementado.
4 Implementação do software planejado.
5 Escrita e Entrega do Relatório Parcial- até 15/07/15 6 Realização de testes preliminares.
7 Correções do software.
8 Realização de testes, coleta e verificação dos dados. 9 Escrita e entrega do Relatório Final – até 30/11/2015
Tabela 2 - Cronograma proposto para cumprimento das metas. MESES
METAS MAR ABR MAI JUN JUL AGO SET OUT NOV
1 X X 2 X X X 3 X 4 X X X 5 X X 6 X X 7 X X 8 X X 9 X
17
ATIVIDADES REALIZADAS
Até o momento da entrega deste relatório, as atividades foram realizadas como previstas no Cronograma. A seguir, se encontram relatados os resultados específicos de cada meta de 1 a 6, mostradas na Tabela 1 e previstas no Cronograma da Tabela 2.
1- Pesquisa de trabalhos relacionados à simulação de vida artificial, envolvendo a criação de ecossistemas, criaturas, ou outras formas de vida artificial.
As pesquisas foram realizadas e com base nas mesmas foi possível observar a falta de pesquisas e de simulações relacionadas, produzidas no país. Grande parte do que foi encontrado são publicações, pesquisas e simulações internacionais, e poucas foram nacionais. Um resumo sobre os trabalhos relacionados pode ser visto no Capitulo 2 deste relatório.
2- Estudo de Algoritmos Evolutivos e pesquisa por trabalhos utilizando os mesmos em jogos.
Assim como na seção anterior, é possível observar mais sobre essa etapa no Capitulo 2 desse relatório, mas foi possível observar de um modo geral que são poucas as pesquisas e projetos que visam utilizar algoritmos evolutivos em jogos. Enquanto o estudo feito sobre algoritmos evolutivos pode ser observado no Anexo 5 com a criação de um algoritmo que simulasse populações e aplicasse crossover e mutação em cada geração com o intuito de obter um indivíduo ou solução perfeita.
3- Planejamento do ambiente, das criaturas, e do algoritmo evolutivo a ser implementado. O planejamento foi dividido em quatro partes, a primeira é a geração de terrenos aleatórios que é detalhada no Anexo 1, segunda é a geração de vegetação de forma aleatória e reprodução simples dessas plantas, lembrando que o tipo de terreno interfere no tipo de planta que pode nascer no local (mais detalhes da geração de vegetação podem ser vistos no Anexo 2). No Anexo 3 está descrito todo planejamento das criaturas, seus dados, funcionamento e ações, e o Anexo 4 mostra o planejamento do funcionamento do software, suas telas e possíveis ações. O planejamento das criaturas e do software em geral por ainda estar em fase de implementação e testes, está sujeito a possíveis alterações.
18 Toda parte já implementada do software pode ser vista nos Anexos 1 e 2 junto com seus devidos planejamentos. As criaturas ainda estão em fase de implementação e de testes que vem sendo realizados junto com a implementação para economizar tempo corrigindo problemas futuros.
5- Escrita e Entrega do Relatório Parcial- até 15/07/15 Refere-se ao relatório atual.
6- Realização de testes preliminares.
Como foi dito na seção 4, os testes preliminares estão sendo realizados em conjunto com a implementação, para economizar tempo não encontrando problemas posteriormente.
ATIVIDADES FUTURAS
Nesta seção, são apresentadas as atividades que ainda serão concluídas/realizadas: 4- Implementação do software planejado.
Até o momento, o software se encontra como explicado na Seção anterior e a parte da geração de terrenos e geração e reprodução de vegetação já se encontram implementadas, testadas e em funcionamento. Nos próximos meses, será finalizado o desenvolvimento e testes das criaturas, o AE e todas as funcionalidades do software.
5- Escrita e Entrega do Relatório Parcial- até 15/07/15 Concluída, com a entrega deste documento.
6- Realização de testes preliminares.
Os testes já iniciados irão continuar junto com a implementação do software, como previsto no cronograma original.
As atividades 7, 8 e 9 estão a ser realizadas como prevista originalmente conforme estabelecido no cronograma, como pode ser observado todas as atividades estão dentro do prazo conforme o determinado.
19
CONSIDERAÇÕES FINAIS
Este documento é um relatório referente ao projeto que propõem a criação de um ambiente para simulação de vida artificial, o desenvolvimento ainda está em fase de implementação e testes, mas já é possível observar parte do funcionamento que está saindo conforme o planejado. É de se esperar que o software fique pronto dentro do prazo estabelecido e que seus testes apresentem atividades e resultados previstos e não previstos, permitindo uma vasta quantidade de características e comportamentos para as criaturas que deverão evoluir a partir do AE. Após o termino desse projeto uma possível continuação prevê a implementação de diferentes tipos de simulação e até mesmo a aplicação de vida artificial na vegetação.
REFERÊNCIAS BIBLIOGRÁFICAS
ANDRADE, K. O.; SILVA, A. E. A.; CROCOMO, M. K. Um Algoritmo Evolutivo para a adaptação de NPCs em um jogo de ação. 2004.
BITTENCOURT, J. R. ; OSÓRIO, F. S. Motores de Jogos para Criação de Jogos Digitais -
Gráficos, Áudio, Interface, Rede, Inteligência Artificial e FísicaV ERI-MG. Anais...2006
CROCOMO, M. K.; SIMÕES, E. V. Um algoritmo evolutivo para aprendizado on-line em jogos eletr{ô}nicos. Proceedings of SBGames, Belo Horizonte, MG, p. 159–168, 2008. CROCOMO, M.; MIAZAKI, M.; SIMOES, E. Algoritmos Evolutivos para a produçao de
NPCs com Comportamentos AdaptativosAnais do Simpósio Brasileiro de Jogos. Anais...2007
INFORM, S. Memoria Sistemas Informáticos. 2012.
KLEIN, J. BREVE: A 3D Environment for the Simulation of Decentralized Systems and Artificial Life. Proceedings of the Eighth International Conference on Artificial Life, p. 329–334, 2003.
LANGTON, C. G. Artificial Life: An Overview. [s.l: s.n.].
MAES, P. Artificial life meets entertainment: lifelike autonomous agentsCommunications of the ACM, 1995.
MIT. MIT Press Journals - Artificial Life, 2015. Disponível em: <http://www.mitpressjournals.org/loi/artl>
NETTO, M. L.; RINALDI, L. C. A. Vida artificial: conceitos e aplicações mX SBAI – Simpósio Brasileiro de Automação Inteligente. Anais...São João del-Rei: 2011
20 OFRIA, C.; BRYSON, D. M.; WILKE, C. O. Avida: A software platform for research in computational evolutionary biology. In: Artificial Life Models in Software (Second
Edition). [s.l: s.n.]. p. 3–35.
POLICARPO, D.; URBANO, P.; LOUREIRO, T. Dynamic scripting applied to a First-Person Shooter. Information Systems and Technologies (CISTI), 2010 5th Iberian Conference
on, 2010.
POOLE, D. L.; MACKWORTH, A. K.; GOEBEL, R. Computational intelligence : a logical
approach. New York: Oxford University Press, 1998.
RUSSELL, S.; NORVIG, P. Artificial Intelligence: A Modern Approach, 3rd edition. [s.l: s.n.].
SEBRAE. O Panorama e a Evolução do Mercado de “Games” no Brasil.
SEBRAE. Economia Criativa - Brasil tem o maior mercado de games no mundo em
2012.
SHEA, R. et al. Cloud gaming: Architecture and performance. IEEE Network, v. 27, p. 16– 21, 2013.
SUSI, T.; JOHANNESSON, M.; BACKLUND, P. Serious games: An overview. 2007. UNITY. Unity - Game Engine. Disponível em: <http://unity3d.com/pt>. Acesso em: 18 jul. 2014.
ZUBEN, F. J. VON. Computação Evolutiva: Uma Abordagem Pragmática. Anais da I
Jornada de Estudos em Computação de Piracicaba e Região, p. 25–45, 2000.
21
Anexo 1
Planejamento da Geração de Mapas
Projeto: Construção de um Ambiente Virtual para Simulação de Aplicações de Vida Artificial
Orientada: Héllen Caroline Salvato Orientador: Marcio Kassouf Crocomo Instituição: IFSP – Campus Piracicaba
22
1. ESQUEMA PARA GERAR TERRENOS
Para uma melhor avaliação da capacidade de sobrevivência e evolução das criaturas geradas na simulação, sendo usados os mais variados cenários sem intervenção de fora da simulação, foi criado um sistema capaz de gerar mapas aleatoriamente. A ideia é gerar mapas com características e tipos de vegetações diferentes, para avaliar a capacidade de evolução em diferentes cenários.
O sistema basicamente escolhe os tipos de solos que serão gerados em cada posição do mapa, esses solos determinam quais plantas poderão nascer nessa área. Porém algumas restrições foram adotadas, alguns solos não podem ter como vizinhança outro tipo de solo.
Um esquema básico foi montado para mostrar o passo a passo, ou o algoritmo de geração de solo. O esquema é: 1º Escolher tipo de terreno, 2º Gerar objeto 3D na simulação, 3º Ir para a próxima posição (x, y), 4º Verificar mapas vizinhos, 5º Determinar possíveis valores (tipos de mapas) a ser gerado, 6º Escolher tipo de terreno dentro dos possíveis valores, 7º Gerar objeto 3D na simulação, 8º Repetir passos 3º - 8º até alcançar valor máximo de terrenos determinados. A Tabela 1 com os tipos de terrenos disponíveis inicialmente nessa simulação. Como nem todos os terrenos podem ser vizinhos uns dos outros, o grafo mostrado na Figura 2 ilustra as possibilidades de vizinhança entre os tipos de terrenos.
Tabela 1 – Tipos de terrenos disponíveis
Código Tipo de Mapa
1 Agua
2 Areia
3 Terra
4 Grama “Seca”
5 Grama “Molhada”
Figura 1 – Grafo de possíveis terrenos vizinhos, indicados por nós conectados.
A tabela abaixo ilustra as possibilidades de vizinhança como no grafo acima, assim podemos observar que as possibilidades são:
23 Tabela 2 – Possíveis terrenos vizinhos.
Tipo Vizinho A (1) Vizinho B (2) Vizinho C (3) Vizinho D (4) Vizinho E (5)
1 OK OK OK - OK
2 OK OK OK OK -
3 OK OK OK OK OK
4 - OK OK OK OK
5 OK - OK OK OK
Como podemos observar cada tipo de terreno forma um conjunto de vizinhos, 1 = {A,
B, C, E}, 2 = {A, B, C, D}, 3 = {A, B, C, D, E}, 4 = {B, C, D, E} e 5 = {A, C, D, E}.
A geração do primeiro mapa será escolhida a partir de um numero aleatório de 1 a 5 gerado pelo sistema. Na primeira linha e nos primeiros mapas de cada linha, os mapas só possuirão um vizinho, que é seu antecessor, dependendo do mesmo serão dadas as possíveis gerações na atual posição. Nas outras linhas teremos a presença de dois vizinhos, onde apenas os mapas em comum entre os dois poderão ser gerados na atual posição como é mostrado na Figura 2.
Figura 2 – Intersecção entre dois vizinhos, onde x são os possíveis mapas a serem gerados. Ou seja, A é um vizinho e B é outro e a intersecção entre eles resulta nos possíveis terrenos que podem ser gerados, na Figura 3 podemos observar melhor esse esquema, a mesma ilustra uma simulação onde o primeiro mapa gerado foi o mapa do tipo 4 (Grama “Seca”), onde seus possíveis vizinhos podem ser todos os números dentro do conjunto 4 (4 =
{B, C, D, E}). Após a geração desses vizinhos primários, podemos ver que a direita foi gerado
um 5, e á cima um 2, o próximo vizinho que será gerado no espaço que se encontra com esses dois só poderá ter como resultado um valor que tenha em comum entre eles, ou seja a intersecção entre 5 e 2. Onde 5 = {A1, C3, D4, E5} e 2 = {A1, B2, C3, D4}, X = 5 ∩ 2 (X é o conjunto de valores da intersecção entre 5 e 2), X = {A1, C3, D4}.
24 Figura 3 – Esquema de geração de terrenos vizinhos.
Assim são obtidos os números que representam o tipo de terreno criado se seguinte posição X e Y do mapa, após a verificação dos tipos de mapa que podem ser criados ali, um comando random (gerador de números aleatórios) será o responsável por escolher qual dos possíveis números serão gerados e assim que o numero é escolhido, seu respectivo modelo gráfico será gerado na posição atual.
2. MODELOS 3D DOS TERRENOS
Na Figura 4 podemos observar os modelos 3D que representam cada tipo de mapa que será gerado na simulação, criados no Unity 3D utilizando o terrain, um método para criação de terrenos no qual se escolhe e modela as elevações do mapa, textura entre outras coisas, facilitando e agilizando o trabalho de modelagem e texturização. Esse também oferece uma ferramenta para criar vegetações fixas de modo mais rápido, mas não foi usada essa ferramenta já que não é planejado que as vegetações sejam fixas nesse projeto.
25
3. CÓDIGO GERADO PARA A CRIAÇÃO DO MAPA
Para a geração do mapa, a partir de todo o esquema mostrado acima foi escrito o código de programação responsável pela criação dos mapas na simulação, a seguir podemos ver o código, que foi escrito no MonoDevelop, editor próprio do Unity 3D, na linguagem de programação C#.
using UnityEngine; using System.Collections;
public class GeradorTerrenosFinal : MonoBehaviour {
//Variaveis
public GameObject aguaMap01;
public GameObject areiaMap01;
public GameObject terraMap01;
public GameObject gSecaMap01;
public GameObject gMolhadaMap01;
System.Random gerar = new System.Random();
public int tipoMapaGerado;
public int i, j;
public int cimaMap;
public int anteriorMap;
public int quantMap = 0;
public int[] mapaCima = new int[16];
void Start () {
for(i = 0; i < 600; i=i+150){
for(j = 0; j < 600; j=j+150){ MapCriar();
mapaCima[quantMap] = tipoMapaGerado;
anteriorMap = tipoMapaGerado; quantMap++; } } }//FECHA START void Update () {}
public void MapCriar(){
if(quantMap == 0){ //Se Primeiro Mapa
tipoMapaGerado = gerar.Next(0,5);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
26
else if(quantMap > 0 && quantMap < 4){//Se Primeira Linha
if(anteriorMap == 0){
do{
tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 3);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(anteriorMap == 1){ tipoMapaGerado = gerar.Next(0,4); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(anteriorMap == 2){ tipoMapaGerado = gerar.Next(0,5); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(anteriorMap == 3){ tipoMapaGerado = gerar.Next(1,5); if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
27
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(anteriorMap == 4){ do{ tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 1); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
}//Fim do se primeira linha
else if( quantMap == 4 || quantMap == 8 || quantMap == 12){//Se primeiro mapa de cada linha quantMap = quantMap - 4; cimaMap = mapaCima[quantMap]; quantMap = quantMap + 4; if(cimaMap == 0){ do{ tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 3); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(cimaMap == 1){ tipoMapaGerado = gerar.Next(0,4); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
28
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(cimaMap == 2){ tipoMapaGerado = gerar.Next(0,5); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(cimaMap == 3){ tipoMapaGerado = gerar.Next(1,5); if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity); } } else if(cimaMap == 4){ do{ tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 1); if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
}// Fim Se primeiro mapa de cada linha
else if(quantMap > 4){//Se outros mapas
quantMap = quantMap - 4; cimaMap = mapaCima[quantMap]; quantMap = quantMap + 4;
29
do{
tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 3);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 0 && cimaMap == 1)||(anteriorMap == 1 && cimaMap == 0)){
tipoMapaGerado = gerar.Next(0,3);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 0 && cimaMap == 2)||(anteriorMap == 2 && cimaMap == 0)){
do{
tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 3);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 0 && cimaMap == 3)||(anteriorMap == 3 && cimaMap == 0)){
do{
tipoMapaGerado = gerar.Next(1,5); }while(tipoMapaGerado == 3);
if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
30
} }
else if((anteriorMap == 0 && cimaMap == 4)||(anteriorMap == 4 && cimaMap == 0)){
do{
tipoMapaGerado = gerar.Next(0,5);
}while((tipoMapaGerado == 1)||(tipoMapaGerado == 3));
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if(anteriorMap == 1 && cimaMap == 1){ tipoMapaGerado = gerar.Next(0,4);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 1 && cimaMap == 2)||(anteriorMap == 2 && cimaMap == 1)){
tipoMapaGerado = gerar.Next(0,4);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 1 && cimaMap == 3)||(anteriorMap == 3 && cimaMap == 1)){
tipoMapaGerado = gerar.Next(1,4);
if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
31
}
else if((anteriorMap == 1 && cimaMap == 4)||(anteriorMap == 4 && cimaMap == 1)){
do{
tipoMapaGerado = gerar.Next(0,4); }while(tipoMapaGerado == 1);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if(anteriorMap == 2 && cimaMap == 2){ tipoMapaGerado = gerar.Next(0,5);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 2 && cimaMap == 3)||(anteriorMap == 3 && cimaMap == 2)){
tipoMapaGerado = gerar.Next(1,5);
if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 2 && cimaMap == 4)||(anteriorMap == 4 && cimaMap == 2)){
do{
tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 1);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
32
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if(anteriorMap == 3 && cimaMap == 3){ tipoMapaGerado = gerar.Next(1,5);
if(tipoMapaGerado == 1){
Instantiate(areiaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if((anteriorMap == 3 && cimaMap == 4)||(anteriorMap == 4 && cimaMap == 3)){
tipoMapaGerado = gerar.Next(2,5);
if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
else if(anteriorMap == 4 && cimaMap == 4){
do{
tipoMapaGerado = gerar.Next(0,5); }while(tipoMapaGerado == 1);
if(tipoMapaGerado == 0){
Instantiate(aguaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 2){
Instantiate(terraMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 3){
Instantiate(gSecaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
}
else if(tipoMapaGerado == 4){
Instantiate(gMolhadaMap01, new Vector3((float)i, 0, (float)j), Quaternion.identity);
} }
}//Fim se outros Mapas
} }
33
Anexo 2
Planejamento da Geração de Vegetação
Projeto: Construção de um Ambiente Virtual para Simulação de Aplicações de Vida Artificial
Orientada: Héllen Caroline Salvato Orientador: Marcio Kassouf Crocomo Instituição: IFSP – Campus Piracicaba
34
1. ESQUEMA PARA GERAR A VEGETAÇÃO
Inicialmente para a geração de vegetação duas maneiras diferentes foram pensadas, a primeira: gerar as posições aleatoriamente, sorteando as posições X, Y e Z. Porém, foram apresentados problemas nesse modo de geração. O primeiro, com a posição em relação ao eixo Y, se um número diferente de zero fosse sorteado, haveria muitas árvores que ficariam flutuando, e muitas abaixo da terra, ao ficar a posição Y, arvores em posições de montanhas ou relevos ficariam embaixo dos mesmos. Para a resolução desse problema foi feita a criação de uma forma de colisão (um objeto que ao tocar outro o identifica) na parte inferior da planta que mostraria se a mesma está tendo uma colisão com a terra ou não, se não estivesse seria entendido que ela está muito abaixo da terra ou está flutuando.
Uma segunda maneira pensada, e a implementada até o momento na simulação, é utilizar a geração de “sementes” como a mostrada na Figura 1, que irão cair, colidindo com o solo, e se fixando na posição X, Y e Z no momento da colisão.
Figura 1 – Semente criada para geração de vegetação
Foi criado um código responsável por gerar sementes a partir de uma posição inicial, no qual dois comandos for (estruturas de repetição) encadeados, controlam as posições (X, Z) na qual as sementes são geradas, enquanto a posição Y é fixada em uma altura consideravelmente grande, para que essas sementes possam ter contato com topos de montanhas até lugares mais baixos. Essas, além de controlarem a posição na qual a planta é gerada, também escolhem o tipo de planta que é gerada no local, de acordo com as regras e com o tipo de solo. Ou seja, assim que a emulação é executada, os mapas são gerados, após isso, as sementes são geradas, e cada semente que colidi com os terrenos, rapidamente captura a posição atual da colisão, após isso identifica o tipo de mapa, e entra em um conjunto de estruturas de decisão que irá dizer quais tipos de plantas podem ser geradas naquele tipo de solo, então é escolhida aleatoriamente um tipo de planta entre os possíveis para a posição capturada.
1.1.Código para gerar sementes
using UnityEngine; using System.Collections;
35
public int a, b;
public GameObject sementePlanta;
void Start () {//INICIO FUNÇAO START
for(a = 0; a < 600; a = a + 30){
for(b = 0; b < 600; b = b + 30){
Instantiate(sementePlanta, new Vector3((float)a, 50, (float)b), Quaternion.identity);
} }
}//FIM FUNCAO START
void Update () {} }
1.2.Código presente nas sementes para gerar plantas
using UnityEngine; using System.Collections;
public class SementesArvores : MonoBehaviour {
public GameObject agua1P;
public GameObject agua2P;
public GameObject areia1M;
public GameObject areia2M;
public GameObject terra1P;
public GameObject terra1M;
public GameObject terra2M;
public GameObject terra1G;
public GameObject gSeca1P;
public GameObject gSeca1M;
public GameObject gSeca2M;
public GameObject gMolhada1P;
public GameObject gMolhada1M;
public GameObject gMolhada2M;
public GameObject gMolhada1G;
public GameObject gMolhada2G;
System.Random gerar = new System.Random();
public int numGerado;
public float xx; public float yy; public float zz; void Start () { } void Update () { }
void OnCollisionEnter(Collision a){ capturarPosicao(); if(yy < 0){ Destroy(gameObject); } else if(a.gameObject.tag == "1"){ numGerado = gerar.Next(0,2); if(numGerado == 0){
Instantiate(agua1P,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 1){
Instantiate(agua2P,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity); Destroy(gameObject); } } else if(a.gameObject.tag == "2"){ numGerado = gerar.Next(0,2); if(numGerado == 0){
36
Instantiate(areia1M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 1){
Instantiate(areia2M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity); Destroy(gameObject); } } else if(a.gameObject.tag == "3"){ numGerado = gerar.Next(0,4); if(numGerado == 0){
Instantiate(terra1P,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 1){
Instantiate(terra1M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 2){
Instantiate(terra2M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 3){
Instantiate(terra1G,new Vector3((float)xx, (float)yy, (float)zz),Quaternion.identity); Destroy(gameObject); } } else if(a.gameObject.tag == "4"){ numGerado = gerar.Next(0,3); if(numGerado == 0){
Instantiate(gSeca1P,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 1){
Instantiate(gSeca1M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if (numGerado == 2){
Instantiate(gSeca2M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity); Destroy(gameObject); } } else if(a.gameObject.tag == "5"){ numGerado = gerar.Next(0,5); if(numGerado == 0){
Instantiate(gMolhada1P,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 1){
Instantiate(gMolhada1M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 2){
Instantiate(gMolhada2M,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
else if(numGerado == 3){
Instantiate(gMolhada1G,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
37
else if(numGerado == 4){
Instantiate(gMolhada2G,new Vector3((float)xx, (float)yy, (float)zz), Quaternion.identity);
Destroy(gameObject); }
}
}//FIM DA FUNCAO DE COLISAO
public void capturarPosicao(){
//transform.position = new Vector3(0,0,0);
xx = transform.position.x; yy = transform.position.y; zz = transform.position.z; yy = yy - 1.8f; } }//FIM PROGRAMA
1.3.Reprodução das plantas
Durante a criação do projeto da simulação, foi definida a ideia de que as plantas influenciariam na sobrevivência e evolução das criaturas, e uma forma de fazer isso, é fazendo que cada vez que uma criatura se alimente de uma planta, a mesma suma, de forma rápida ou mais devagar dependendo do tamanho da planta e do tamanho da criatura. Com isso, é de se esperar que muitas criaturas grandes em um ambiente com poucas plantas venham a se extinguir. Por esse motivo, foi pensado em um modo de reprodução para as plantas, no qual dependendo dos animais e das plantas daquela região, a reprodução pode ser mais rápida ou não. Nesse modo, um tempo é estabelecido, cada vez que esse tempo se esgota, as plantas se reproduzem, gerando novas sementes a sua volta que irão gerar plantas semelhantes à mesma na posição que for capturada pelas sementes, lembrando que cada planta tem seu próprio “cronometro” que contará o tempo, esse começa a contar quando a planta é criada.
1.3.1. Código presente nas plantas geradas para reprodução
using UnityEngine; using System.Collections;
public class PlantaPp : MonoBehaviour {
public GameObject sementeSemente;
public float tempoParaReproducao;
private float tempoPassado;
public int quantidadeG;
public float vx;
public float vz;
public float novaP;
public int maisMenos;
System.Random gerar = new System.Random();
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update () {
tempoPassado = tempoPassado + Time.deltaTime;
//quantidadeG = gerar.Next(0,quantidadeG);
if(tempoPassado > tempoParaReproducao){
for(int a = 0; a < quantidadeG; a++){
//Capturo a posiçao da planta
vx = transform.position.x;
38 /* maisMenos = gerar.Next(0,2); if(maisMenos == 0){ novaP = gerar.Next(0,11); vx = vx - novaP; vz = vz - novaP; } else if (maisMenos == 1){ novaP = gerar.Next(0,11); vx = vx + novaP; vz = vz + novaP; } */ novaP=gerar.Next(0,21)-10; vx=vx + novaP; novaP=gerar.Next(0,21)-10; vz = vz + novaP;
Instantiate(sementeSemente,new Vector3((float)vx, 50, (float)vz), Quaternion.identity); } tempoPassado = 0; } } }
1.3.2. Código presente nas sementes reproduzidas que geram um tipo especifica de planta
using UnityEngine; using System.Collections;
public class SementeSs : MonoBehaviour {
//tipo de solo true para valido e false para nao valido
public bool solo1;
public bool solo2;
public bool solo3;
public bool solo4;
public bool solo5;
private float pxx;
private float pyy;
private float pzz;
public GameObject muda;
void Start () { }
// Update is called once per frame
void Update () { }
void OnCollisionEnter(Collision a){ capturaDePosicao();
if(pyy > 0){
if((a.gameObject.tag == "1")||(a.gameObject.tag == "2")||(a.gameObject.tag ==
"3")||(a.gameObject.tag == "4")||(a.gameObject.tag == "5")){ capturaDePosicao();
if(a.gameObject.tag == "1"){
if(solo1 == true){
Instantiate(muda,new Vector3((float)pxx, (float)pyy, (float)pzz), Quaternion.identity);
Destroy(gameObject); }
else if(solo1 == false){ Destroy(gameObject); }
}
39
if(solo2 == true){
Instantiate(muda,new Vector3((float)pxx, (float)pyy, (float)pzz), Quaternion.identity);
Destroy(gameObject); }
else if(solo2 == false){ Destroy(gameObject); }
}
if(a.gameObject.tag == "3"){
if(solo3 == true){
Instantiate(muda,new Vector3((float)pxx, (float)pyy, (float)pzz), Quaternion.identity);
Destroy(gameObject); }
else if(solo3 == false){ Destroy(gameObject); }
}
if(a.gameObject.tag == "4"){
if(solo4 == true){
Instantiate(muda,new Vector3((float)pxx, (float)pyy, (float)pzz), Quaternion.identity);
Destroy(gameObject); }
else if(solo4 == false){ Destroy(gameObject); }
}
if(a.gameObject.tag == "5"){
if(solo5 == true){
Instantiate(muda,new Vector3((float)pxx, (float)pyy, (float)pzz), Quaternion.identity);
Destroy(gameObject); }
else if(solo5 == false){ Destroy(gameObject); } } } else{ Destroy(gameObject); } } capturaDePosicao(); if(pyy < 0){ Destroy(gameObject); } }
public void capturaDePosicao(){ pxx = transform.position.x; pyy = transform.position.y; pzz = transform.position.z; pyy = pyy - 1.8f; } }
Os modelos 3D de plantas utilizadas são da própria Asset Store do Unity 3D, disponibilizados gratuitamente. Seus tamanhos e colisões foram ajustados e, assim como os mapas, cada planta recebe uma tag diferente que serve para sua identificação quando entra em contato com uma criatura. É possível observar na Figura 2 alguns modelos de plantas usados e na Figura 3 a geração de terrenos e plantas em funcionamento dentro da simulação.
40 Figura 2 – Modelos de plantas 3D usadas na simulação
41
Anexo 3
Planejamento da Geração e Funcionamento das
Criaturas
Projeto: Construção de um Ambiente Virtual para Simulação de Aplicações de Vida Artificial
Orientada: Héllen Caroline Salvato Orientador: Marcio Kassouf Crocomo Instituição: IFSP – Campus Piracicaba