Você está na página 1de 44

F ELIPE DE O LIVEIRA R IOS

Grades Regulares em Jogos Digitais


História, Geometria e Algoritmos

Trabalho de Conclusão apresentado à Coordenação do


Curso de Ciência da Computação do Instituto de Infor-
mática da Universidade Federal de Goiás, como requisito
parcial para obtenção do título de Bacharel em Ciência da
Computação.
Área de concentração: Desenvolvimento de Jogos, Geo-
metria Analítica.
Orientador: Prof. Leonardo Alves

Goiânia, GO
1
Agradecimentos

“Agradeço a meus pais, sem os quais não estaria aqui e a Deus pelas oportuni-
dades; a meus amigos, que estiveram sempre presentes, me dando forças quando mais
precisei; aos professores que me ajudaram e me guiaram pelo caminho.
Agradeço a todos os que me incentivaram a ir em frente, pois foram os que me
puxaram para frente e me ajudaram a continuar. Agradeço também a todos os que me
incentivaram a parar e fizeram duvidar de mim; esses foram os que me empurraram pelas
costas e fizeram me esforçar para provar que estavam errados.”
Sumário

Lista de Figuras 4

Lista de Códigos de Programas 5

1 Introdução 9

2 Tabuleiros, Padrões e Grades 11

3 Análise Geométrica 14
3.1 Tesselações Monoédricas Regulares Aresta-a-Aresta 14
3.2 Considerações Sobre Polígonos Regulares 16

4 Grades Triangulares 20
4.1 Estruturas de Dados para Grades Triangulares 25

5 Grades Quadradas 28
5.1 Estruturas de Dados para Grades Quadradas 31

6 Grades Hexagonais 33
6.1 Estruturas de Dados para Grades Hexagonais 38

7 Considerações Finais 40

Referências Bibliográficas 43
Lista de Figuras

3.1 Relação entre o baricentro e dois vértices consecutivos de um polígono


regular. 17
3.2 Triângulo retângulo criado usando a bissetriz do ângulo θ. 17

4.1 Grade triangular construída em torno do vétice O. 20


4.2 Uso de três eixos na grade triangular. 21
4.3 Células adjacentes na grade triangular, sob o sistema de coordenadas
cúbicas. 23
4.4 Representação visual da estrutura de dados sugerida. 25
4.5 Arestas na estrutura de dados sugerida. As arestas tracejadas correspon-
dem às arestas que estariam armazenadas em uma célula vizinha. 26
4.6 Vértices na estrutura de dados sugerida. Os vértices representados por
um círculo vazio correspondem aos vértices que estariam armazenados
em uma célula vizinha. 26

5.1 Grade quadrada que tem como centro o ponto O, baricentro do quadrdado
(0, 0), e eixos da grade. 28
5.2 Células adjacentes à célula (i, j). 30
5.3 Vértices e arestas da célula (i, j). As arestas tracejadas e círculos repre-
sentam as arestas e vértices associados a outras células. 32

6.1 Grade hexagonal com a célula central O. A linha tracejada mostra a


variação no das coordenadas do centro das células no eixo horizontal. 33
6.2 Grade hexagonal com a célula central O. A linha tracejada mostra a
variação no das coordenadas do centro das células no eixo horizontal. 34
6.3 Vizinhança de uma célula (i, j, k). 36
6.4 Arestas de uma célula (i, j). As linhas tracejadas correspondem às ares-
tas cujos dados estarão associados a células vizinhas. 38
6.5 Vértices de uma célula (i, j). As linhas tracejadas correspondem às
arestas cujos dados estarão associados a células vizinhas. 39

7.1 Grades triangular e hexagonal sobrepostas, com suas origens sobrepostas. 41


Lista de Códigos de Programas

4.1 Implementação em python do resultado (4-4). 23


4.2 Implementação em Python da adjacência de células na grade triangular. 24
4.3 Implementação em Python da distância entre duas células na grade trian-
gular. 24
5.1 Implementação em Python do resultado 5-1. 29
5.2 Implementação em Python da adjacência de células na grade quadrada. 30
5.3 Implementação em Python da distância entre duas células na grade qua-
drada. 31
6.1 Implementação em Python do resultado 6-4. 35
6.2 Implementação em Python da adjacência de células na grade hexagonal. 36
6.3 Implementação em Python da distância entre duas células na grade hexa-
gonal. 37
"Science isn’t about WHY. It’s about WHY NOT. Why is so much of our
science dangerous? Why not marry safe science if you love it so much?"

Cave Johnson,
Portal 2.
7

Resumo

. Grades Regulares em Jogos Digitais. Goiânia, GO, 1. 44p. Relatório de


Graduação. Instituto de Informática, Universidade Federal de Goiás.

Em grande parte dos jogos digitais nos quais existe um tabuleiro, os tabuleiros são
restritos por grades em diversos formatos, sendo a grade hexagonal e a grade quadrada os
mais comuns. Enquanto existem diversas publicações, de diversos autores e em diversos
formatos acerca de grades e seus algoritmos, são raras as publicações que tratam de mais
de um tipo de grade, com suas propriedades geométricas e algoritmos simplificados. Este
artigo procura centralizar a informação básica acerca de grades como tabuleiros digitais,
seus algoritmos e suas propriedades geométricas, e oferecer um ponto de partida para
desenvolvedores de jogos.

Palavras–chave
Grade, Tabuleiro, Jogos Digitais, Geometria Analítica, Desenvolvimento de
Jogos
8

Abstract

. Grades Regulares em Jogos Digitais. Goiânia, GO, 1. 44p. Relatório de


Graduação. Instituto de Informática, Universidade Federal de Goiás.

In most digital games in which there is a board, the boards are restricted by grids in
different formats, with the hexagonal grid and the square grid being the most common.
While there are several publications, by different authors and in different formats about
grids and their algorithms, papers about more than one type of grid, with their geometric
properties and simplified algorithms, are rare. This article seeks to centralize basic
information about grids used as digital boards, their algorithms and their geometric
properties, and provide a starting point for game developers.

Keywords
Grid, Board, Digital Games, Analytical Geometry, Game Development
CAPÍTULO 1
Introdução

No decorrer da história dos jogos digitais, a presença de grades apresenta uma


variação recorrente em sua função, ora atuando como uma mecânica básica dos jogos,
planejada como parte do design do jogo, ora servindo como forma de reduzir o impacto
de gráficos melhorados na performance dos jogos, ora servindo a ambos os propósitos.
Os primeiros jogos digitais não passavam de versões digitais de jogos de tabuleiro já
existentes, como damas, jogo da velha e xadrez. Assim, era natural que esses primeiros
exemplares de jogos digitais apresentassem grades, que modelavam os tabuleiros com
relativa simplicidade.
Com o surgimento do que são chamados os primeiros video-games[18], Tennis
for Two, de 1958, e Spacewar!, iniciado em 1961 e completado em 1962, demonstrou-se
que era possível implementar jogos com visual interativo em uma tela. Esses primeiros
exemplares foram desenvolvidos em máquinas com monitores capazes de exibir apenas
duas cores e não eram limitados por grades. Dito isso, a complexidade dos cálculos de
ponto-flutuante necessários para o Spacewar! impediram que fosse desenvolvida uma IA
rudimentar que jogasse contra os jogadores na versão original, levando o jogo a necessitar
de dois jogadores para ser jogado[1].
Em 1966, Ralph Baer publicou um artigo de quatro páginas, contendo suas idéias
a respeito da possibilidade de usar aparelhos de TV comuns para jogos interativos. Alguns
anos depois, em 1972, o mesmo Ralph Baer se tornou o responsável pelo lançamento do
Odyssey, o primeiro sistema de video-games para o lar. Três anos à frente, o mercado de
jogos arcade já havia passado por seu grande boom, e surgia o Indy 800, publicado pela
Kee Games, que já fazia uso de uma TV colorida (além de permitir até 8 jogadores, com
seus volantes e pedais).
Eventualmente, com a popularização de jogos com visuais que contassem com
mais de uma única cor na tela e desenhos rudimentares, as grades ressurgem como uma
forma de encaixar imagens umas com as outras, de modo a criar um mundo de jogo
visualmente agradável ao custo de pouco poder de processamento através da combinação
de alguns “blocos de construção”. A essa técnica, deu-se o nome de tiling, do verbo em
inglês to tile, “azulejar”, por conta da idéia de utilizar imagens menores como azulejos
10

