O Jogo dos 21 (também conhecido em teoria dos jogos como uma variação do Jogo de Nim ou Jogo de Bachet) é um clássico exercício de lógica matemática e programação. A dinâmica básica consiste em dois participantes alternando turnos para contar números consecutivamente — geralmente somando de 1 a 3 unidades a partir do número anterior — até que alguém atinja 21. Apesar de parecer trivial, implementar uma versão de linha de comando robusta, que trate exceções de entrada humana e integre uma inteligência artificial funcional, exige organização arquitetural e boas práticas de código.
Estrutura e Regras da Simulação
No formato padrão adotado:
- O jogo começa em zero.
- Em cada turno, o jogador ativo escolhe somar 1, 2 ou 3 ao total atual.
- O jogador que alcançar exatamente 21 vence a partida (ou perde, caso adotada a regra ‘misère’). No exemplo implementado, o objetivo é alcançar exatamente o número 21.
- O software valida cada jogada humana para impedir valores fora do intervalo permitido ou que ultrapassem o limite estipulado.
Implementação Técnica em Python
Para garantir legibilidade e facilidade de manutenção, dividimos a solução em módulos bem definidos: verificação de integridade de dados, motor do jogo e lógica do oponente artificial.
python
import random
import time
class Jogo21:
def init(self):
self.total = 0
self.alvo = 21
self.limite_passo = 3
def jogada_usuario(self):
while True:
try:
escolha = int(input(f"Total atual: {self.total}. Quanto deseja somar (1-{self.limite_passo})? "))
if 1 <= escolha <= self.limite_passo and self.total + escolha <= self.alvo:
return escolha
print(f"Escolha inválida. Insira um número entre 1 e {self.limite_passo} que não ultrapasse {self.alvo}.")
except ValueError:
print("Entrada inválida. Digite um número inteiro.")
def jogada_ia_facil(self):
print(f"nTotal atual: {self.total}. Vez da IA...")
time.sleep(0.8)
max_possivel = min(self.limite_passo, self.alvo - self.total)
# Se puder vencer nesta rodada, a IA aproveita
if max_possivel == self.alvo - self.total:
escolha = max_possivel
else:
# Comportamento 'Easy': escolhe aleatoriamente entre as jogadas permitidas
escolha = random.randint(1, max_possivel)
print(f"A IA somou {escolha}.")
return escolha
def executar(self):
print("=== BEM-VINDO AO JOGO DOS 21 ===")
turno_jogador = True
while self.total < self.alvo:
if turno_jogador:
print("n--- Seu Turno ---")
self.total += self.jogada_usuario()
if self.total == self.alvo:
print(f"nParabéns! Você atingiu {self.alvo} e venceu!")
break
else:
self.total += self.jogada_ia_facil()
if self.total == self.alvo:
print(f"nA IA atingiu {self.alvo} e venceu a partida.")
break
turno_jogador = not turno_jogador
if name == ‘main‘:
jogo = Jogo21()
jogo.executar()
Otimização e Comportamento da IA
Como especialista em IA e arquitetura de software, destaco que a modelagem de agentes computacionais em jogos por turnos depende diretamente da intenção de design. Para um modo classificado como ‘Easy’ (fácil), a IA deve cometer erros calculados e alternar escolhas pseudoaleatórias dentro do espaço de estados válidos.
Caso o objetivo fosse criar uma IA imbatível, aplicaríamos a fórmula matemática dos pontos de controle: (alvo - total) % (limite_passo + 1) == 0. Qualquer desvio do oponente permitiria ao algoritmo forçar a vitória sistematicamente. No entanto, equilibrar desafios para manter o engajamento do usuário exige exatamente a flexibilização implementada no código acima, tornando o jogo dinâmico e acessível.
Conclusão e Próximos Passos
O desenvolvimento de scripts limpos, documentados e orientados a objetos estabelece a base para projetos mais complexos de automação e tomada de decisão computacional em Python.
Se a sua empresa precisa construir protótipos inteligentes, scripts de automação sob medida ou integrar modelos de decisão lógica e IA em sistemas existentes, agende uma consultoria técnica com Thiago Programador e acelere o desenvolvimento das suas soluções.


