Это мои счастливые кости [закрыто]


10

Реализуйте программу или функцию, которая имитирует обычные кости для ролевых игр. Он должен обрабатывать как минимум d6 и d20, два самых распространенных кубика.

Тем не менее, он должен работать так, как ожидают от него стереотипные геймеры, а не как настоящая игра в кости.

Это игра в шутку между игроками, что можно получить особенно удачный кубик для очень очень важного броска, предварительно бросив много кубиков, выбрав те, которые привели к «1», затем бросая их снова, пока вы не получите несколько, которые бросили "1" несколько раз. Затем вы тщательно сохраняете их, потому что они бросают 1 несколько раз подряд, поэтому вероятность бросить 1 в следующий раз должна быть чрезвычайно низкой.

Конечно, это не так, как кости работают в реальной жизни , потому что броски являются статистически независимыми.

Ваши смоделированные кубики должны учитывать предыдущие броски и работать так же, как и игрок, ошибочно полагая, что он сработает. Например, если выпало много младших чисел, вероятность увеличения большего числа должна быть увеличена.

Однако, поскольку это обман, вы должны хорошо это скрывать . Это означает, что случайный взгляд на программу не должен показывать, что вы обманули. Это означает, что явно сохранять предыдущие результаты и читать их при каждом броске было бы слишком подозрительно. Вы должны скрыть это «свойство» ваших костей и бонусные очки, если вы сделаете его правдоподобным, отрицающим и замаскируете его как честную ошибку. (например, вы делаете свой собственный ГСЧ с «непреднамеренным» недостатком)

Избиратели, примите во внимание, насколько хорошо скрыт этот «недостаток».

Программы должны быть понятными, а не запутанными. Слишком легко спрятать злой код в запутанной программе.


3
Насколько хорошо мы спрятаны? ИМО, что-либо за пределами языкового эквивалента getRandomBetween(1,d)заставило бы меня глубже вникнуть в это.
Geobits

@Geobits: вы можете найти очень хороший пример того, как решить скрытые проблемы, здесь: codegolf.stackexchange.com/questions/19569/… Я имею в виду, что вы можете сделать что-нибудь, если вы достаточно хорошо это оправдываете, конечно, оправдание может быть большая ложь.
вс

Godmaydamnit, Java не хватает причуд для закулисных вещей ...
masterX244


4
Я голосую, чтобы закрыть этот вопрос как не по теме, потому что закулисные вызовы сейчас не по теме, и каким-то образом этот вопрос ускользнул от радаров.
Мего

Ответы:


3

Ява

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

Это так просто, что он, очевидно, ничего не скрывает: он java.util.Randomявляется прямым линейным конгруэнтным генератором и использует метод отбрасывания для обеспечения однородности, поэтому он гарантирует, что при любом запуске наибольшего кратного из sizeменее чем 2 48 выборок он будет распределять числа равномерно, удовлетворяющие требованию.


не могу объяснить, как работает java.util.random
masterX244

Отбрасывание, которое java.util.Randomвыполняет, имеет очень мало общего с поведением этого ответа. На самом деле, этот ответ основан на том факте, что, как и у любого ГСЧ, java.util.Randomесть период, и если вы генерируете число чисел порядка этого периода, его статистические свойства нарушаются. Это не очень интересно; то же самое произошло бы даже с криптографически защищенным ГСЧ, таким как Blum Blum Shub, если вы выполняете его достаточно долго.
user2357112 поддерживает Monica

@ user2357112, отбрасывание актуально, потому что вопрос требует единообразия, а не небольшого смещения к меньшим числам. По моему мнению, этот ответ олицетворяет скрытность: преднамеренное использование стандартной библиотеки способом, который на первый взгляд кажется прозрачно правильным, но на самом деле выводит его за пределы проектных параметров.
Питер Тейлор

Тем не менее, почти каждый ГСЧ отбрасывает вещи. Ничего особенного Вы могли бы использовать этот ответ буквально с любым генератором псевдослучайных чисел, потому что, если ГСЧ 1) имеет период и 2) может произвести более 1 различного числа, то в пределах одного периода, чем больше число появилось относительно других чисел, тем меньше он будет отображаться до следующего периода с помощью простого аргумента подсчета.
user2357112 поддерживает Monica

Анализ в этом ответе требует порядка 2 ^ 48 бросков для проявления эффекта. Может быть, если бы вы использовали более сложный анализ, показывающий, что использование LCG приводит к появлению измеримых статистических аномалий в течение ряда бросков, которые правдоподобно появляются в настольной игре, это может быть правильным ответом. Когда вы говорите о триллионах рулонов, это просто не очень закулисно.
user2357112 поддерживает Monica

0

Рубин

В настоящее время поддерживает только d6, позже добавлю поддержку d20 ...

И вот, эти кубики противны!

# 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])
...

Я бы добавил "abort", требующий ruby ​​2 ", если где-то там RUBY_VERSION <" 2 "', как будто вы запускаете его на более ранних версиях, это портит трюк
bazzargh

0

Haskell

Используйте одну случайную вещь, чтобы сделать другую случайную вещь: в этом случае перетасуйте карты, чтобы генерировать броски костей.

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

Принимает один аргумент, количество лиц на кубике. Вывод такой:

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

... и так далее для всех карт (сбросы не печатаются). Слишком очевидно?

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.