8. Modelos
O MINECRAFT - FGA - 2025/1 utiliza uma arquitetura baseada em models para representar as entidades do jogo. Esta abordagem garante separação de responsabilidades, reutilização de código e facilita a manutenção.
8.1. Estrutura de Models
app/src/models/
├── __init__.py # Exporta todas as models
├── player.py # Models do personagem (Player e PlayerSession)
├── chunk.py # Model do chunk
├── bioma.py # Model do bioma
├── mapa.py # Model do mapa
├── item.py # Model do item
└── inventory.py # Model do inventário
8.2. Player
A model Player representa um personagem principal do jogo com todos os seus atributos persistentes.
- class models.player.Player(id_player, nome, vida_maxima, vida_atual, forca, localizacao, nivel, experiencia, current_chunk_id=None, inventario=<factory>)[source]
Bases:
objectModel que representa um personagem no banco de dados
- Variables:
id_player (int) – ID único do personagem no banco
nome (str) – Nome do personagem
vida_maxima (int) – Vida máxima do personagem
vida_atual (int) – Vida atual do personagem
forca (int) – Força do personagem
localizacao (str) – Localização atual do personagem
nivel (int) – Nível do personagem
experiencia (int) – Experiência acumulada
- current_chunk_id: int | None = None
- experiencia: int
- forca: int
- gain_experience(amount)[source]
Adiciona experiência ao personagem
- Parameters:
amount (int) – Quantidade de experiência a ser adicionada
- get_health_bar(width=20)[source]
Retorna uma barra de vida visual
- Parameters:
width (int) – Largura da barra em caracteres
- Returns:
String representando a barra de vida
- Return type:
str
- get_health_percentage()[source]
Retorna a porcentagem de vida atual
- Returns:
Porcentagem de vida (0.0 a 1.0)
- Return type:
float
- heal(amount)[source]
Cura o personagem
- Parameters:
amount (int) – Quantidade de vida a ser restaurada
- id_player: int
- inventario: List[InventoryEntry]
- level_up()[source]
Tenta fazer o personagem subir de nível
- Returns:
True se subiu de nível
- Return type:
bool
- localizacao: str
- nivel: int
- nome: str
- take_damage(damage)[source]
Aplica dano ao personagem
- Parameters:
damage (int) – Quantidade de dano a ser aplicado
- Returns:
True se o personagem ainda está vivo após o dano
- Return type:
bool
- vida_atual: int
- vida_maxima: int
Exemplo de uso:
from src.models.player import Player
from src.models.inventory import InventoryEntry
# Criar um personagem
player = Player(
id_player=1,
nome="Steve",
vida_maxima=100,
vida_atual=85,
forca=12,
localizacao="Mapa 1 - Chunk 1",
nivel=1,
experiencia=150,
current_chunk_id=1
)
# Verificar se está vivo
if player.is_alive():
print("Personagem está vivo!")
# Aplicar dano
sobreviveu = player.take_damage(20)
# Ganhar experiência
player.gain_experience(50)
# Tentar subir de nível
if player.level_up():
print("Subiu de nível!")
# Exibir barra de vida
print(player.get_health_bar())
8.3. PlayerSession
A model PlayerSession representa um personagem ativo na sessão do jogo com informações otimizadas para performance.
- class models.player.PlayerSession(id_player, nome, vida_max, vida_atual, xp, forca, id_chunk_atual=None, chunk_bioma=None, chunk_mapa_nome=None, chunk_mapa_turno=None)[source]
Bases:
objectModel que representa um personagem ativo na sessão do jogo
- Variables:
id_player (int) – ID único do personagem no banco
nome (str) – Nome do personagem
vida_max (int) – Vida máxima do personagem
vida_atual (int) – Vida atual do personagem
xp (int) – Experiência acumulada
forca (int) – Força do personagem
id_chunk_atual (int | None) – ID do chunk onde o personagem está
chunk_bioma (str | None) – Nome do bioma atual (cache para performance)
chunk_mapa_nome (str | None) – Nome do mapa atual (cache para performance)
chunk_mapa_turno (str | None) – Turno atual (Dia/Noite) (cache para performance)
- can_move()[source]
Verifica se o personagem pode se mover
- Returns:
True se pode se mover
- Return type:
bool
- chunk_bioma: str | None = None
- chunk_mapa_nome: str | None = None
- chunk_mapa_turno: str | None = None
- forca: int
- gain_xp(amount)[source]
Adiciona experiência ao personagem
- Parameters:
amount (int) – Quantidade de XP a ser adicionada
- get_health_bar(width=20)[source]
Retorna uma barra de vida visual
- Parameters:
width (int) – Largura da barra em caracteres
- Returns:
String representando a barra de vida
- Return type:
str
- get_health_percentage()[source]
Retorna a porcentagem de vida atual
- Returns:
Porcentagem de vida (0.0 a 1.0)
- Return type:
float
- get_location_display()[source]
Retorna a localização formatada para exibição
- Returns:
String formatada da localização
- Return type:
str
- heal(amount)[source]
Cura o personagem
- Parameters:
amount (int) – Quantidade de vida a ser restaurada
- id_chunk_atual: int | None = None
- id_player: int
- nome: str
- take_damage(damage)[source]
Aplica dano ao personagem
- Parameters:
damage (int) – Quantidade de dano a ser aplicado
- Returns:
True se o personagem ainda está vivo após o dano
- Return type:
bool
- vida_atual: int
- vida_max: int
- xp: int
Exemplo de uso:
from src.models.player import PlayerSession
# Criar uma sessão de personagem
session = PlayerSession(
id_player=1,
nome="Steve",
vida_max=100,
vida_atual=85,
xp=150,
forca=12,
id_chunk_atual=5,
chunk_bioma="Oceano",
chunk_mapa_nome="Mapa_Principal",
chunk_mapa_turno="Dia"
)
# Verificar se pode se mover
if session.can_move():
print("Pode se mover!")
# Obter localização formatada
print(session.get_location_display())
# Converter para dicionário
data = session.to_dict()
8.4. Chunk
A model Chunk representa um chunk do mapa do jogo com suas coordenadas e relacionamentos.
- class models.chunk.Chunk(id_chunk, id_bioma, id_mapa, x, y)[source]
Bases:
objectModel que representa um chunk do mapa
- Variables:
id_chunk (int) – Identificador único do chunk (chave primária)
id_bioma (int) – FK para Bioma.id_bioma
id_mapa (int) – FK para Mapa.id_mapa
x (int) – Coordenada X do chunk no grid
y (int) – Coordenada Y do chunk no grid
- belongs_to_map(mapa_nome, mapa_turno)[source]
Verifica se o chunk pertence a um mapa específico
- Parameters:
mapa_nome (str) – Nome do mapa
mapa_turno (str) – Turno do mapa
- Returns:
True se o chunk pertence ao mapa
- Return type:
bool
- get_adjacent_chunk_ids(map_size=32)[source]
Retorna os IDs dos chunks adjacentes Baseado na lógica de grid do mapa
- Parameters:
map_size (int) – Tamanho do mapa (assumindo mapa quadrado)
- Returns:
Lista de IDs dos chunks adjacentes
- Return type:
List[int]
- get_bioma_type()[source]
Retorna o tipo de bioma como string
- Returns:
Nome do bioma
- Return type:
str
- get_display_name()[source]
Retorna o nome formatado do chunk para exibição
- Returns:
String formatada do chunk
- Return type:
str
- get_map_key()[source]
Retorna a chave do mapa como tupla
- Returns:
Tupla (nome_mapa, turno_mapa)
- Return type:
tuple
- id_bioma: int
- id_chunk: int
- id_mapa: int
- x: int
- y: int
Exemplo de uso:
from src.models.chunk import Chunk
# Criar um chunk
chunk = Chunk(
id_chunk=1,
id_bioma=2, # ID do bioma Oceano
id_mapa=1, # ID do mapa principal
x=10,
y=15
)
# Verificar tipo de bioma por ID
if chunk.id_bioma == 2:
print("É um oceano!")
# Obter nome formatado
print(chunk.get_display_name())
# Obter chunks adjacentes
adjacentes = chunk.get_adjacent_chunk_ids()
# Verificar se é dia ou noite baseado na coordenada
if chunk.is_day():
print("É dia neste chunk!")
8.5. Bioma
A model Bioma representa um bioma do jogo com suas características.
- class models.bioma.Bioma(id_bioma, nome, descricao)[source]
Bases:
objectModel que representa um bioma do jogo
- Variables:
id_bioma (int) – Identificador único do bioma (chave primária)
nome (str) – Nome do bioma
descricao (str) – Descrição do bioma
- descricao: str
- id_bioma: int
- nome: str
- class models.bioma.BiomaType(value)[source]
Bases:
EnumTipos de bioma disponíveis no jogo
- DESERTO = 'Deserto'
- FLORESTA = 'Floresta'
- OCEANO = 'Oceano'
- SELVA = 'Selva'
Biomas Predefinidos:
from src.models.bioma import BIOMAS_PREDEFINIDOS, BiomaType, Bioma
# Usar bioma predefinido
deserto = BIOMAS_PREDEFINIDOS[BiomaType.DESERTO]
# Criar bioma personalizado
bioma_custom = Bioma(
id_bioma=5,
nome="Tundra",
descricao="Um bioma frio e gelado."
)
# Comparar biomas
if deserto == bioma_custom:
print("São o mesmo bioma!")
8.6. Mapa
A model Mapa representa um mapa do jogo com seus chunks e características temporais.
- class models.mapa.Mapa(id_mapa, nome, turno, chunks=<factory>)[source]
Bases:
objectModel que representa um mapa do jogo
- Variables:
id_mapa (int) – Identificador único do mapa (chave primária)
nome (str) – Nome do mapa
turno (models.mapa.TurnoType) – Turno do mapa
chunks (List[models.chunk.Chunk]) – Lista de chunks relacionados a este mapa
_chunk_repository – Repository para acesso aos chunks (injeção de dependência)
- get_bioma_distribution()[source]
Retorna a distribuição de biomas no mapa
- Returns:
Dicionário com bioma e quantidade de chunks
- Return type:
Dict[str, int]
- get_chunk_by_id(chunk_id)[source]
Busca um chunk pelo ID neste mapa
- Parameters:
chunk_id (int) – ID do chunk
- Returns:
Chunk encontrado ou None
- Return type:
Chunk | None
- get_chunks_by_bioma(bioma)[source]
Retorna todos os chunks de um bioma específico neste mapa
- Parameters:
bioma (str) – Nome do bioma
- Returns:
Lista de chunks do bioma
- Return type:
List[Chunk]
- get_display_info()[source]
Retorna informações formatadas do mapa para exibição
- Returns:
Dicionário com informações do mapa
- Return type:
Dict[str, Any]
- id_mapa: int
- nome: str
- class models.mapa.TurnoType(value)[source]
Bases:
EnumTipos de turno disponíveis
- DIA = 'Dia'
- NOITE = 'Noite'
Exemplo de uso:
from src.models.mapa import Mapa, TurnoType
# Criar mapa
mapa = Mapa(
id_mapa=1,
nome="Mapa_Principal",
turno=TurnoType.DIA
)
# Verificar tipo de turno
if mapa.is_day_map():
print("É um mapa de dia!")
# Obter informações de exibição
info = mapa.get_display_info()
# Buscar chunk específico (requer repository configurado)
# mapa.set_chunk_repository(chunk_repository)
# chunk = mapa.get_chunk_by_id(1)
8.7. Item
A model Item representa um item do jogo que pode ser coletado ou usado.
- class models.item.Item(id_item, nome, tipo, poder=None, durabilidade=None)[source]
Bases:
objectRepresenta um item no inventário ou no jogo
- Variables:
id_item (int) – Identificador único do item (chave primária)
nome (str) – Nome do item
tipo (str) – Tipo do item (e.g., ‘Arma’, ‘Poção’, ‘Comida’)
poder (int | None) – Opcional, poder de ataque ou efeito do item
durabilidade (int | None) – Opcional, durabilidade restante
- durabilidade: int | None = None
- id_item: int
- nome: str
- poder: int | None = None
- tipo: str
Exemplo de uso:
from src.models.item import Item
# Criar diferentes tipos de itens
espada = Item(
id_item=1,
nome="Espada de Ferro",
tipo="Arma",
poder=8,
durabilidade=200
)
pocao = Item(
id_item=2,
nome="Poção de Vida",
tipo="Poção",
poder=50,
durabilidade=None # Poções não têm durabilidade
)
madeira = Item(
id_item=3,
nome="Madeira",
tipo="Material",
poder=None,
durabilidade=None
)
8.8. InventoryEntry
A model InventoryEntry representa uma entrada no inventário de um jogador.
- class models.inventory.InventoryEntry(id, player_id, item_id, quantidade)[source]
Bases:
objectRepresenta uma entrada de inventário (itens de um jogador)
- Variables:
id (int) – Identificador único da entrada (chave primária)
player_id (int) – FK para Player.id_player
item_id (int) – FK para Item.id_item
quantidade (int) – Quantidade do item possuído
- id: int
- item_id: int
- player_id: int
- quantidade: int
Exemplo de uso:
from src.models.inventory import InventoryEntry
# Criar entrada de inventário
entrada = InventoryEntry(
id=1,
player_id=1,
item_id=3, # Madeira
quantidade=64
)
# Modificar quantidade
entrada.quantidade += 32
print(f"Nova quantidade: {entrada.quantidade}")
8.9. Relacionamentos do Banco de Dados
As models refletem exatamente a estrutura do banco de dados:
Mapa (id_mapa, nome, turno) ← Chunk (id_mapa)
Bioma (id_bioma, nome) ← Chunk (id_bioma)
Chunk (id_chunk) ← Player (current_chunk_id)
Player (id_player) ← Inventario (player_id)
Item (id_item) ← Inventario (item_id)
Características dos Relacionamentos:
Mapa: Chave primária simples (id_mapa) com constraint única (nome, turno)
Bioma: Chave primária simples (id_bioma) com nome único
Chunk: Chave primária simples (id_chunk) com FKs para Bioma e Mapa
Player: Referencia Chunk através de current_chunk_id (pode ser NULL)
Item: Chave primária simples (id_item) com nome único
Inventario: Relacionamento N:M entre Player e Item com quantidades
8.10. Integração com o Sistema
As models são utilizadas em conjunto com o sistema de gerenciamento de personagens:
from src.models.player import Player
from src.utils.player_manager import get_current_player, set_current_player
from src.services.interface_service import InterfaceService
# Obter personagem ativo
current_player = get_current_player()
if current_player:
print(f"Jogando com: {current_player.nome}")
print(f"Localização: {current_player.localizacao}")
print(f"Vida: {current_player.get_health_bar()}")
# Usar interface service para operações
interface_service = InterfaceService.get_instance()
# Mover para outro chunk
updated_player = interface_service.move_player_to_chunk(current_player, 2)
# Salvar progresso
interface_service.save_player(updated_player)
8.11. Vantagens da Arquitetura de Models
Separação de Responsabilidades: Cada model tem responsabilidades bem definidas
Reutilização: Models podem ser usadas em diferentes partes do sistema
Manutenibilidade: Mudanças em uma model não afetam outras partes
Testabilidade: Cada model pode ser testada independentemente
Documentação: Models são auto-documentadas com docstrings
Type Safety: Uso de type hints para melhor desenvolvimento
Fidelidade ao Banco: Models refletem exatamente a estrutura do banco
Performance: PlayerSession otimizada para uso em sessões de jogo
8.12. Padrões de Uso
Player vs PlayerSession:
- Use Player para operações de persistência e dados completos
- Use PlayerSession para otimização de performance em sessões ativas
Localização:
- Player.localizacao armazena string formatada (“Mapa 1 - Chunk 1”)
- Player.current_chunk_id armazena referência direta ao chunk
- PlayerSession inclui cache de informações do chunk para performance
Inventário: - Relação N:M entre Player e Item através de InventoryEntry - Suporte a quantidades e controle de unicidade por constraint
8.13. Exemplos Avançados
Para ver exemplos completos de uso das models em cenários reais, consulte os testes unitários e os services do sistema.
Navegação entre Chunks:
# Obter chunk atual do jogador
current_chunk = interface_service.get_chunk_by_id(player.current_chunk_id)
# Obter chunks adjacentes
adjacent_chunks = interface_service.get_adjacent_chunks(current_chunk.id_chunk, 'Dia')
# Mover para chunk adjacente
if adjacent_chunks:
next_chunk_id = adjacent_chunks[0][0]
updated_player = interface_service.move_player_to_chunk(player, next_chunk_id)
Progressão de Personagem:
# Sistema de XP e level up
player.gain_experience(50)
while player.level_up():
print(f"Subiu para nível {player.nivel}!")
print(f"Nova vida máxima: {player.vida_maxima}")
print(f"Nova força: {player.forca}")
# Salvar progresso
interface_service.save_player(player)