Depois de semanas de expetativa, tu e os teus amigos reúnem-se para a vossa primeira partida de Dungeons & Dragons (D&D). Como esta é a primeira sessão do jogo, cada jogador tem de criar uma personagem para jogar. Os atributos da personagem são determinados pelo lançamento de dados de 6 faces, mas onde estão os dados? Com um sobressalto, percebes que os teus amigos estão à espera que tu arranjes os dados; afinal de contas, foi tua ideia jogar D&D! Entras em pânico ao perceberes que te esqueceste de trazer os dados, o que significaria não haver jogo de D&D. Como tens alguns conhecimentos básicos de programação, arranjas rapidamente uma solução: vais escrever um programa para simular lançamentos de dados.
Num jogo de Dungeons & Dragons, cada jogador começa por gerar uma personagem com a qual possa jogar. Essa personagem tem, entre outras coisas, seis atributos: strength, dexterity, constitution, intelligence, wisdom e charisma. Estes seis atributos têm valores determinados aleatoriamente. Fazes isto lançando quatro dados de 6 faces e registando a soma dos três dados mais altos. Fazes isto seis vezes, uma vez para cada atributo.
Os hitpoints iniciais da tua personagem são 10 + o modificador de constitution da tua personagem. Encontras o modificador de constitution da tua personagem subtraindo 10 à constitution da tua personagem, dividindo por 2 e arredondando para baixo.
Escreve um gerador aleatório de personagens que siga as regras acima.
Por exemplo, os seis lançamentos de quatro dados podem ser assim:
Como a constitution é 3, o modificador de constitution é -4 e os hitpoints são 6.
A maioria das linguagens de programação tem geradores (pseudo)aleatórios, mas poucas linguagens de programação são feitas para lançar dados. Uma dessas linguagens é Troll.
A biblioteca padrão do Zig evita estado global oculto, por isso, em vez de manteres o teu próprio gerador de números aleatórios, as tuas funções recebem uma interface std.Random de onde podem extrair valores.
Os testes passam um gerador com semente std.testing.random_seed, e verificam que geradores com a mesma semente produzem os mesmos carateres.
A distribuição das tuas pontuações de atributo é verificada por testes de qui-quadrado a um nível de significância de p < 0.0001:
ability são comparadas com a distribuição esperada;Uma implementação correta tem menos de 0,01% de probabilidade de falhar cada teste.
Consulta as instruções acima para uma definição do que é uma pontuação de atributo.
Inscreve-te no Exercism para aprenderes e dominares Zig com 104 exercícios, e mentoria humana real, tudo grátis.
Exploramos como gerar lançamentos de dados (aparentemente) aleatórios. Vais aprender sobre sementes, números pseudoaleatórios e algumas armadilhas comuns. Por fim, vemos porque é que os testes baseados em propriedades são excelentes para testar funções que devolvem valores aleatórios.