Estes são os meus dados da sorte [fechado]

10

Implemente um programa ou função que simule dados comuns para jogos de RPG. Ele deve lidar com pelo menos o d6 e o ​​d20, os dois dados mais comuns.

No entanto, deve funcionar como jogadores estereotipados esperam que eles funcionem, e não como dados reais.

É uma piada entre os jogadores, que se pode ter um dado especialmente sortudo por um lançamento muito importante, jogando muitos dados anteriormente, selecionando aqueles que resultaram em um "1" e depois jogando-os novamente, até que você obtenha alguns que rolaram um "1" várias vezes. Em seguida, você os preserva com cuidado, porque eles rolaram um 1 várias vezes em sequência, portanto a probabilidade de rolar um 1 na próxima vez deve ser extremamente baixa.

Obviamente, não é assim que os dados funcionam na vida real , porque os lançamentos são estatisticamente independentes.

Seus dados simulados precisam levar em consideração as jogadas anteriores e funcionar da mesma forma que o jogador na falácia do jogador espera que ele funcione. Por exemplo, se muitos números baixos forem rolados, a probabilidade de rolar um número maior deve ser aumentada.

No entanto, como isso é trapaça, você precisa escondê-lo bem . Isso significa que uma olhada casual no programa não deve revelar que você trapaceou. Isso significa que salvar explicitamente os resultados anteriores e lê-los a cada lançamento seria muito suspeito. Você precisa ocultar essa "propriedade" dos seus dados e pontos de bônus se a tornar plausível negável e disfarçá-la como um erro honesto. (por exemplo, você cria seu próprio RNG com uma falha "não intencional")

Eleitores, por favor, levem em conta o quão bem oculta essa "falha" está.

Os programas devem ser claros e não ofuscados. É muito fácil ocultar códigos maliciosos em um programa ofuscado.

vsz
fonte
3
Quão bem escondidos estamos falando? Na IMO, qualquer coisa além do equivalente ao idioma getRandomBetween(1,d)me levaria a aprofundar o assunto.
Geobits
@ Geobits: você pode encontrar um exemplo muito bom de como resolver problemas ocultos aqui: codegolf.stackexchange.com/questions/19569/… Quero dizer que você pode fazer qualquer coisa se justificar bem o suficiente, é claro, a justificativa pode ser uma grande mentira.
vsz
Godmaydamnit, java does not tem peculiaridades suficientes para coisas dissimulado ...
masterX244
4
Estou votando para encerrar esta questão como fora de tópico, porque os desafios ocultos agora estão fora de tópico e, de alguma forma, este passou despercebido.
Mego4

Respostas:

3

Java

public class GamerDie {
    private final java.util.Random rnd;
    private final int sides;

    public GamerDie(int sides) {
        this.sides = sides;
        this.rnd = new java.util.Random();
    }

    public int throw() {
        return rnd.nextInt(sides) + 1;
    }
}

É tão simples que obviamente não está escondendo nada: mas java.util.Randomé um gerador congruencial linear direto e usa uma técnica de descarte para garantir uniformidade, garantindo assim que, em qualquer execução do maior múltiplo de sizemaior que 2 ^ 48 amostras, ele distribuirá o uniformemente, satisfazendo o requisito.

Peter Taylor
fonte
não pode ficar atrás do explicar como funciona java.util.Random
masterX244
O descarte que java.util.Randomexecuta tem muito pouco a ver com o comportamento dessa resposta. Realmente, o que esta resposta se baseia é o fato de que, como qualquer RNG, java.util.Randompossui um período, e se você gerar um número de números na ordem do período, suas propriedades estatísticas serão quebradas. Isso não é muito interessante; o mesmo aconteceria com um RNG criptograficamente seguro como Blum Blum Shub se você o executasse por tempo suficiente.
User2357112 suporta Monica
@ user2357112, o descarte é relevante porque a pergunta requer uniformidade, não um pequeno viés para números menores. Na minha opinião, essa resposta resume a falta de clareza: o uso deliberado de uma biblioteca padrão de uma maneira que, à primeira vista, parece transparentemente correta, mas na verdade a tira fora de seus parâmetros de design.
Peter Taylor
Porém, praticamente todo RNG faz a coisa de descarte. Não é nada de especial. Você poderia ter usado essa resposta com literalmente qualquer gerador de números pseudoaleatórios, porque se um RNG 1) possui um período e 2) pode produzir mais de um número diferente, então, no escopo de um único período, mais um número apareceu em relação a outros números, menos ele aparecerá até o próximo período com um simples argumento de contagem.
User2357112 suporta Monica
A análise nesta resposta requer da ordem de 2 ^ 48 rolos para que um efeito apareça. Talvez se você tivesse usado uma análise mais sofisticada, mostrando que o uso de um LCG faz com que anomalias estatísticas mensuráveis ​​apareçam em vários rolos que apareceriam plausivelmente em um jogo de mesa, essa pode ser uma resposta correta. Quando você está falando de trilhões de rolos, porém, isso não é muito discreto.
User2357112 suporta Monica
0

