이것들은 내 행운의 주사위입니다.


10

롤 플레잉 게임의 일반적인 주사위를 시뮬레이션하는 프로그램 또는 기능을 구현합니다. 최소한 두 개의 가장 일반적인 주사위 인 d6과 d20을 처리해야합니다.

그러나 전형적인 게이머가 실제 주사위 작업이 아니라 작동하기를 기대하는 것처럼 작동해야합니다.

이전에는 많은 주사위를 던지고 "1"을 얻은 주사위를 선택한 다음 다시 던질 때까지 매우 중요한 롤을 위해 특별히 운이 좋은 주사위를 가질 수 있다는 것은 게이머 사이의 농담입니다. "1"을 여러 번 굴린 몇 개. 그런 다음 순서대로 1을 여러 번 굴렸으므로 다음에 1을 굴릴 확률이 매우 낮아야합니다.

롤이 통계적으로 독립적이기 때문에 이것은 실제 생활에서 주사위가 작동하는 방식아닙니다 .

시뮬레이션 된 주사위는 이전 롤을 고려해야하며, 도박꾼의 잘못에있는 도박꾼이 예상하는 방식과 비슷하게 작동해야합니다. 예를 들어, 낮은 숫자가 많이 굴리면 높은 숫자를 굴릴 확률이 높아져야합니다.

그러나 이것이 속임수 이므로 잘 숨겨야합니다 . 즉, 프로그램을 간단히 살펴보면 속임수를 밝히지 않아야합니다. 즉, 이전 결과를 명시 적으로 저장하고 모든 던지기에서 결과를 읽는 것은 너무 의심됩니다. 주사위의이 "속성"과 숨겨야 할 보너스 포인트를 정직한 실수로 위장하면 보너스 포인트를 숨겨야합니다. (예를 들어, "의도하지 않은"결함으로 자신의 RNG를 만듭니다)

유권자 여러분,이 "결함"이 얼마나 숨겨져 있는지 고려하십시오.

프로그램은 명확하고 난독 처리되지 않아야합니다. 난독 화 된 프로그램에서 악의적 인 코드를 숨기는 것은 너무 쉽습니다.


3
우리는 얼마나 숨겨져 있습니까? IMO, 언어와 동등한 것을 넘어 서면 getRandomBetween(1,d)더 깊이 들여다 볼 수 있습니다.
Geobits

@Geobits : 당신은 여기에 핸디 문제를 해결하는 방법에 대한 아주 좋은 예를 찾을 수 있습니다 : codegolf.stackexchange.com/questions/19569/… 충분히 정당화하면 아무것도 할 수 있습니다. 물론 정당화는 큰 거짓말.
vsz

Godmaydamnit, 자바는 미숙 한 물건에 대한 충분한 단점이 없습니다 ...
masterX244


4
나는이 문제를 논외 주제로 폐지하기로 결정하고있다. 현재 미해결 과제는 논외 주제이며, 어떻게 든이 문제는 레이더 아래로 미끄러 져 나갔다.
Mego

답변:


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직선 선형 합동 발생기이며, 버림 기술을 사용하여 균일 성을 보장하므로 size2 ^ 48보다 작은 샘플 의 가장 큰 배수의 모든 실행에서 분포를 보장합니다 . 요구 사항을 충족하는 균등 한 숫자.


설명 java.util.random 설명 뒤에
숨을 수 없습니다

java.util.Random수행 하는 폐기 는이 답변의 동작과 거의 관련이 없습니다. 실제로이 답변에 의존하는 것은 RNG와 마찬가지로 java.util.Random기간이 있으며 기간 순서에 따라 많은 수의 숫자를 생성하면 통계적 속성이 분해된다는 것입니다. 별로 흥미롭지 않습니다. Blum Blum Shub와 같은 암호 보안 RNG에서도 충분히 오래 실행하면 마찬가지입니다.
user2357112는

@ user2357112, 질문은 작은 숫자에 대한 작은 편향이 아닌 균일 성이 필요하기 때문에 폐기와 관련이 있습니다. 제 생각에는이 답변은 손길을 잘 보여줍니다. 언뜻보기에는 투명하게 보이지만 실제로는 디자인 매개 변수를 벗어나는 방식으로 표준 라이브러리를 의도적으로 사용하는 것입니다.
피터 테일러

그러나 거의 모든 RNG가 버리는 일을합니다. 별거 아니에요 RNG 1)에 기간이 있고 2) 하나 이상의 다른 숫자를 생성 할 수있는 경우 단일 기간의 범위 내에서 더 많은 숫자가 표시되기 때문에 말 그대로 임의의 의사 난수 생성기와 함께이 답변을 사용할 수 있습니다. 다른 숫자에 비해 간단한 계산 인수로 다음 기간까지 표시되는 수가 줄어 듭니다.
user2357112는 Monica

이 답변의 분석에는 효과가 나타나려면 2 ^ 48 롤 순서가 필요합니다. LCG를 사용하면 탁상용 게임에서 그럴듯하게 나타날 수있는 여러 롤 내에 측정 가능한 통계적 이상이 나타나는 것을 보여주는보다 정교한 분석을 사용했을 수 있습니다. 그러나 수 조조에 달하는 롤에 대해 이야기 할 때는 그다지 중요하지 않습니다.
user2357112는

0

루비

현재는 d6 만 지원하며 나중에 d20 지원을 추가합니다.

Lo와 보라-그 오지는 불쾌합니다!

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

이전 버전에서 실행하면 "RUBY_VERSION는 <경우"2 " '어딘가에서, 그것은 트릭 전리품으로 나는"취소 "는 루비 2를 필요로하는 추가 것
bazzargh

0

하스켈

임의의 것을 사용하여 다른 임의의 것을 만드십시오.이 경우, 카드를 섞어 주사위 던지기를 생성하십시오.

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

... 등 모든 카드에 대해 (폐기물이 인쇄되지 않음) 너무 분명해?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.