Uma estrutura de dados é uma forma particular de armazenar e organizar dados em um computador de modo que possam ser usados de forma eficiente na busca e na modificação destes dados. Diferentes estrutura de dados devem ser utilizadas para para diferentes tipos de aplicações. As estrutura de dados são chamadas de tipos de dados compostos que se dividem em homogêneos e heterogêneos. As Estruturas de dados homogêneas são conjuntos de dados formados por tipos de dados primitivos iguais, enquanto as heterogêneas são formadas por dados primitivos diferentes em uma mesma estrutura. A escolha de uma estrutura de dados apropriada pode transformar um problema complexo em uma solução relativamente simples.
Grafo
A teoria dos grafos é um ramo da matemática que estuda relações entre objetos de um determinado conjunto. São empregadas estruturas chamadas de grafos, G(V,E), onde V é um conjunto não vazio de objetos chamados de vértices e E um subconjunto de pares não ordenados V, chamados de arestas. Dependendo da aplicação essas arestas podem ou não ter direção, podem ou não ser permitido que essas arestas conecte um vértice a ele mesmo. Também é possível que as arestas tenham um peso associado.
Um grafo direcionado consiste de:
- Um conjunto V de vértices
- Um conjunto E de arestas
- Mapas s, t : E→V, onde s(e) é a fonte e t(e) é o alvo desta aresta direcionada e.
Um grafo não direcionado consiste de:
- Um conjunto V de vértices
- Um conjunto E de arestas
- Uma função w: E→P(V) que associa cada aresta a um subconjunto de dois ou de um elemento V interpretado como os pontos terminais das arestas.
Um grafo com pesos utiliza uma função adicional E → R que associa um valor a cada aresta, o que pode ser considerado seu custo; tais grafos surgem em problemas como pathfinding ou ainda problemas como caixeiro viajante.
Comumente os grafos são representados graficamente da seguinte forma: São utilizados círculos para cada vértice, e, para cada aresta é desenhado um arco conectado às suas extremidades. Caso um grafo seja direcionado, o sentido é indicado utilizando uma seta. Há diversas formas de armazenar na memória de um grafo. A estrutura de dados dependerá tanto da estrutura do grafo a ser armazenado, assim como do algoritmo que irá manipulá-lo. É possível dividir entre as estruturas do tipo lista e do tipo matriz, porém em aplicações reais o ideal é a combinação de ambas estruturas de dados. Estruturas do tipo lista são frequentemente usadas em grafos esparsos, grafos que possuem um pequeno número de arestas em relação ao número de vértices, por exigirem uma quantidade menor do uso de memória. Estruturas do tipo matriz fornecem um acesso rápido, mas podem consumir uma grande quantidade de memória.
Árvores & Árvores Binárias
A árvore, na teoria dos grafos, é um grafo conexo e acíclico, ou seja, existe um caminho entre quaisquer vértices e não possui ciclos. Toda árvore é um grafo, mas nem todo grafo é uma árvore. Conceitualmente diferente das listas, em que todos os dados se encontram em uma sequência, nas árvores os dados estão dispostos de forma hierárquica, seus elementos se encontram “acima” ou “abaixo” de outros elementos da árvore.
Seja G um grafo, G é uma árvore se satisfaz as seguintes condições:
- G é conexo e há exatamente um caminho entre dois vértices quaisquer.
- G é acíclico, e um simples ciclo é formado se qualquer aresta for adicionada.
- G é conexo, e deixará de ser conexo se qualquer aresta for removida de G
- G é conexo, acíclico e tem n-1 arestas
São estruturas eficientes e simples de tratamentos se comparada com os grafos tradicionais.
Formalmente temos:
- Definimos uma árvore T como um conjunto finito de zero ou mais nós tal que:
- Se o número de nodos = 0, temos uma árvore vazia, ou
- Se o número de novos > 0:
- Existe 1 nó especialmente denominado de raiz de T
- Os nós restantes formam m >= 0 conjuntos disjuntos p1, p2, … , pm e cada um desses conjuntos é uma árvore em si, chamada de subárvore da raiz de T, ou simplesmente subárvore.
O número máximo de filhos em um nodo é chamado de ordem da árvore. Uma árvore binária é aquela de ordem 2, portanto, cada elemento possui no máximo 2 filhos.
Máquina de Estados
Uma máquina de estados pode ser definida da seguinte forma: “A finite state machine is a device, or a model of a device, which has a finite number of states it can be in at any given time and can operate on input to either make transitions from one state to another or to cause an output or action to take place. A finite state machine can only be in one state at any moment in time” - Mat Buckland “Programming Game AI by Example”
As máquinas de estados finitas ( FSMs - finite state machines) são uma das primeiras escolhas quando o objetivo é dar uma ilusão de inteligência a um agente. A idéia final de uma máquina de estados finita é a decomposição do comportamento de um agente em estados e simples.
A utilização de máquinas de estado trazem muitas vantagens ao longo do desenvolvimento de um jogo. São fáceis e simples de codificar. Existem diversas maneiras de se programar uma máquina de estado finita e quase sempre são simples de serem implementadas. São fáceis de serem debugadas. Como cada estado do agente é isolado e quebrado em partes menores e simples, se o agente começar a ter um comportamento inesperado é fácil de localizar a fonte do erro. Elas custam poucos recursos computacionais. São intuitivas, o ser humano naturalmente pensa dessa forma. Por exemplo, o dia de uma pessoa pode ser descrito dessa forma. São flexíveis, um agente pode simplesmente ser ajustado pelo programador para ter o comportamento esperado pelo game designer.
Os Fantasmas em Pac-Man
Cada um dos fantasmas em Pac-Man utiliza um algoritmo diferente para determinar como irá se movimentar ao longo do labirinto. Dessa forma, os fantasmas Blinky, Pinky, Inky e Clyde tem uma “personalidade” diferente entre si.
Quando o jogador inicia o jogo, ele não é imediatamente atacado pelos quatro fantasmas, já que apenas um dos fantasmas está dentro do labirinto. Os outros fantasmas estão contidos dentro de uma área pequena no centro do labirinto, comumente chamada de “ghost house”. Além desse momento inicial, as únicas formas dos fantasmas voltarem para essa área é se forem comidos pelo Pac-Man ou se o Pac-Man morrer. Assim que um fantasma sai dessa ghost house eles vão para a esquerda. Entretanto, devido ao seu comportamento, os fantasmas podem mudar de direção de forma imediata.
As condições necessárias para um fantasma sair dessa ghost house são bastante complexas, leia o artigo nos links recomendados para saber mais sobre. O jogo Pac-man é utiliza tiles com medidas de 8 x 8 e sua tela tem como resolução 224 x 288. Dessa forma o tabuleiro tem um total de 28 x 36 tiles.
Para compreender o comportamento dos fantasmas é necessário entender o conceito de “tile alvo”. Na maior parte do tempo, cada fantasma tem um tile alvo que deseja chegar e o seu comportamento determina como ele tentará chegar nesse tile considerando o atual. Observe que todos os fantasmas utilizam exatamente o mesmo algoritmo para chegar de um tile até o tile alvo, a diferença entre eles é como eles selecionam esse tile alvo. Destaca-se também que não existem restrições considerando que esse tile alvo seja realmente alcançável. Por conta dessa característica, é bastante comum que os fantasmas escolham realmente tiles inacessíveis.
Os fantasmas utilizam três possíveis modos: Chase, Scatter ou Frightened. O modo “normal” dos fantasmas é tentar perseguir o Pac-Man, com o modo Chase. Enquanto no modo Chase, todos os fantasmas utilizam a posição atual do Pac-Man como um fator para selecionar o tile alvo. No modo Scatter, cada um dos fantasmas tem um tile alvo pré-determinado, esse tile é simplesmente um dos cantos do tabuleiro. Isso acaba causando que os fantasmas se dispersem ao longo do tabuleiro. No modo Frightened os fantasmas se comportam de maneira única. Eles determinam de forma pseudo-randômica para que lado irão se mover toda vez que encontram uma interseção. Nesse modo os fantasmas são mais lentos e podem serem comidos pelo Pac-Man. As mudanças entre o modo Chase e Scatter ocorrem em um tempo fixo, o que causa um efeito de “wave” que é descrito por Toru Iwatani. “To give the game some tension, I wanted the monsters to surround Pac Man at some stage of the game. But I felt it would be too stressful for a human being like Pac Man to be continually surrounded and hunted down. So I created the monsters’ invasions to come in waves. They’d attack and then they’d retreat. As time went by they would regroup, attack, and disperse again. It seemed more natural than having constant attack.” - Toru Iwatani, Pac-Man creator
O timer utilizado para as mudanças entre o modo Chase e Scatter é reiniciado ao início de cada level ou quando o Pac-Man morre. O timer também é pausado enquanto os fantasmas estão no modo Frightened. Quando o modo Frightened acaba, os fantasmas voltam ao seu estado anterior e a contagem do tempo reinicia onde foi deixada. No início da fase os fantasmas iniciam no modo Scatter e então existem 4 waves alternando entre os modos Scatter/Chase até que os fantasmas fiquem no modo Chase de forma indefinida. Para o primeiro nível as durações são:
- Scatter por 7 segundos, então Chase por 20 segundos
- Scatter por 7 segundos, então Chase por 20 segundos
- Scatter por 5 segundos, então Chase por 20 segundos
- Scatter por 5 segundos, então Chase permanentemente.
Os fantasmas apenas planejam apenas um passo no futuro. Assim que um fantasma entra em um tile, ele observa a frente o tile e toma a decisão sobre para onde ele irá quando chegar nesse tile. Existe uma restrição bastante importante nessa decisão: Um fantasma nunca escolherá voltar, portanto sempre que um fantasma entrar em um tile com apenas duas saídas, ele sempre irá continuar na mesma direção. A única exceção a esta regra é que sempre que um fantasma muda de estado Chase ou Scatter, ele é forçado a reverter sua direção assim que entra no próximo tile. O objetivo dessa decisão é notificar o jogador quando os fantasmas mudam de modo, já que é a única forma de um fantasma mudar de direção. Essa regra vale inclusive para os fantasmas presos da ghost house. Assim quando um fantasma entra no labirinto e já ocorreu uma mudança de estado, ele automaticamente já entra com o comando de “mude de direção assim que você puder”. Devido a esse comportamento uma decisão só é necessária quando o tile adjacente é uma interseção.
Quando uma decisão de qual direção deve ser tomada é utilizada a distância em linha reta entre os tiles adjacentes o tile alvo. Dentre as opções, o tile que tiver a menor distância é escolhido. Se existir duas ou mais opções possíveis em que a distância é igual, a decisão é tomada da seguindo a seguinte prioridade : cima, esquerda e baixo. A decisão de ir para a direita nunca é tomada já que sempre existe uma opção com uma prioridade maior. Como essa decisão só considera o tile imediatamente adjacente, o fantasma pode acabar escolhendo um caminho mais longo.
Um último caso especial deve ser considerado, existem 4 interseções em que os fantasmas nunca podem ir para cima. Portanto, se um fantasma entrar nessas interseções ele sempre seguirá para o lado oposto. Note que essa restrição não se aplica se os fantasmas estiverem no modo Frightened já que a tomada de decisão é aleatória nesse modo. O objetivo dessa regra é que caso o Pac-man esteja sendo perseguido pelos fantasmas de forma muito próxima, é possível ganhar uma certa distância já que os fantasmas são obrigados a tomar a rota mais longa.
Cada um dos fantasmas presentes em Pac-Man tem uma personalidade diferente que é dada pelo método que ele seleciona o tile alvo no modo Chase e Scatter. “This is the heart of the game. I wanted each ghostly enemy to have a specific character and its own particular movements, so they weren’t all just chasing after Pac Man in single file, which would have been tiresome and flat.” - Toru Iwatani, Pac-Man creator
No modo Scatter cada um dos fantasma tem um tile alvo pré-determinado. Quando ativado o modo Scatter, cada um dos fantasmas tenta chegar em sua “casa” usando o método de busca de caminho apresentado. Entretanto, as casas são inacessíveis e como os fantasmas não podem parar de se mover ou ainda reverter a direção, eles são forçados a “passar” do ponto mais próximo. Isso acaba formando eventualmente um loop. Se os fantasmas ficassem travados no modo Scatter eles ficariam executando esse loop indefinidamente.
Na prática, a duração do modo Scatter é tão curta que raramente os fantasmas tem tempo de completar o loop antes de ser revertido ao modo Chase.
Blinky - O fantasma vermelho
O fantasma vermelho com o nome “Blinky” é descrito como tendo uma personalidade de perseguidor. Ele é o primeiro fantasma a sair de dentro da “ghost house” e sai imediatamente assim que o jogo começa. No modo Chase, Blinky seleciona o tile em que o Pac-Man efetivamente está. Isso garante que o Blinky quase sempre irá seguir diretamente o Pac-Man, exceto quando o path-finding acaba escolhendo um caminho ineficiente.
A forma como o Blinky se desloca é bastante simples, entretanto existem dois aspectos que devem ser considerados. O primeiro é que a velocidade de Blinky aumenta em 5% em dois pontos pré-determinados em cada nível dependendo da quantidade de pontos sobrando.
Além disso o seu comportamento no modo Scatter também é alterado. A mudança no modo Scatter é bastante significante já que mesmo nesse modo Blinky continuará escolhendo como tile alvo o tile em que o Pac-Man está. Ou seja, dependendo de pontos na fase, Blinky efetivamente continuará no modo Chase de forma permanente. Apesar dele continuar perseguindo o Pac-Man de forma permanente quando nesse estado, ele ainda é obrigado a reverter sua rota quando ocorre uma mudança de estado no jogo. Quando o Blinky está nesse estado ele também é chamado de “Cruise Elroy”. Se o Pac-Man morre enquanto o Blinky está no modo Cruise Elroy, Blinky volta ao comportamento normal temporariamente, mas retorna ao modo Elroy assim que todos os outros fantasmas estiverem fora da ghost house.
Pinky - O fantasma Rosa
O fantasma rosa é conhecido como Pinky e em japonês sua personalidade é descrita como “atacar de tocaia”. Pinky escolhe seu tile alvo considerando a direção para onde Pac-Man está e sua orientação. Para determinar o tile alvo é verificada a posição atual do Pac-Man e então são selecionados 4 tiles a frente do Pac-Man.
Entretanto devido a um bug, quando o Pac-Man está olhando para cima o tile alvo selecionado é o 4 para cima e 4 para a esquerda.
Por conta do comportamento do Pinky é bastante comum utilizar uma estratégia com o objetivo de enganar o fantasma. Como o tile alvo do Pinky é sempre 4 tiles a frente do Pac-Man, se o Pac-Man estiver virado diretamente para ele, Pinky escolherá um tile que está atrás dele. Isso forçará ao Pinky escolher mudar sua rota em qualquer interseção disponível e voltar para esse tile alvo.
Inky - O fantasma Azul
O fantasma azul recebe o apelido de “Inky” e fica dentro da ghost house até que o Pac-Man tenha comido pelo menos 30 pontos. A descrição da personalidade do Inky diz que ele é tímido e é bastante difícil prever o tile alvo do Inky. É difícil prever o tile alvo do Inky no modo Chase, pois ele utiliza tanto a informação da posição e orientação do Pac-Man quanto a posição do Blinky. Para determinar o tile alvo do Inky é necessário selecionar 2 tiles a frente do Pac-Man, a partir disso imagine um vetor considerando a posição do Blinky entre esses 2 tiles. Em seguida, dobre o tamanho deste vetor, este será o tile selecionado pelo Inky.
Devido ao modo como o Inky seleciona seu tile alvo, o comportamento do Inky varia bastante quanto está longe do Pac-Man. Porém, se o Blinky perseguindo bastante próximo, Inky também irá perseguir o Pac-Man. Observe que pelo mesmo bug do Pinky, se o Pac-Man estiver virado para cima, Inky utilizará o tile que estiver 2 tiles para cima e 2 tiles para a esquerda do Pac-Man como referência inicial.
Clyde - O fantasma Laranja
O fantasma restante é o laranja conhecido como Clyde. Sua personalidade é descrita em japonês “fingindo ignorância”. Existem duas formas que Clyde pode decidir seu tile alvo dependendo de sua proximidade com o Pac-Man. Se Clyde estiver longe do Pac-Man, com uma distância maior que 8 tiles, então ele utiliza a posição atual do Pac-Man como tile alvo. Caso contrário, é utilizado o mesmo ponto utilizado no modo Scatter.
Devido a combinação destes dois métodos, Clyde costuma alternar entre vir diretamente atrás do Pac-Man e quando chega próximo “muda de idéia” e tenta seguir para o seu canto. Se de alguma forma, o Pac-Man se posicionar estaticamente neste ponto do mapa, Clyde irá fazer permanentemente esse loop em forma T. Além disso, exceto se jogador estiver no canto inferior esquerdo do jogo é possível evitar Clyde completamente, bastando deixar sua “rota de fuga” para o seu canto aberta.
。・:*:・゚★,。・:*:・゚☆ 。・:*:・゚★,。・:*:・゚☆ 。・:*:
Contact Info:
E-mail: pamabeltrani@gmail.com
Discord: pamnawi