para construir uma imagem maior através de sua combinação, como a criação de um
mosaico ou o assentamento de azulejos em uma construção. No decorrer deste texto,
tiling estará traduzido como “tesselação”, levando em consideração a definição do termo
por Grunbaum e Shephard.
Embora o poder de processamento dos computadores, consoles em geral e
dispositivos móveis tenha crescido muito, e não seja estritamente necessário o uso
de tiling para otimização (mesmo nos dispositivos móveis), seu uso ainda é muito
comum pelas facilidades geradas no desenvolvimento. De mesmo modo, as grades como
representações de tabuleiros, especialmente em jogos de estratégia, continuam sendo
amplamente utilizadas como forma de restringir o posicionamento de objetos no mundo
do jogo, como nas séries Civilization, The Sims, Age Of Empires, Minecraft e Terraria.
Este texto se propõe a explorar as origens dos tabuleiros e grades de uma pers-
pectiva histórica, suas propriedades geométricas e exemplos de implementação em python
para o uso de grades como tabuleiros em jogos digitais de forma relativamente simples
e concisa. A linguagem de programação Python foi escolhida para a implementação por
sua popularidade e legibilidade, permitindo que os exemplos sejam entendidos de forma
prática e possam ser facilmente reproduzidos em outras linguagens de programação.
CAPÍTULO 2
Tabuleiros, Padrões e Grades

A presença de jogos de tabuleiro não é, de forma alguma, um fenômeno recente.


Mardon Et. Al., em The History of Board Games[12] afirma que foram encontradas placas
de pedra com entalhes semelhantes a tabuleiros de mancala modernos datados de 6000
a.C.; o tabuleiro mais antigo conhecido, mas não necessariamente o mais antigo existente,
e antes mesmo dos tabuleiros de pedra, os povos primitivos certamente já haviam criado
formas ainda mais antigas de entretenimento (usando ossos como dados, por exemplo).
Achados arqueológicos datados de 3500 a.C. provam a existência de tabuleiros de Semet
no antigo Egito, e representações visuais do jogo mais antigas já foram encontradas. Há
também evidências de que jogos de tabuleiro eram comuns no império romano (embora
jogos com dados fossem mais populares).
Certos jogos de tabuleiro, como xadrez, apesar de sua idade (século 5 a.C.,
Índia), mantiveram sua relevância através dos séculos. Segundo Donovan[4], Turing, em
1947, desenvolveu o primeiro programa de computador que implmentava o jogo, embora
os computadores da época não fossem capazes de executá-lo, e o criador nunca tenha
chegado a presenciar sua execução (mas foi capaz de “testá-lo”, jogando uma partida de
xadrez com seu colega enquanto seguia os passos da execução do programa). Portanto, é
seguro afirmar que os primeiros jogos digitais não passavam de versões digitais de jogos
analógicos, e possívelmente de tabuleiro, e é provável que o jogo da velha e damas tenham
sido implementados antes de xadrez por serem menos complexos.
De fato, em 1952, na Universidade de Cambridge, foi implementada uma versão
funcional do jogo da velha no Electronic Delay Storage Automated Calculator (EDSAC),
o primeiro computador com memória que permitia leitura e escrita, construído em 1949
pelo professor Maurice Wilkes. A autoria do jogo recai sobre Alexander Douglas, aluno
de Wilkes, que desenvolveu o programa como parte de sua tese de PHD sobre interação
humano-computador, datada do ano de 1952. Foi apenas à partir do surgimento de Tennis
For Two, em 1958, e Spacewar!, em 1962, que a indústria de jogos começou a atrair a
atenção do público geral (e não apenas de acadêmicos), e em 1972, com o lançamento do
Odyssey, o mercado começava a se abrir para o segmento.
Tentar encontrar com exatidão o primeiro jogo digital criado (programado e
12

efetivamente executado) certamente é uma tarefa árdua, dado que, mesmo na época em
que vieram a público os primeiros jogos digitais, computadores ainda eram grandes e
caros, e só podiam ser ultilizados de forma compartilhada e em ambiente acadêmico ou
em grandes empresas, onde qualquer indíviduo que ousasse fazer uso de equipamentos tão
caros para fins de entretenimento provavelmente não viria a público anunciar sua criação
por medo de represálias por parte da instituição à qual pertencesse o mainframe.
Uma característica recorrente em todos os tabuleiros conhecidos para jogos é
a presença de um padrão. Grünbaun Et. Al, em Tilings and patterns[8] se dedica não
apenas à análise geométrica dos padrões criados por diversas civilizações através da
história, mas também a uma exploração histórica desses padrões nas mais diversas formas:
tapeçaria, pinturas, mosaicos em pisos, paredes e tetos, aplicados em cestas, tecidos,
armas e utensílios diversos. Os padrões, descritos como “repetições de uma ’figura’ [ou
mais] no plano de forma ’regular’[...]” (tradução livre), são encontrados tanto na natureza
(o que fez com que grande parte dos estudos acerca do tema tenham sido conduzidos por
cristalógrafos) quanto em estruturas construídas por mãos humanas.
Por suas características geométricas, amplamente exploradas na obra supraci-
tada, vários dos padrões encontrados em diversas construções de civilizações distintas, de
épocas distintas e sem qualquer ligação aparente, apresentam semelhanças consideráveis
em sua organização e disposição dos elementos. Além dos padrões, os autores definem o
conceito de tiling, traduzido como “tesselação” neste texto, como um conjunto de regiões
poligonais que cobrem totalmente um plano, sem interseções. Uma definição mais formal
para tesselações será apresentada no capítulo seguinte.
Um conjunto específico entre as tesselações, as chamadas tesselações monoé-
dricas regulares aresta-a-aresta, referidas como "grades regulares"ou simplesmente como
“grades” no decorrer do texto, são o foco principal deste estudo (mais especificamente, as
grades triangulares, quadradas e hexagonais, as únicas grades regulares possíveis), e cor-
respondem a tesselações nas quais as regiões que cobrem o plano são polígonos regulares
com o mesmo número de lados e dimensões, e com arestas compartilhadas entre apenas
dois deles; ou seja, várias instâncias de um mesmo polígono cobrem todo o plano, com
vértices e arestas perfeitamente sobrepostos.
Os tabuleiros em jogos digitais são, em sua maioria, grades. O uso de grades
como tabuleiros, especialmente em jogos baseados em turnos, permite que os jogadores
planejem o posicionamento dos objetos controlados de forma mais simples, e também
gera uma maior sensação de controle sobre a posição dos objetos controlados pelo
jogador. Grades também podem ser utilizadas em jogos digitais como forma de compor o
mundo do jogo, fazendo uso de tilemaps.
A idéia por trás dos tilemaps é compor o mundo (ou outros objetos) do jogo
através da combinação de blocos menores de construção, chamados tiles. O uso de
13

grades para tilemaps já é bem documentado na literatura1 , e as principais engines já


incluem facilidades para essa aplicação. Por esse motivo, este texto não inclui informações
específicas para essa aplicação de grades.
Nos jogos mais antigos, os tabuleiros virtuais assumiam a forma de grades qua-
dradas, e eram utilizados para restringir as direções de movimento e posicionamento dos
personagens e outros objetos do jogo, permitindo melhorias na performance ao controlar
a quantidade de cálculos com ponto flutuante que eram necessários. Eventualmente, com
o aumento do poder computacional do hardware utilizado para fins de entretenimento,
essa restrição como forma de otimização deixou de ser necessária e passou a ser utilizada
apenas como parte das mecânicas definidas no design dos jogos. Além disso, o impacto
do emprego de grades hexagonais e triangulares (embora a última ainda não seja ampla-
mente utilizada) se tornou menor, permitindo que esses novos tipos de tabuleiros fossem
utilizados.
Atualmente, grades apresentam um papel crucial em jogos de simulação, jogos
que envolvam construção, jogos de estratégia baseados em turnos e jogos com estética
antiquada, sendo especialmente comuns no cenário de jogos indie, onde as facilidades
geradas por seu uso permitem pequenos grupos desenvolver jogos com custo reduzido.

1 Dhule[3]e Halpern[9], por exemplo, possuem capítulos inteiros dedicados ao assunto em seus livros
sobre desenvolvimento de jogos nas duas principais engines utilizadas por desenvolvedores independentes.
CAPÍTULO 3
Análise Geométrica

