Capítulo 19: Projeto Integrador I: Motor Completo de Jogo de Xadrez em Python POO Pura
Especialização em Sistemas com Python & POO com Type Hints • Capítulo 19
🗺️ Mapa Conceitual do Tópico
flowchart TD
subgraph BOARD_DOMAIN["Domínio do Tabuleiro e Coordenadas"]
COORD["Notação Algébrica ('a1'..'h8') ↔ Matriz 2D [0..7, 0..7]\nConversão Algorítmica r = 8 - rank, c = ord(col) - ord('a')"]
BOARD["Classe Tabuleiro\nGrade Bidimensional 8x8 de Ponteiros (Peca | None)"]
end
subgraph PIECES_POLY["Hierarquia Polimórfica de Peças"]
PECA["Classe Abstrata Peca (ABC)\n#Cor cor · #Tabuleiro tabuleiro · int qtd_movimentos"]
SLIDING["Peças Deslizantes (Sliding Pieces)\nTorre (Retas) · Bispo (Diagonais) · Dama (Combinada)"]
STEPPING["Peças de Passo (Stepping Pieces)\nRei (Vizinhança 1) · Cavalo (Deltas em L: 8 opções) · Peão"]
end
subgraph ENGINE["Orquestrador da Partida (Engine)"]
MATCH["PartidaXadrez (Aggregate Root)\nTurno · Jogador Ativo · Validação de Xeque e Xeque-Mate"]
ATOMIC_MOVE["executar_movimento(): Simula Lance → Valida Rei Seguro → Confirma"]
end
COORD --> BOARD
BOARD --> PIECES_POLY
PIECES_POLY --> ENGINE
ENGINE --> CLI["Renderização no Terminal via Símbolos Unicode e Cores ANSI"]
style BOARD_DOMAIN fill:#ede7f6,stroke:#512da8,stroke-width:2px
style PIECES_POLY fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
style ENGINE fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
♟️ 1. O Desafio Arquitetural do Motor de Xadrez
O Projeto Integrador I desafia o estudante a projetar e implementar um motor de xadrez em Python puro, aplicando todos os pilares consolidados da orientação a objetos corporativa:
- Herança e Polimorfismo Nominal (
abc.ABC): Cada tipo de peça de xadrez implementa de forma independente seu algoritmo de cálculo de movimentos legais. - Encapsulamento e Invariantes: O tabuleiro protege sua grade interna bidimensional, impedindo que peças se sobreponham ilegalmente ou saltem para fora das 64 casas.
- Modelagem de Domínio Rica: Enums semânticos de cor, objetos de posição imutáveis e agregação de regras de jogo (xeque, xeque-mate e promoção).
📐 2. Álgebra de Coordenadas Algébricas e Matriz 2D
O xadrez humano utiliza coordenadas alfanuméricas (colunas de a até h e fileiras de 1 até 8). O computador processa uma matriz bidimensional contígua $8 \times 8$ com índices de $0$ a $7$:
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class PosicaoXadrez:
coluna: str # 'a' a 'h'
linha: int # 1 a 8
def para_indices(self) -> tuple[int, int]:
r = 8 - self.linha
c = ord(self.coluna.lower()) - ord('a')
return r, c
@classmethod
def de_indices(cls, r: int, c: int) -> "PosicaoXadrez":
col = chr(ord('a') + c)
lin = 8 - r
return cls(coluna=col, linha=lin)
👑 3. Polimorfismo das Peças: Peças Deslizantes vs Passo Único
A classe abstrata Peca obriga todas as peças a devolverem uma matriz booleana $8 \times 8$ com suas intenções de movimento:
from abc import ABC, abstractmethod
class Peca(ABC):
def __init__(self, tabuleiro: "Tabuleiro", cor: "Cor") -> None:
self.tabuleiro = tabuleiro
self.cor = cor
self.qtd_movimentos: int = 0
@abstractmethod
def movimentos_possiveis(self) -> list[list[bool]]:
"""Retorna matriz 8x8 onde True indica casas alcançáveis."""
...
Algoritmos de Deslocamento:
- Peças Deslizantes (Sliding - Torre, Bispo, Dama): Projetam raios em direções vetoriais $(\Delta r, \Delta c)$ até encontrar a borda do tabuleiro ou outra peça. Se for adversária, marca a captura e interrompe o raio; se for aliada, interrompe imediatamente antes.
- Peças de Salto (Stepping - Rei e Cavalo): Avaliam um conjunto finito de vetores discretos (o Cavalo possui exatamente 8 saltos em L possíveis: $(\pm 1, \pm 2)$ e $(\pm 2, \pm 1)$), testando se a casa de pouso é livre ou abriga adversário.
🛡️ 4. O Agregado Raiz PartidaXadrez e a Validação de Xeque
A inteligência da partida reside em um ciclo em três tempos:
- O jogador escolhe a peça de origem e o destino desejado.
- A partida simula o movimento provisoriamente no tabuleiro.
- Se o movimento deixar o próprio Rei do jogador sob ataque (em estado de Xeque), o lance é imediatamente desfeito (Rollback) e uma exceção de domínio
XadrezError("Você não pode se colocar em xeque!")é lançada.
sequenceDiagram
participant Jogador
participant Engine as PartidaXadrez
participant Tabuleiro
Jogador->>Engine: executar_jogada(e2, e4)
Engine->>Tabuleiro: mover_provisorio(e2, e4)
Engine->>Engine: testar_rei_em_xeque(Cor.BRANCA)
alt Rei sob Ataque
Engine->>Tabuleiro: desfazer_movimento()
Engine-->>Jogador: Erro: Lance ilegal (Rei em Xeque)
else Rei Seguro
Engine->>Engine: confirmar_captura_e_avancar_turno()
Engine-->>Jogador: Lance Válido (Vez das Pretas)
end