Rubi

Atualmente, suporta apenas d6, adicionará suporte ao d20 mais tarde ...

Eis que esses dados são desagradáveis!

# first idea was to create 6 super cool dices just by copy&paste
# -> each dice holds its number at the beginning of the array
# -> we don't need all of them now, so we comment them out
dice0 = %w[[[[[[[[[ 0 . : :. :: ::. ::: ]]]]]]]]
#dice1 = %w[[[[[[[ 1 : . :. ::. :: ::: ]]]]]]]
#dice2 = %w[[[[[[ 2 . : :. :: ::. ::: ]]]]]]
#dice3 = %w[[[[[[ 3 : . :. ::. :: ::: ]]]]]]]
#dice4 = %w[[[[[[[ 4 . : :. :: ::: ::. ]]]]]]]
#dice5 = %w[[[[[[[[ 5 . : :. :: ::. ::: ]]]]]]]]]

# and hey, those dices are almost ascii art ;)

# well, let's just create a standard dice
# -> get rid of the number at the beginning
# -> then sort (maybe we need that later due to the
#    currently unused dices being unsorted)
dice = dice0.select!{|e| /[:.]+/ === e}.sort

def roll(d)
  # rolling is easy
  # -> use size instead of hardcoded number,
  #   maybe we'll have other dices later
  d.slice!(rand(d.size - 1))
end

# and here you have 8 very underhanded dices!
dices = [dice]*8

# roll like a champion
roll(dices[0])
...
David Herrmann
fonte
Eu adicionaria um "abortar 'requer ruby 2' se RUBY_VERSION < '2'' em algum lugar, como se você executá-lo em versões anteriores estraga o truque
bazzargh
0

Haskell

Use uma coisa aleatória para criar outra coisa aleatória: nesse caso, embaralhe as cartas para gerar jogadas de dados.

import System.Environment
import System.Random
import Data.Array.IO
import Control.Monad
-- make random dice from random cards
suit c=map (\(a,b)->[a,b])$zip "A23456789TJQK" (repeat c)
deck=concatMap(\s->suit s) "♠♥♦♣"
-- just like casinos, use more decks for extra randomness
decks=concat$take 8$repeat deck
-- shuffle the cards
shuffle :: [a] -> IO [a]
shuffle xs = do
        ar <- newArray n xs
        forM [1..n] $ \i -> do
            j <- randomRIO (i,n)
            vi <- readArray ar i
            vj <- readArray ar j
            writeArray ar j vi
            return vj
  where
    n = length xs
    newArray :: Int -> [a] -> IO (IOArray Int a)
    newArray n xs =  newListArray (1,n) xs
-- convert a card to a die, by counting along the original deck
-- then taking mod (faces). If we don't have enough cards to make
-- a full set of faces, assign the 'extra' cards a value of 0
card2die faces card=
  let index=(head[i|(i,c)<-zip[0..]deck,c==card]) in
  if (index > (length deck-(length deck`mod`faces)))
  then 0
  else (index`mod`faces)+1
main=
  do
    args <- getArgs
    let faces = read (args!!0)
    -- throw away cards we can't map to die faces
    cards<-shuffle$filter (\card->card2die faces card/=0) decks
    mapM_ (\card->putStrLn (card++" -> "++(show (card2die faces card)))) cards

Leva um argumento, o número de faces no dado. A saída é assim:

./cards 20|head
2♦ -> 8
7♥ -> 20
J♦ -> 17
6♥ -> 19
9♥ -> 2
8♥ -> 1
5♥ -> 18
4♠ -> 4
Q♥ -> 5
2♣ -> 1

... e assim por diante para todos os cartões (os descartes não são impressos). Muito óbvio?

bazzargh
fonte