No decorrer deste capítulo, será feita a análise geométrica das tesselações mo-
noédricas regulares aresta-a-aresta, que são o objeto de estudo desta publicação, de modo
a estabelecer os conceitos e bases para as implementações descritas nos capítulos a seguir.
Também será feita a análise de características dos polígonos regulares, e deduções mate-
máticas acerca destes que serão utilizados como base para muitos dos conceitos utilizados
nas implementações e considerações geométricas nos capítulos seguintes.

3.1 Tesselações Monoédricas Regulares Aresta-a-Aresta


Grünbaum e Shephard[8] definem a tesselação de um plano euclidiano como
“uma família contável de conjuntos [...] que cobrem o plano sem frestas ou sobreposições”
(tradução livre), onde “conjuntos” se refere a estruturas que representam polígonos,
compostas por um subconjunto de vértices e por um subconjunto de arestas que ligam
esses vértices. Os autores incluem também que esses conjuntos devem ser disjuntos e sua
união deve ser igual a todo o plano1 , e que cada conjunto deve ser um disco topológico2 .
Também é estabelecido o conceito de tesselação monoédrica, onde cada subdivisão do
plano é um polígono de mesmo tamanho e formato, e, no caso destes polígonos serem
polígonos regulares, é dito que se trata de uma tesselação monoédrica regular do plano.
Como citado no capítulo anterior, este texto se dedicará a um subconjunto dessa família de
tesselações, as tesselações monoédricas regulares aresta-a-aresta, onde as arestas de cada
um dos polígonos da tesselação têm contato com a aresta de apenas um outro polígono3 .
Os únicos tipos possíveis dessa família de tesselações regulares do plano são
a tesselação usando triângulos equiláteros, quadrados ou hexágonos regulares. Como
provado por Grünbaum e Shephard[8], isso ocorre em razão de que, para um polígono
regular de n lados, sabe-se que a soma de seus ângulos internos é de (n − 2)π. Como

1A tesselação deve cobrir todo o plano.


2 Istoé, cada conjunto deve ser definido por uma única curva, com início e fim no mesmo vértice, e sem
que a curva cruze a si mesma.
3 As arestas são compartilhadas entre exatamente dois polígonos.
3.1 Tesselações Monoédricas Regulares Aresta-a-Aresta 15

resultado, para polígonos regulares, cada ângulo interno deve medir (n−2)π n . Logo, em
um vértice compartilhado entre um conjunto de p polígonos, com números de lados
n1 , n2 , n3 , ..., n p , a soma destes ângulos deve ser igual a 2π. Então,

p
(ni − n) π
∑ = 2π (3-1)
i=1 n i

Por se tratar de uma tesselação regular monoédrica aresta-a-aresta, todos os


polígonos terão a mesma quantidade de lados (e mesmo tamanho), ou seja, n1 = n2 =
n3 = ... = nr = n. Logo,
p
(ni − n) π
∑ = 2π
i=1 ni
(n − 2) π
p· = 2π
n
(n − 2)
p· =2 (3-2)
n
2n
p= (3-3)
n−2

Seguindo outro caminho de desenvolvimento à partir da equação (3-2), tem-se:

(n − 2)
p· =2
n
np − 2p = 2n
np − 2n = 2p
n (p − 2) = 2p
2p
n= (3-4)
p−2

Uma vez que p e n são números naturais, com n ≥ 3 (pois não existem polígonos
com menos de 3 lados) e p ≥ 2 (cada vértice deve ser “compartilhado” por pelo menos
2 polígonos, para garantir a tesselação), chegamos à restrição n ≤ 6, pois, para n > 6,
partindo de (3-4):

2p
>6
p−2
2p > 6p − 12
−4p > −12
p<3

Se p ∈ N e 3 > p ≥ 2, então, obrigatoriamente, p = 2, o que gera uma divisão


3.2 Considerações Sobre Polígonos Regulares 16

por 0 com o ao aplicar o valor na equação (3-4). Logo, n > 6 não satisfaz as restrições,
e não é possível criar uma tesselações monoédricas regulares face-a-face com polígonos
regulares com mais de 6 lados. Também, valores de n < 2 levam a equação (3-4) a valores
negativos, reforçando a restrição de que p ≥ 2. Por fim, é possível eliminar o caso onde
n = 5, uma vez que, ao aplicar o valor de n na equação (3-4), teremos p = 10 3 , conflitando
com a restrição de que p ∈ N.
Portanto, o valor de n deve pertencer a {3, 4, 6} para que todas as restrições sejam
respeitadas, e fica provado que as únicas tesselações regulares monoédricas aresta-a-aresta
possíveis devem ter suas células na forma de polígonos regulares de 3, 4 e 6 lados. Para
esses casos, ao aplicar os valores na equação (3-4), chega-se a conclusão que os vértices
dessas tesselações serão compartilhados por, respectivamente, 6 triângulos equiláteros, 4
quadrados e 3 hexágonos regulares. Por este motivo, essas tesselações são classificadas
pelos seus vértices como 36 , 44 e 63 .
No decorrer deste texto, o termo “grade” é amplamente utilizado como uma
forma simplificada de se referir às tesselações regulares monoédricas aresta-a-aresta.

3.2 Considerações Sobre Polígonos Regulares


Para um polígono regular qualquer de n lados, é possível desenhar uma circun-
ferência circunscrita ao polígono de forma que todos os vértices estejam contidos na cir-
cunferência e o centro da circunferência seja exatamente o baricentro do polígono; logo,
a distância entre o baricentro e um vértice qualquer do polígono regular será igual ao raio
da circunferência circunscrita a este polígono.
Supondo um polígono regular com n lados de comprimento l, com seu baricentro
em O = (xO , yO ), um de seus vértices, V = (xV , yV ), com x′ > x e yO = yV , e outro vértice
do polígono, consecutivo a V , que chamaremos de V ′ , é possível definir a distância entre
O e V ′ como o raio r do círculo circunscrito ao polígono, e também o ângulo θ entre os
segmentos OV e OV ′ como θ = 2π n , conforme a seção anterior. A figura 3.1 representa
essa configuração.
Traçando a bissetriz do ângulo θ, é possível definir um triângulo retângulo atra-
vés dos vértices V , O e o ponto médio da aresta VV ′ , e através das relações trigonométri-
cas no triângulo retângulo, encontrar o raio r da circunferência circunscrita ao polígono
em razão de valores dados inicialmente, como o comprimento do lado e a quantidade de
lados, de acordo com a figura 3.2.
3.2 Considerações Sobre Polígonos Regulares 17

Figura 3.1: Relação entre o baricentro e dois vértices consecutivos


de um polígono regular.

Figura 3.2: Triângulo retângulo criado usando a bissetriz do ân-


gulo θ.
3.2 Considerações Sobre Polígonos Regulares 18

l
  
θ 2
sin =
2 r

! l

n 2
sin =
2 r
π l
sin =
n 2r
l
r= π
 (3-5)
2 · sin n

À partir do raio, é possível escrever as coordenadas do vértice V relativas ao


centro O:

xV − xO = r, yV − yO = 0
V = O + (r, 0) = O + (1, 0)r (3-6)

Pela propriedade de polígonos regulares que diz que todos os vértices estão sobre
a circunferência circunscrita ao polígono (ou, em outras palavras, todos os vértices estão
a uma mesma distância do centro), pode-se afirmar que todos os vértices estarão a r
unidades de distância do centro, e suas coordenadas podem ser encontradas à partir da
rotação das coordenadas de um vértice qualquer do polígono por um ângulo i · θ ao redor
do centro O, onde i é um número inteiro. Assim, supondo a existência do vértice V , da
equação (3-6), é possível generalizar a posição de um dos vértices do polígono como

