Ce sont mes dés chanceux [fermé]

10

Mettez en œuvre un programme ou une fonction qui simule des dés communs pour les jeux de rôle. Il devrait gérer au moins le d6 et le d20, les deux dés les plus courants.

Cependant, cela devrait fonctionner comme les joueurs stéréotypés s'attendent à ce qu'ils fonctionnent, et non comme de vrais dés.

C'est une blague entre les joueurs, que l'on peut avoir un dé particulièrement chanceux pour un jet très très important, en lançant précédemment beaucoup de dés, en sélectionnant ceux qui ont abouti à un "1", puis en les lançant à nouveau, jusqu'à ce que vous obteniez quelques-uns qui ont obtenu un "1" plusieurs fois. Vous les conservez ensuite soigneusement, car ils ont roulé un 1 plusieurs fois de suite, de sorte que la probabilité de lancer un 1 la prochaine fois devrait être extrêmement faible.

Bien sûr, ce n'est pas ainsi que les dés fonctionnent dans la vraie vie , car les jets sont statistiquement indépendants.

Vos dés simulés doivent prendre en compte les jets précédents et fonctionner de la même manière que le joueur dans l'erreur du joueur s'attend à ce qu'il fonctionne. Par exemple, si de nombreux nombres faibles ont été obtenus, la probabilité de lancer un nombre plus élevé doit être augmentée.

Cependant, comme c'est de la triche, vous devez bien le cacher . Cela signifie qu'un simple coup d'œil sur le programme ne doit pas révéler que vous avez triché. Cela signifie que sauvegarder explicitement les résultats précédents et les lire à chaque lancer serait trop suspect. Vous devez cacher cette "propriété" de vos dés et des points bonus si vous la rendez plausible et que vous la dissimulez comme une erreur honnête. (par exemple, vous créez votre propre RNG avec un défaut "non intentionnel")

Votants, veuillez tenir compte de la façon dont cette "faille" est bien cachée.

Les programmes doivent être clairs et non obscurcis. Il est trop facile de cacher le code malveillant dans un programme obscurci.

vsz
la source
3
Comment bien caché parlons-nous? OMI, tout ce qui est au-delà de l'équivalent de la langue getRandomBetween(1,d)me ferait approfondir.
Geobits
@Geobits: vous pouvez trouver un très bel exemple pour résoudre les problèmes sournois ici: codegolf.stackexchange.com/questions/19569/… Je veux dire que vous pouvez tout faire si vous le justifiez suffisamment, bien sûr, la justification peut être un gros mensonge.
vsz
Godmaydamnit, java n'a pas assez de bizarreries pour des trucs sournois ...
masterX244
4
Je vote pour fermer cette question comme hors sujet parce que les défis sournois sont hors sujet maintenant, et en quelque sorte celui-ci a glissé sous le radar.
Mego

Réponses:

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;
    }
}

C'est si simple qu'il ne cache évidemment rien: mais java.util.Randomc'est un générateur congruentiel linéaire simple, et il utilise une technique de rejet pour assurer l'uniformité, donc il garantit que dans n'importe quelle série du plus grand multiple de sizemoins de 2 ^ 48 échantillons, il distribuera le les chiffres uniformément, satisfaisant à l'exigence.

Peter Taylor
la source
n'arrive pas à expliquer comment fonctionne java.util.random
masterX244
Le rejet qui java.util.Randomfonctionne a très peu à voir avec le comportement de cette réponse. Vraiment, ce sur quoi repose cette réponse est le fait que, comme tout RNG, java.util.Randoma une période, et si vous générez un certain nombre de nombres dans l'ordre de la période, ses propriétés statistiques se décomposent. Ce n'est pas très intéressant; la même chose se produirait même avec un RNG sécurisé cryptographiquement comme Blum Blum Shub si vous le faisiez fonctionner assez longtemps.
user2357112 prend en charge Monica
@ user2357112, la mise au rebut est pertinente car la question nécessite l'uniformité, pas un petit biais pour les petits nombres. À mon avis, cette réponse incarne la sournoise: l'utilisation délibérée d'une bibliothèque standard d'une manière qui, à première vue, semble correcte et transparente, mais la place en fait en dehors de ses paramètres de conception.
Peter Taylor
Quasiment tous les RNG font le rejet, cependant. Ce n'est rien de spécial. Vous auriez pu utiliser cette réponse avec littéralement n'importe quel générateur de nombres pseudo-aléatoires, car si un RNG 1) a une période, et 2) peut produire plus d'un nombre différent, alors dans le cadre d'une seule période, plus un nombre est apparu par rapport aux autres nombres, moins il apparaîtra jusqu'à la période suivante par un simple argument de comptage.
user2357112 prend en charge Monica
L'analyse dans cette réponse nécessite de l'ordre de 2 ^ 48 rouleaux pour qu'un effet apparaisse. Peut-être que si vous aviez utilisé une analyse plus sophistiquée, montrant que l'utilisation d'un LCG fait apparaître des anomalies statistiques mesurables dans un certain nombre de rouleaux qui apparaîtraient vraisemblablement dans un jeu de table, cela pourrait être une bonne réponse. Quand vous parlez de billions de rouleaux, cependant, ce n'est tout simplement pas très sournois.
user2357112 prend en charge Monica
0

Rubis

Actuellement ne prend en charge que d6, ajoutera la prise en charge d20 plus tard ...

Et voilà, ces dés sont méchants!

# 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
la source
J'ajouterais qu'un "abandon" nécessite ruby ​​2 "si RUBY_VERSION <" 2 "'quelque part, comme si vous l'
exécutiez
0

Haskell

Utilisez une chose au hasard pour en faire une autre au hasard: dans ce cas, mélangez les cartes pour générer des lancers de dés.

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

Prend un argument, le nombre de faces sur le dé. La sortie est comme ceci:

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

... et ainsi de suite pour toutes les cartes (les rejets ne sont pas imprimés). Trop évident?

bazzargh
la source