SANAKA
Kālikā, Mors e um companheiro investigam cartas em uma taverna iluminada por lamparinas e habitada por espíritos.
← Voltar ao catálogo da Matrix

Matrix on-line · Laboratório 05

O jogo impossível de Kālikā

Escolha os gestos de Kālikā e Mors, jogue uma rodada e acompanhe como o programa decide quem vence.

Experimentar

Jogue antes de abrir as regras

Você escolhe os dois gestos. A mesma combinação sempre produz o mesmo resultado.

Etapa 1 de 3

Jogar uma rodada

Escolha os dois gestos e jogue. Pedra vence tesoura, tesoura vence papel e papel vence pedra. Gestos iguais empatam.

Compara os gestos escolhidos e mostra o resultado desta rodada.

O que aconteceu?

Os gestos estão escolhidos. Clique em “Jogar rodada” para avaliá-los.

Ver explicação técnica e código desta passagem

player e opponent guardam as entradas. O resultado começa em null até a avaliação.

TypeScriptkalika-game.ts
Função e condições
/** Função pura suficiente para três jogadas fixas. Não modifica suas entradas. */
export function playClassic(player: string, opponent: string): RoundOutcome | 'invalid' {
  if (!isMove(player, CLASSIC_MOVES) || !isMove(opponent, CLASSIC_MOVES)) {
    return 'invalid';
  }
  if (player === opponent) {
    return 'tie';
  }
  // && exige as duas condições; || aceita qualquer uma das três vitórias possíveis.
  const wins =
    (player === 'rock' && opponent === 'scissors') ||
    (player === 'paper' && opponent === 'rock') ||
    (player === 'scissors' && opponent === 'paper');
  // ?: escolhe um retorno. Uma vez removidos empates, não vencer significa perder.
  return wins ? 'win' : 'lose';
}
Inspecionar os registros antes e depois

Estes registros mostram a simulação em cada momento. Rever uma passagem muda o estado observado; agir a partir dela substitui o caminho que vinha depois.

Estado anterior

{
  "player": "rock",
  "opponent": "scissors",
  "variant": "conditions",
  "result": null,
  "inspectedRule": null,
  "inspectedRules": []
}

Estado observado

{
  "player": "rock",
  "opponent": "scissors",
  "variant": "conditions",
  "result": null,
  "inspectedRule": null,
  "inspectedRules": []
}
Testar uma situação pronta (opcional)

Cada opção escolhe os gestos por você e inicia a avaliação. “Entrada inválida” usa banana para mostrar uma escolha rejeitada.

Mostra a conclusão do percurso atual sem passar pelas inspeções restantes.

Escolha os gestos e clique em “Jogar rodada”.

Código em movimento

Se quiser ir além

Trecho 1 de 4
Consultar as funções e os arquivos

Funções completas deste laboratório, extraídas dos arquivos reais. A explicação da ação atual está junto do experimento.

TypeScriptkalika-game.ts
Função e condições
/** Função pura suficiente para três jogadas fixas. Não modifica suas entradas. */
export function playClassic(player: string, opponent: string): RoundOutcome | 'invalid' {
  if (!isMove(player, CLASSIC_MOVES) || !isMove(opponent, CLASSIC_MOVES)) {
    return 'invalid';
  }
  if (player === opponent) {
    return 'tie';
  }
  // && exige as duas condições; || aceita qualquer uma das três vitórias possíveis.
  const wins =
    (player === 'rock' && opponent === 'scissors') ||
    (player === 'paper' && opponent === 'rock') ||
    (player === 'scissors' && opponent === 'paper');
  // ?: escolhe um retorno. Uma vez removidos empates, não vencer significa perder.
  return wins ? 'win' : 'lose';
}
Função e condições

A implementação inicial realmente usada no modo de três gestos.

Onde estudar estes arquivos
Rever os conceitos
Antes das classes, uma função

Em palavras simples

Com três gestos, combinar quem vence quem numa pequena lista resolve o jogo. Uma ferramenta simples pode ser a escolha mais clara.

O conceito técnico

Uma função pura depende das entradas, devolve um resultado e não modifica dados externos. Condicionais expressam uma política fixa sem precisar de classes.

Regras que conversam pelo mesmo contrato

Em palavras simples

Uma pessoa confere empates, outra conhece a lista de vitórias. O jogo pergunta a ambas sem precisar saber como cada uma trabalha.

O conceito técnico

Composição reúne colaboradores. Encapsulamento controla o acesso aos detalhes. Polimorfismo permite chamar o mesmo contrato em implementações diferentes. Uma interface TypeScript descreve esse contrato na compilação.

Estender sem espalhar condicionais

Em palavras simples

Mors não precisa reescrever a mesa inteira para trazer novas relações. Precisa declarar as novas possibilidades e conferir se as antigas continuam válidas.

O conceito técnico

Open/Closed orienta a projetar pontos de extensão que evitem modificar o motor a cada política nova. Não proíbe toda alteração de código. Aqui, a extensão é configuração e composição, não uma hierarquia grande.

Testar exemplos

Confira o que aprendeu

Abrir exemplos de verificação

Este botão roda exemplos prontos e compara os resultados. Ele não altera sua experiência.

Explorar

Continue explorando

E se a entrada for vazia?

Ela não pertence ao conjunto de gestos e produz invalid. Acrescente esse caso ao teste antes de modificar a validação.

E se ambos repetirem o mesmo gesto?

TieRule decide empate antes da dominância. No modo função, o teste de igualdade cumpre a mesma responsabilidade.

E se Mors trouxer uma regra nova?

Implemente RoundRule ou configure novos pares. Escolha conscientemente a ordem: a primeira regra que decide vence. Teste conflitos e combinações antigas.

Em que situação você manteria só a função?

Quando os três gestos forem estáveis e a função continuar clara. Extensibilidade não compensa automaticamente mais arquivos e indireção.