" # " #
cos(θi) − sin(θi) 1
Vi = O + · ·r
sin(θi) cos(θi) 0
" #
1 · cos(θi) − 0 · sin(θi)
Vi = O + ·r
1 · sin(θi) + 0 · cos(θi)
" #
cos(θi)
Vi = O + · r , ou
sin(θi)
Vi = O + (cos(θi), sin(θi)) · r , com i ∈ [0, n[. (3-7)

Note que o resultado em (3-7) não é totalmente genérico, pois depende da exis-
tência de um vértice com as coordenadas relativas definidas em (3-6). Isso pode ser corri-
gido adicionando um ângulo α à rotação do vértice (e, por consequência, rotacionando o
polígono como um todo pelo mesmo ângulo):

Vi = O + (cos(α + θi), sin(α + θi)) · r , com i ∈ [0, n[. (3-8)


3.2 Considerações Sobre Polígonos Regulares 19

Para obter o ponto médio de um lado do polígono, faremos o cálculo do


comprimento do segmento que vai do centro do polígono ao centro do vértice, através
das relações trigonométricas no triângulo retângulo da figura 3.2, que será o a apótema
a = r · cos ( θ2 ). Assim, o centro de um lado li pode ser obtido rotacionando o vetor (0, a)
por um ângulo α + θi + θ2 :

    
θ θ
li = O + cos α + θi + , sin α + θi + · a , com i ∈ [0, n[. (3-9)
2 2
CAPÍTULO 4
Grades Triangulares

Essa seção trata de tesselações regulares monoédricas aresta-a-aresta com vér-


tices do tipo 36 , que chamaremos simplesmente de grades triangulares (figura 4.1). Seu
uso não é comum, mas jogos como Colossal Citadels, que usa a grade para combate e
construção, chamam a atenção por sua criatividade.
Uma facilidade gerada por este tipo de grade é a aplicação sobre terrenos
tridimensionais, que vem da capacidade que triângulos possuem de modelar superfícies
complexas. Nesse tipo de aplicação, desde que a grade mantenha a integridade com
relação a um plano (que corresponde à vista superior da grade), é possível aplicá-la sobre
terrenos com relevos diversos, alterando a “altura” dos vértices. O tamanho das células
pode ser reduzido para modelar detalhes do terreno de forma mais precisa, ou aumentada
para obter o efeito inverso. O terreno também pode passar por suavização visual sem
desconectar o “tabuleiro visual” do “tabuleiro mecânico”.
Como pode ser observado na figura 4.1, em grades triangulares, as células podem
assumir a forma de triângulos em duas orientações diferentes, com um ângulo de rotação
de 180° (ou π radianos) entre elas. Ao tentar definir dois eixos perpendiculares e designar

Figura 4.1: Grade triangular construída em torno do vétice O.


21

c a
Figura 4.2: Uso de três eixos na grade triangular.

índices (i, j) para cada célula, a diferença de orientação dos triângulos se torna um
problema, uma vez que a distância entre os baricentros de triângulos na mesma “linha”
não é constante, e será diferente para índices ímpares e pares. Além disso, a orientação
do primeiro triângulo de cada linha também varia. A criação de uma função que faça esse
mapeamento do plano da grade para o plano cartesiano é possível, mas não é simples ou
intuitiva.
Adam “BorisTheBrave” Newgas, em sua publicação de 2021[13], descreve uma
abordagem para a indexação de grades triangulares utilizando três eixos, a, b e c, com
um ângulo de 120° entre eles, com o índice (0, 0, 0) designando um vértice como centro
da grade, e com a soma das coordenadas (i, j, k) de um triângulo no plano sendo tais que
(i + j + k) ∈ {1, 2}, como mostrado na figura 4.2. Os triângulos “com a ponta para cima”
terão a soma de suas coordenadas na grade iguais a 2, enquanto os triângulos “com a
ponta para baixo” terão a soma de suas coordenadas na grade iguais a 1.
Através do sistema de coordenadas triplas para grades triangulares, para uma
célula da grade triangular em (i, j, k) e lado de comprimento l, seu baricentro será pode
ser encontrado pela combinação linear dos três vetores unitários que representam os eixos,
multiplicados pelas respectivas coordenadas e pelo raio r da circunferência circunscrita
ao polígono. A princípio temos acesso apenas ao vetor unitário b, que é vertical para cima.

b = (0, 1) (4-1)

Porém, sabendo que os três vetores são separados por um ângulo de 3 radianos,
é possível encontrar a e c através da rotação de b.
22

" # " # √ !
cos(− 2π 3 ) − sin(− 2π
3 ) 0 3 1
a= · = ,− (4-2)
sin(− 2π 3 ) cos(− 2π
3 ) 1 2 2
" # " # √ !
cos( 2π
3 ) − sin( 2π
3 ) 0 3 1
c= · = − ,− (4-3)
sin( 2π
3 ) cos( 2π
3 ) 1 2 2

Assim, as cordenadas do baricentro de uma célula triangular (i, j, k) da grade


serão dados por:

Oi, j,k = (i · a + j · b + k · c) · r
" √ ! √ !#
3 1 3 1
Oi, j,k = i · ,− + j · (0, 1) + k · − ,− ·r
2 2 2 2
" √ ! √ !#
i 3 i k 3 k
Oi, j,k = ,− + (0, j) + − ,− ·r
2 2 2 2
√ !
(i − k) 3 −i + 2 j − k
Oi, j,k = , ·r
2 2
√ !
(i − k) 3 −i + 2 j − k l
Oi, j,k = , · 
2 2 2 · sin π3
√ !
1 (i − k) 3 1 −i + 2 j − k
Oi, j,k = · , · ·l
2 sin π3 2 2 sin π3 2
√ !
1 (i − k) 3 1 −i + 2 j − k
Oi, j,k = √ · ,√ · ·l
3 2 3 2
 
(i − k) −i + 2 j − k
Oi, j,k = , √ ·l
2 2 3
√ !
(i − k) 3 (2 j − k − i)
Oi, j,k = , ·l (4-4)
2 6

À partir do resultado em (4-4), Newgas apresenta o trecho a seguir. No código,



o valor de 3 foi pré-calculado e armazenado na variável sqrt3. O autor adiciona como
nota, em seu guia de implementação, que caso sejam utilizadas coordenadas que somem
zero como parâmetros para a função, ela retornará a posição de um vértice na grade, ao
invés do baricentro de uma célula.
23

i − 1, j, k i, j − 1, k
i, j, k i, j, k + 1

i, j, k − 1 i, j, k
i + 1, j, k i, j + 1, k

Figura 4.3: Células adjacentes na grade triangular, sob o sistema


de coordenadas cúbicas.

Código 4.1 Implementação em python do resultado (4-4).

1 def tri_center (a , b , c):


2 return (( 0.5 * a +
,→ -0.5 * c)
,→ * edge_length ,
3 (- sqrt3 / 6 * a + sqrt3 / 3
,→ * b - sqrt3 / 6 * c) *
,→ edge_length )

Partindo do algoritmo implementado (ou do resultado em (4-4)) e do resultado


em (3-8), é possível encontrar as posições de todos os vértices de uma das células do
triângulo no plano cartesiano à partir de suas coordenadas na grade, desde que se conheça
a orientação do triângulo na grade (ponta para cima ou ponta para baixo). Através de
análises da grade, Newgas conjectura que todo triângulo cuja soma das coordenadas for
igual a 2 será um triângulo com a ponta para cima (α = π2 ), e todo triângulo cuja soma
das coordenadas for igual a 1 será um triângulo com a ponta para baixo (α = − π2 ).
Para uma grade qualquer, duas células serão classificadas como adjacentes
quando compartilharem uma aresta (ou dois vértices). Para o caso de grades triangulares,
cada célula possuirá 3 células adjacentes (excluindo-se as células da “borda” da grade).
As coordenadas das células adjacentes a uma célula (i, j, k) serão diferentes para cada
orientação dos triângulos na grade, como pode ser visto na figura 4.3. Assim, Newgas
define a adjacência para ambos os casos através da função no código 4.2.
24

Código 4.2 Implementação em Python da adjacência de célu-


las na grade triangular.

1 def tri_neighbours (a , b , c):


2 points_up = a + b + c == 2
3 if points_up :
4 return [
5 (a - 1, b , c ),
6 (a , b - 1, c ),
7 (a , b , c - 1) ,
8 ]
9 else :
10 return [
11 (a + 1, b , c ),
12 (a , b + 1, c ),
13 (a , b , c + 1) ,
14 ]

Código 4.3 Implementação em Python da distância entre duas


células na grade triangular.

1 def tri_dist (a1 , b1 , c1 , a2 , b2 , c2 ):


2 return abs ( a1 - a2 ) + abs ( b1 - b2 ) +
,→ abs ( c1 - c2 )

Adam Newgas também define uma implementação de algoritmo para o cálculo


da distância entre dois triângulos, com suas respectivas coordenadas (i, j, k) e (i′ , j′ , k′ ),
que está representado no código 4.3. A simplicidade do código é consequência direta
do uso de três eixos de coordenadas para a representação de triângulos em um plano
bidimensional. A função simplesmente calcula a diferença absoluta entre as coordenadas.
A função do cálculo de distâncias, em conjunto com a função de adjacência no Código
4.2, pode ser utilizada como base para uma implementação do algoritmo A*, permitindo
encontrar as células componentes do caminho de uma célula de origem para uma célula
de destino.
4.1 Estruturas de Dados para Grades Triangulares 25

i, j, B

i, j,C

Figura 4.4: Representação visual da estrutura de dados sugerida.

4.1 Estruturas de Dados para Grades Triangulares


O armazenamento de dados estruturados para grades triangulares pode ser reali-
zado de forma simples através do uso de uma matriz tridimensional, aproveitando as três
coordenadas utilizadas para identificar os triângulos na grade, mas essa abordagem gera
dois problemas. O primeiro é que uma matriz tridimensional, para este caso específico,
seria esparsa, dada a restrição sobre os índices dos triângulos terem sua soma igual a 1 ou
2. O segundo é que, uma vez que estão sendo utilizadas três coordenadas para identificar
as células na grade bidimensional, uma dessas coordenadas deve ser supérflua. A coor-
denada supérflua pode ser colocada em função das outras duas, pois partindo dos vetores
unitários dos eixos a, b e c, definidos respectivamente em (4-2), (4-1) e (4-3), é possível
encontrar

c = −a − b (4-5)

E, para as coordenadas, teremos

i+ j+k = 1 i+ j+k = 2
ou (4-6)
k = 1−i− j k = 2−i− j

O uso de apenas duas coordenadas permite o mapeamento direto da grade para


uma matriz bidimensional, mas as equações (4-6) mostram um problema óbvio no acesso
a um triângulo à partir de apenas duas coordenadas (i, j): a existência de dois triângulos
que poderiam ser referenciados por essas mesmas coordenadas, sendo eles triângulo
(i, j, 1 − i − j), com a ponta para baixo, e o triângulo (i, j, 2 − i − j), com a ponta para
cima. Diversos autores propõem formas diferentes de lidar com esse problema.
A abordagem escolhida para as implementações neste texto é descrita por Amit
Patel[15], que consiste em armazenar os dados de ambos os triângulos que respondem às
mesmas coordenadas (i, j) em uma estrutura de dados que encapsule ambos os triângulos
(correspondente a um paralelogramo), e que permite o acesso à estrutura de dados que
4.1 Estruturas de Dados para Grades Triangulares 26

i, j, N

i, j, O i, j, L i + 1, j, O

i, j + 1, N
Figura 4.5: Arestas na estrutura de dados sugerida. As arestas tra-
cejadas correspondem às arestas que estariam arma-
zenadas em uma célula vizinha.

i+1, j
i, j

i, j+1
i, j+1
Figura 4.6: Vértices na estrutura de dados sugerida. Os vértices
representados por um círculo vazio correspondem aos
vértices que estariam armazenados em uma célula
vizinha.

corresponde a cada triângulo de forma particular. Patel, em seu guia sobre partes de grades
e seus relacionamentos sugere a nomenclatura de “R” (do inglês, “right”, direita) para o
triângulo com a ponta para baixo, e “L” (do inglês, “left”, esquerda), para o triângulo
com a ponta para cima. Para manter a clareza no texto e algoritmos, os chamaremos os
triângulos com a ponta para cima de “C” (de “cima”) e os triângulos com a ponta para
baixo de “B” (de “baixo”). Essa organização está ilustrada na figura 4.4.
Patel[15] propõe que, em cada paralelogramo (i, j), sejam mantidos os dados das
arestas do triângulo B (arestas Norte, Oeste e Leste) e apenas o vértice no canto superior
esquerdo deste triângulo. Quanto às arestas do triângulo C no paralelogramo, uma delas
será compartilhada com o triângulo B (aresta Leste) de (i, j) e as outras duas virão dos
triângulos B dos paralelogramos (i + 1, j) (aresta Oeste) e (i, j + 1) (aresta Norte), de
acordo com a figura 4.5.
Quanto aos vértices, Patel[15] sugere que seja armazenado apenas um vértice
por estrutura de dados da grade. Supondo que o vértice escolhdido seja o vértice superior
esquerdo, para o triângulo B, o vértice no canto superior esquerdo virá de (i, j), o vértice
4.1 Estruturas de Dados para Grades Triangulares 27

do canto superior direito virá de (i + 1, j), e o vértice inferior virá do paralelogramo


(i, j + 1). Para o triângulo C, o vértice no canto inferior esquerdo vem do paralelogramo
(i, j +1), o vértice no canto inferior direito vem do paralelogramo (i+1, j +1), e o vértice
superior vem de (i + 1, j).
Tendo em vista que as células na grade nem sempre armazenarão todos os seus
vértices e/ou arestas, é conveninente ressaltar que essa abordagem pode requerer que, ao
armazenar uma grade triangular, seja necessária a criação de células adicionais ao redor
das células da borda da grade, para que todas as suas arestas e vértices estejam acessíveis.
CAPÍTULO 5
Grades Quadradas

Amplamente utilizadas em alguns dos jogos de tabuleiro mais difundidos e jogos


digitais com estética antiquada, as grades quadradas são o tipo mais intuitivo de tesselação
monoédrica regular aresta-a-aresta. Sua classificação de acordo com seus vértices é 44 ,
uma vez que cada aresta é compartilhada por quatro polígonos regulares de quatro lados.
Suas características mais atrativas são a simplicidade e intuitividade nas imple-
mentações, o grande repertório de artigos e diversas outras formas de publicação que
descrevem seus usos e implementações, bem como o grande número de bibliotecas gra-
tuitas que estão disponíveis para serem utilizadas por desenvovedores em geral. Exemplos
de seu uso são comuns: os primeiros títulos da série Final Fantasy, Final Fantasy Tactics,
The Sims, Sim City, Terraria, Minecraft.
A indexação de quadrados em uma grade é uma tarefa quase trivial. Diferente
do caso da grade triangular, não é necessário o uso de três eixos de coordenadas para

O x

Figura 5.1: Grade quadrada que tem como centro o ponto O,


baricentro do quadrdado (0, 0), e eixos da grade.
29

endereçar as células, uma vez que é possível definir dois eixos perpendiculares x e y, tais
que os quadrados em uma mesma linha estejam alinhados com relação ao eixo x e os
quadrados em uma mesma coluna estejam alinhados relativos ao eixo y (vide figura 5.1).
Também, na abordagem escolhida, a posição central da grade (0, 0) será o baricentro uma
célula da grade (e não um vértice), e não há restrições acerca das coordenadas1 .
Considerando o baricentro da célula central da grade como o ponto O, a posição
do baricentro de qualquer célula (i, j), considerando o tamanho do lado l, será

Oi, j = O + (i, j) · l (5-1)

Código 5.1 Implementação em Python do resultado 5-1.

1 def quad_center (i , j):


2 return (i * edge_length , j *
,→ edge_length )

O código 5.1 demonstra a trivialidade da implementação do resultado 5-1 como


uma função em python. A equação 3-8, em conjunto com o desenvolvimento acima, com
θ = π2 , permite que as posições dos vértices sejam encontrados facilmente. Considerando
que, na abordagem escolhida, α = π4 (o primeiro vértice fazendo um ângulo de 45° com o
eixo x da grade), a equação em 3-8 pode ser desenvolvida. Para uma célula quadrada com
baricentro O, tem-se:
 π  π 
Vi = O + cos + θi , sin + θi · r
4 4
√ √ !
2 2
Vi = O + · (cos (θi) − sin (θi)) , · (cos (θi) + sin (θi)) · r
2 2

2
Vi = O + (cos (θi) − sin (θi), cos (θi) + sin (θi)) · ·r
√2
2 l
Vi = O + (cos (θi) − sin (θi), cos (θi) + sin (θi)) · ·√
2
        2
iπ iπ iπ iπ l
Vi = O + cos − sin , cos + sin (5-2)
2 2 2 2 2

O resultado 5-1 pode ser utilizado para comprovar a equação em 5-2. O re-
sultado 5-1 também pode ser provado através do teorema de pitágoras. Uma vez que

1 Isto é, além dos limites de tamanho da grade.


30

i, j + 1

i − 1, j i, j i + 1, j

i, j − 1

Figura 5.2: Células adjacentes à célula (i, j).

i ∈ {0, 1, 2, 3}, as coordenadas dos vértices serão dadas por:

l
V0 = O + (1, 1) ·
2
l
V1 = O + (−1, 1) ·
2
l
V2 = O + (−1, −1) ·
2
l
V3 = O + (1, −1) ·
2

Código 5.2 Implementação em Python da adjacência de célu-


las na grade quadrada.

1 def quad_neighbours (i , j):


2 return [(i -1 , j) , (i+1 , j) , (i ,
,→ j -1) , (i , j +1) ]

A adjacência em grades quadradas também é simples. No caso geral, cada célula


possuirá quatro células ajacentes2 , com as quais compartilhará uma aresta3 . Trivialmente,
considerando uma célula em (i, j), suas células adjacentes serão: (i − 1, j) a Oeste,

2 Com exceção das células nas bordas da grade, que podem ter 3 ou 2 células adjacentes.
3 Para a abordagem escolhida, apenas as célullas que compartilham arestas entre si serão consideradas
adjacentes. Há também abordagens que consideram adjacentes todas as células que compartilhem vértices
entre si.
5.1 Estruturas de Dados para Grades Quadradas 31

(i + 1, j) a Leste, (i, j − 1) ao Sul e (i, j + 1) ao Norte. Além disso, a célula terá como
diagonais (i − 1, j + 1) a Noroeste, (i − 1, j − 1) a Sudoeste, (i + 1, j + 1) a Nordeste e
(i + 1, j − 1) a Sudeste, de acordo com a figura 5.2. O código 5.2 exibe uma função de
obtenção das células adjacentes à partir de uma célula (i, j).
Para o cálculo de distância entre duas células (i1 , j1 ) e (i2 , j2 ), utiliza-se a
chamada distância de Manhattan:

d = |i2 − i1 | + | j2 − j1 | (5-3)

Código 5.3 Implementação em Python da distância entre duas


células na grade quadrada.

1 def quad_dist (i1 , j1 , i2 , j2 ):


2 return abs ( i2 - i1 ) + abs ( j2 - j1 )

O código 5.3 implementa a distância de células em grades quadradas. De posse


do resultado em 5-3 e de uma forma de encontrar células adjacentes, é possível e simples
fazer seu uso em uma implementação do algoritmo A*, permitindo encontrar um caminho
na grade, partindo de uma célula de origem para uma célula de destino.

5.1 Estruturas de Dados para Grades Quadradas


As coordenadas do baricentro de uma célula quadrada na grade podem ser facil-
mente mapeadas para uma matriz bidimensional sem qualquer perda. Todavia, quando
o interesse do desenvolvedor não estiver (apenas) nos centros das células, mas tam-
bém em suas arestas e vértices, surge a necessidade da criação de uma estrutura de
dados para representá-las. Amit Patel, em seu guia sobre partes das grades e seus
relacionamentos[15], aponta que, para o caso particular das grades quadradas, a forma
mais conveniente de armazenar dados acerca dos vértices e arestas é associando cada po-
sição da grade a um vértice e duas arestas. Deste modo, não haverão vértices ou arestas
que serão armazenados de forma redundante.
Utilizando a mesma representação que Patel, cada célula da grade armazenará
os dados relacionados ao vértice Noroeste e os lados Norte e Oeste; portanto, para uma
célula (i, j), suas arestas Norte e Oeste estarão autocontidas, mas a aresta Leste estará
associada à célula (i + 1, j) como sua aresta Oeste, e a aresta Sul estará associada à
célula (i, j − 1) como sua aresta Norte. Quanto aos vértices, o vértice Noroeste estará
autocontido, enquanto o vértice Nordeste estará associado à célula (i + 1, j), o vértice
5.1 Estruturas de Dados para Grades Quadradas 32

i, j, N i, j i + 1, j

i, j, O i + 1, j, O

i, j − 1, N i, j − 1 i + 1, j − 1
Figura 5.3: Vértices e arestas da célula (i, j). As arestas traceja-
das e círculos representam as arestas e vértices asso-
ciados a outras células.

Sudoeste estará associado à célula (i, j − 1), e o vértice Sudeste estará associado à célula
(i + 1, j − 1). A figura 5.3 ilustra essa configuração.
Para essa representação, as células na última coluna à direita da grade não terão
vértices e arestas definidas no lado Leste, e as células na linha mais inferior não terão
vértices e arestas definidas do lado Sul, então se faz necessária a criação de células
extra, para garantir que os vértices e arestas das células “incompletas” estejam acessíveis,
assim como ocorre no restante da grade. O espaço em memória ocupado por essas
“células-fantasma” é desprezível quando comparado ao desperdício que seria causado
pela redundância gerada caso se escolhesse uma abordagem onde cada célula armazenasse
seus quatro vértices e arestas por conta própria, e perde sua relevância de acordo com o
crescimento da grade.
Certas linguagens de programação podem permitir o acesso facilitado às estru-
turas dos vértices e arestas, fazendo o acesso às estruturas relacionadas a outras células
através de referências diretas. Também é possível armazenar as informações associadas
aos vértices à parte das informações associadas às células, em uma estrutura matricial de
fácil acesso. Os efeitos dessas otimizações, porém, só tendem a se mostrar vantajosos em
grades maiores ou com grande número de acessos aos vértices.
CAPÍTULO 6
Grades Hexagonais

Amplamente utilizadas como tabuleiro em jogos modernos de estratégia, as


grades hexagonais (figura 6.1) possuem uma propriedade única com relação às demais
grades regulares: células que compartilham vértices entre si são sempre adjacentes1 .
Logo, todas as células vizinhas a uma célula “central” terão seu baricentro à mesma
distância do baricentro dessa célula central. Essa característica faz com que as grades
hexagonais sejam percebidas pelos jogadores como um tabuleiro menos restritivo que os
demais, permitindo mais direções de movimento, e mais justo, com todas as células da
vizinhança a uma mesma distância. São comumente empregadas em jogos de estratégia,
como os jogos da série Civilization, Dorf Romantik e Catan Online2 .

1 Ouseja, compartilham também uma aresta.


2 Pode-searumentar que Catan faz uso de uma grade hexagonal apenas visualmente, e que, com respeito
a mecânicas, sua grade é triangular.

Figura 6.1: Grade hexagonal com a célula central O. A linha


tracejada mostra a variação no das coordenadas do
centro das células no eixo horizontal.
34

s q

r
Figura 6.2: Grade hexagonal com a célula central O. A linha
tracejada mostra a variação no das coordenadas do
centro das células no eixo horizontal.

As grades hexagonais sofrem do mesmo mal que as grades triangulares: para uma
grade de hexágonos com a “ponta” para cima (em contraposição às grades com hexágonos
com as “pontas” para os lados), embora os hexágonos de uma mesma linha estejam
alinhados paralelos a um eixo horizontal (mesma coordenada no eixo vertical para células
na mesma linha), os hexágonos em uma mesma "coluna"não estarão alinhados paralelos a
um eixo vertical (a coordenada no eixo horizontal varia no decorrer da coluna)3 . Por essa
razão, Patel[14] propõe o uso de três eixos de coordenadas, assim como na abordagem
proposta por Adam Newgas para grades triangulares[13].
Os três eixos q, s e r, fazem um ângulo de 2π
3 entre si, de modo que o primeiro
eixo, q, faça um ângulo de π6 radianos com o eixo horizontal do plano (vide figura 6.2).
Relativas aos eixos q, s e r, a posição do centro da grade, (0, 0, 0), será o baricentro de
uma célula hexagonal, e todas as células poderão ser acessadas por índices (i, j, k) tais
que i + j + k = 0. Para obter os vetores unitários que representam os eixos, uma vez que
os ângulos relativos ao eixo horizontal são conhecidos, basta rotacionar um vetor unitário

3 Para grades de hexágonos com as "pontas"para os lados, o problema ocorrerá no eixo vertical.
35

horizontal para a direita pelo ângulo do eixo:


"
π
 π
# " # √ !
q=
cos 6  − sin 6 · 1 = 3 1
, (6-1)
sin π
6 cos 6 π
0 2 2
" # " # √ !
cos π6 + 2π 2π
 π
3 − sin 6 + 3 · 1 3 1
s= 2π 2π
= − , (6-2)
π
sin 6 + 3 π
cos 6 + 3 0 2 2
" # " #
cos π6 + 4π 4π
 π
3 − sin 6 + 3 · 1 = (0, −1)
r= (6-3)
sin π6 + 4π 3 cos π6 + 4π 3 0

À partir da combinação linear dos vetores unitários que representam os eixos, é


possível obter as coordenadas no plano cartesiano do baricentro de uma célula hexagonal
usando suas coordenadas na grade (i, j, k) e as coordenadas no plano cartesiano do
baricentro O da célula (0, 0, 0) na grade.

l
Oi, j,k = O + (i · q + j · s + k · r) · 
2 · sin π6
√ ! √ ! !
3 1 3 1
Oi, j,k = O + i · , + j· − , + k · (0, −1) · l
2 2 2 2
√ ! √ ! !
i 3 i j 3 j
Oi, j,k = O + , + − , + (0, −k) · l
2 2 2 2
√ !
(i − j) 3 i + j − 2k
Oi, j,k = O + , ·l (6-4)
2 2

Código 6.1 Implementação em Python do resultado 6-4.

1 def hex_center (i , j , k):


2 return (( i - j) * sqrt3 *
,→ 0.5 * edge_length ,
3 (i + j - 2* k) *
,→ 0.5 * edge_length )

O código 6.1 contém a implementação de uma função que, dadas as coordenadas


de uma célula na grade, retorna as coordenadas de seu baricentro relativas à origem da
grade. Uma vez encontrado o baricentro da célula, é possível encontrar as coordenadas
dos vértices através da equação em 3-8.
36

i, j + 1, k − 1 i + 1, j, k − 1

i − 1, j + 1, k i, j, k i + 1, j − 1, k

i − 1, j, k + 1 i, j − 1, k + 1

Figura 6.3: Vizinhança de uma célula (i, j, k).

Código 6.2 Implementação em Python da adjacência de célu-


las na grade hexagonal.

1 def hex_neighbours (i , j , k):


2 return [( i+1 , j , k -1) ,
3 (i+1 , j -1 , k) ,
4 (i , j -1 , k +1) ,
5 (i -1 , j , k +1) ,
6 (i -1 , j+1 , k) ,
7 (i , j+1 , k -1) ]

Apesar do uso do sistema de coordenadas cúbicas na grade, a obtenção de


células adjacentes é simples. Dada uma célula (i, j, k), suas células adjacentes podem ser
encontradas somando 1 a uma das coordenadas e subtraindo 1 de outra das coordenadas4
(vide 6.3). O código 6.2 contém uma implementação em Python deste método.
O cálculo das distâncias entre duas células, (i1 , j1 , k1 ) e (i2 , j2 , k2 ) também é
facilitado pelo uso de coordenadas cúbicas. Segundo Patel[14], essa distância será dada
por:
d = max (|i2 − i1 |, | j2 − j1 |, |k2 − k1 |) (6-5)

A validade do resultado na equação 6-5 se dá pelo fato de que uma das coordena-
das do sistema utilizado na grade é supérflua, e, portanto, pode ser colocada em razão de

4A peculiaridade da adjacência vem da restrição de que as coordenadas de uma célula na grade devem
somar 0.
37

outras duas, convertendo o sistema de coordenadas cúbicas em um sistema de coordena-


das oblíquas. Nas equações a seguir, a coordenada k será tratada como supérflua. À partir
do sistema de coordenadas oblíquas, Luczak e Rosenfeld [11], da análise dos sextantes
da grade e das fórmulas para disância de Manhattan e do tabuleiro de xadrez, define o
seguinte método para o cálculo de distâncias:

d = |i − i | + | j − j | , caso ambos os termos tenham o mesmo sinal, ou
2 1 2 1
(6-6)
d = max (|i − i |, | j − j |) , caso os termos tenham sinais postos.
2 1 2 1

A restrição sobre as coordenadas na grade hexagonal i + j + k = 0 pode ser


manipulada para k = −i − j. Deste modo, a equação 6-5 pode desenvolvida:

d = max (|i2 − i1 |, | j2 − j1 |, |(−i2 − j2 ) − (−i1 − j1 )|)


d = max (|i2 − i1 |, | j2 − j1 |, | − i2 − j2 + i1 + j1 |)
d = max (|i2 − i1 |, | j2 − j1 |, | − (i2 − i1 ) − ( j2 − j1 )|)
d = max (|i2 − i1 |, | j2 − j1 |, | − [(i2 − i1 ) + ( j2 − j1 )]|)
d = max (|i2 − i1 |, | j2 − j1 |, |(i2 − i1 ) + ( j2 − j1 )|) (6-7)

Código 6.3 Implementação em Python da distância entre duas


células na grade hexagonal.

1 def hex_dist (i1 , j1 , k1 , i2 , j2 , k2 ):


2 return max ( abs ( i1 - i2 ) , abs ( j1 -
,→ j2 ) , abs ( k1 - k2 ))

Para (i2 − i1 ) e ( j2 − j1 ) com o mesmo sinal, temos que |(i2 − i1 ) + ( j2 − j1 )| =


|i2 − i1 | + | j2 − j1 |. Para (i2 − i1 ) e ( j2 − j1 ) com sinais diferentes, um dos dois termos
será maior que o outro, e sua soma, entre um número positivo e um número negativo, será
menor que o número positivo, pois, se a > 0 > b, então a > a + b (somar a a todos os
termos da inequação demonstra esta propriedade). Deste modo, o cálculo das distâncias
na equação 6-5 proposta por Patel[14] é equivalente ao cálculo das distâncias na equação
6-6 proposta por Luczak e Rosenfeld[11]. O código 6.3 exibe uma implementação de
função para o cálculo de distâncias entre duas células na grade hexagonal.
De posse de métodos que permitem calcular a distância entre duas células e
encontrar a vizinhança de uma célula à partir de suas coordenadas na grade, é possível
implementar o algoritmo A* para a grade hexagonal, permitindo o uso deste tipo de grade
nos tipos mais comuns de jogos digitais.
6.1 Estruturas de Dados para Grades Hexagonais 38

i, j, NO i, j, NE

i, j, O i + 1, j, O

i − 1, j − 1, NE i, j + 1, NO
Figura 6.4: Arestas de uma célula (i, j). As linhas tracejadas cor-
respondem às arestas cujos dados estarão associados
a células vizinhas.

Em seu guia de implementação para grades hexagonais, Patel[14] exibe também


algoritmos para operações menos usuais, como rotações e reflexões na grade. Snyder Et.
Al.[17] descreve operações algébricas em grades hexagonais e diversas propriedades do
sistema de coordenadas oblíquas na grade hexagonal (referido como h2 na publicação).

6.1 Estruturas de Dados para Grades Hexagonais


Através da conversão entre os sistemas de coordenadas cúbico e oblíquo, é
possível mapear uma grade hexagonal para uma matriz bidimensional, mas o formato
da grade pode gerar áreas vazias na matriz. Mais especificamente, para que toda as
posições da matriz sejam mapeadas para células na grade, as células da grade deverão
estar arranjadas como um paralelogramo, uma vez que um dos eixos da grade com apenas
duas coordenadas é oblíquo.
Para os formatos mais comuns da grade, como retangular e hexagonal, haverão
regiões “triangulares” na parte inferior e superior da matriz que estarão vazias. Todavia,
este resultado é considerado aceitável para grande parte dos autores, levando em con-
sideração a simplicidade de cálculos e implementação das formas de indexação usando
coordenadas cúbicas e oblíquas. Existem formas de indexação de índice único, na qual as
células são ordenadas como uma espiral (Sheridan e Hintz[16], Kitto Et. Al.[10]), mas o
tradeoff entre complexidade e desempenho é questionável.
Quanto aos vértices e arestas, Amit Patel[15] sugere que, para grades hexagonais
cujas células assumem a forma de hexágonos a “ponta” para cima, cada célula deva
armazenar dados a relacionados aos vértices superior e inferior, e aos lados nas direções
Leste, Noroeste e Nordeste.
Portanto, os vértices de uma célula hexagonal (i, j) serão os vértices Norte e
Sul da célula (i, j), os vértices Sul das células (i, j − 1) e (i + 1, j − 1) e os vértices
6.1 Estruturas de Dados para Grades Hexagonais 39

i, j, N
i, j − 1, S i + 1, j − 1, S

i − 1, j + 1, N i, j + 1, N
i, j, S
Figura 6.5: Vértices de uma célula (i, j). As linhas tracejadas cor-
respondem às arestas cujos dados estarão associados
a células vizinhas.

Norte das células (i, j + 1) e (i − 1, j + 1). Semelhantemente, os lados para uma célula
hexagonal (i, j) serão os lados Oeste, Noroeste e Nordeste da própria célula (i, j), o lado
Oeste de (i + 1, j), o lado Noroeste de (i, j + 1) e o lado Nordeste de (i − 1, j + 1). Estes
relacionamentos estão ilustrados nas figuras 6.4 e 6.5.
CAPÍTULO 7
Considerações Finais

Embora sejam o tipo mais intuitivo e menos complexo de grades que podem ser
implementadas como tabuleiros, as grades quadradas não produzem necessariamente os
melhores resultados para todos os gêneros de jogos (e é por esse motivo que jogos de
plataforma com movimento baseado em grade são raros). Grades quadradas comumente
possuem o efeito de reduzir o passo do jogo, e podem não ser a melhor escolha para jogos
de ação, mas, em contrapartida, apelam para a familiaridade e nostalgia dos jogadores. A
recomendação geral de uso é para jogos com estética e mecânicas antiquadas e jogos que
envolvam construção limitada pela grade.
Grades hexagonais, apesar de sua maior complexidade de implementação e
manutenção, dado o fato que toda a vizinhança de uma célula é diretamente acessível
e equidistante, gera uma sensação maior de justiça em movimentos na grade. Além
disso, o movimento na grade é menos restritivo considerando válida a transição apenas
entre células adjacentes, em comparação com a grade quadrada. Apesar disso, o poder
computacional necessário para lidar com grades hexagonais é maior e planejar e prever
a movimentação na grade pode se tornar um fardo para jogadores acostumados com
grades quadradas. Dito isso, a liberdade de movimento pode ser útil em jogos baseados
em turnos, permitindo que o mapa seja percorrido com maior facilidade, acelerando o
andamento do jogo. Seu uso em jogos que envolvam construção e controle de movimento
em tempo real na grade é impopular.
Para grades triangulares, seu uso em quaisquer aplicações é impopular. Grades
triangulares combinam a restritividade de movimento na grade entre células adjacentes
(pois possuem apenas três lados) com a complexidade do sistema de coordenadas cúbico,
utilizando três eixos. Sua grande vantagem, como já citado anteriormente, é a possibili-
dade de utilização em terrenos tridimensionais com variação de altura, e sua aplicação
apela para jogadores atraídos por mecânicas criativas e incomuns.
Um detalhe digno de nota acerca de grades triangulares e hexagonais é seu
relacionamento de dualidade, e a possibilidade de substituição de uma pela outra para a
modelagem do mesmo tabuleiro. Isso ocorre em razão dos vértices nas grades hexagonais
serem compartilhados por 3 polígonos de 6 lados, e os vértices nas grades triangulares
41

Figura 7.1: Grades triangular e hexagonal sobrepostas, com suas


origens sobrepostas.

serem compartilhados por 6 polígonos de 3 lados. Considerando um vértice da grade


hexagonal, devem haver 3 arestas que ligam este vértice a 3 outros, de mesmo modo
que cada célula em uma grade triangular deve compartilhar arestas com 3 outras células.
Considerando um vértice da grade triangular, devem haver 6 arestas que ligam esse vértice
a 6 outros vértices, de mesmo modo que cada célula em uma grade hexagonal deve
compartilhar arestas com 6 outras células. Esse relacionamento está ilustrado na figura
7.1. A razão entre os comprimentos dos lados das células na grade hexagonal lh e dos
lados das células na grade triangular equivalente lt pode ser encontrada através da equação
3-5, uma vez que o raio da circunferência inscrita às células em ambas as grades será o
mesmo. Logo, tem-se:

lh lt
π
= 
2 · sin 6 2 · sin π3
π
lh · 2 · sin = lt
3

lh · 3 = lt

Um ponto trivial, mas cuja citação é cabível, é que, para o armazenamento das
grades considerando índices negativos, será necessária a adição de um deslocamento
(a, b) na conversão de coordenadas da grade para os índices de linha e coluna da matriz
bidimensional. Para grades triangulares e hexagonais, a adição do deslocamento pode
ser realizada após a conversão, mantendo um impacto mínimo na complexidade das
implementações.
42

Por fim, o uso de quaisquer grades como tabuleiros em jogos deve sempre
considerar outras mecânicas-chave do jogo sendo desenvolvido, bem como estilo de
jogo, tempo gasto pelo jogador, plataforma-alvo e público-alvo. Jogos em grades que
restringem o movimento podem se tornar cansativos, lentos e frustrantes, especialmente
para jogos de estratégia baseados em turnos. Jogos em grades não-ortodoxas podem tornar
a movimentação confusa e os controles mais complexos que o necessário, se usadas em
plataformas com compatibilidade ruim ou em projetos com controles incompatíveis. Em
contrapartida, jogos com mecânicas bem pensadas e com boa sinergia com as grades
escolhidas podem oferecer experiências únicas e inesquecíveis para os jogadores. Cabe
ao desenvolvedor tomar as decisões apropriadas e projetar sua criação de acordo com a
experiência desejada.
Referências Bibliográficas

[1] The great videogame swindle? Next Generation Magazine, 23:64–66, Nov 1996.
Versão digitalizada acessada em 22 de fevereiro de 2022, disponível em The Internet
Archive, https://archive.org/details/NextGeneration23Nov1996_2400.

[2] C HAVEY, D. Tilings by regular polygons—ii a catalog of tilings. Symmetry 2, p.


147–165, 1989.

[3] D HULE , M. Building the game world. In: Beginning Game Development with
Godot, p. 161–202. Springer, 2022.

[4] D ONOVAN , T. Replay: The history of video games. Yellow Ant, 2010.

[5] G OLOMB, S. W. Tilings and patterns. by branko grünbaum and gc shephard.


The American Mathematical Monthly, 95(1):63–64, 1988.

[6] G OODMAN -S TRAUSS, C. Tessellations. arXiv preprint arXiv:1606.04459, 2016.

[7] G OOS, G.; H ARTMANIS, J.; L EEUWEN , J. V. Lecture notes in computer science.
Springer, 1973.

[8] G RÜNBAUM , B.; S HEPHARD, G. C. Tilings and patterns. Courier Dover Publicati-
ons, 1987.

[9] H ALPERN , J. Developing 2D Games with Unity. Springer, 2019.

[10] K ITTO, W. Z.; V INCE , A.; W ILSON , D. C. An isomorphism between the p-


adic integers and a ring associated with a tiling of n-space by permutohedra.
Discrete Applied Mathematics, 52(1):39–51, 1994.

[11] L UCZAK , E.; ROSENFELD, A. Distance on a hexagonal grid. IEEE Transactions on


Computers, 25(05):532–533, 1976.

[12] M ARDON , A.; W IEBE , J.; DANSEREAU, P.; TOMBROWSKI , L. The history of Board
Games. Golden Meteorite Press, 2020.
Referências Bibliográficas 44

[13] N EWGAS, A. Triangle grids. https://www.boristhebrave.com/2021/05/23/


triangle-grids/, May 2021. Acessado em 23 de maio de 2022.

[14] PATEL , A. Hexagonal grids. https://www.redblobgames.com/grids/


hexagons/, May 2003. Acessado em 24 de maio de 2022.

[15] PATEL , A. Grid parts and relationships. https://www.redblobgames.com/


grids/parts/, Jan 2006. Acessado em 17 de maio de 2022.

[16] S HERIDAN , P.; H INTZ , T. Spiral Architecture for machine vision. PhD thesis,
1996.

[17] S NYDER , W. E.; Q I , H.; S ANDER , W. A. Coordinate system for hexagonal


pixels. In: Medical Imaging 1999: Image Processing, volume 3661, p. 716–727.
International Society for Optics and Photonics, 1999.

[18] WOLF, M. J. The video game explosion: a history from PONG to Playstation
and beyond. ABC-CLIO, 2008.

Você também pode gostar