これらは私のラッキーダイスです[終了]


10

ロールプレイングゲームの一般的なサイコロをシミュレートするプログラムまたは機能を実装します。少なくとも2つの最も一般的なサイコロであるd6とd20を処理する必要があります。

ただし、ステレオタイプのゲーマーが期待どおりに機能するはずであり、実際のサイコロの動作としては機能しません。

これはゲーマー間の冗談であり、非常に重要なロールに特別に幸運なサイコロを振ることができます。以前にたくさんのサイコロを投げ、「1」になったサイコロを選択してから、再び手に入れるまで「1」を複数回振ったいくつか。その後、それらは1を順番に複数回振ったので、それらを慎重に保存します。したがって、次に1を振る確率は非常に低くなるはずです。

もちろん、ロールは統計的に独立しているため、これは実際のサイコロの動作とは異なります。

シミュレートされたダイスは、以前のロールを考慮に入れ、ギャンブラーの誤解におけるギャンブラーが期待どおりに動作するように機能する必要があります。たとえば、多数の低い数字が出た場合、高い数字を出せる確率を高くする必要があります。

ただし、これは不正行為であるため、よく隠す必要があります。これは、プログラムを少し見ただけで、あなたが不正行為をしたことを明らかにしてはならないことを意味します。つまり、以前の結果を明示的に保存し、スローするたびにそれらを読み取ることは、疑わしいことになります。サイコロのこの「プロパティ」を非表示にする必要があり、それをもっともらしい否認可能にして正直な間違いに偽装する場合はボーナスポイントを獲得する必要があります。(たとえば、「意図しない」欠陥で独自のRNGを作成します)

有権者は、この「欠陥」がどれほど隠されているかを考慮に入れてください。

プログラムは明確で、難読化されていない必要があります。難読化されたプログラムで悪質なコードを隠すのは簡単すぎます。


3
私たちはどれほどよく隠されていますか?IMO、言語に相当するものを超えると、getRandomBetween(1,d)私はそれをより深く見るようになります。
Geobits 2014年

@Geobits:ここで手に負えない問題を解決する方法の非常に良い例を見つけることができます:codegolf.stackexchange.com/questions/19569/… 十分に正当化すれば、何でもできることを意味します。もちろん、正当化は大きな嘘。
vsz 2014年

Godmaydamnit、javaにはアンダーハンドのものに十分な癖がありません...
masterX244 2014年


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ですが、単純な線形合同ジェネレーターであり、破棄手法を使用して均一性を確保しているためsize、2 ^ 48サンプル未満の最大の倍数の任意の実行で、要件を満たし、均等に数。


java.util.randomがどのように機能するかについての説明を
後回しに

java.util.Random実行する破棄は、この回答の動作とはほとんど関係がありません。実際、この回答が依存しているのは、他のRNGと同様にjava.util.Randomピリオドがあり、ピリオドのオーダーで多数の数値を生成すると、その統計特性が壊れるという事実です。それはそれほど興味深いことではありません。十分に長く実行すれば、Blum Blum Shubのような暗号的に安全なRNGでも同じことが起こります。
user2357112はモニカ

@ user2357112、質問には均一性が必要であり、小さい数値への小さなバイアスではないため、破棄は関連しています。私の意見では、この回答は手に負えないことを表しています。一見したところ、一見透過的に正しいように見えますが、実際には設計パラメーターの範囲外にある標準ライブラリの意図的な使用です。
Peter Taylor

ただし、ほとんどすべてのRNGが破棄を行います。それは特別なことではありません。RNGが1)ピリオドを持ち、2)複数の異なる数を生成できる場合、単一のピリオドの範囲内で、より多くの数が表示されるため、文字通り任意の疑似乱数ジェネレータでこの回答を使用できます。他の数値と比較して、単純なカウント引数によって次の期間まで表示される数は少なくなります。
user2357112はモニカ

この回答の分析では、効果を表示するために2 ^ 48ロールのオーダーが必要です。LCGを使用すると、卓上ゲームでもっともらしいと思われる多数のロール内に測定可能な統計的異常が発生することを示す、より高度な分析を使用した場合は、これで問題ありません。しかし、何兆ものロールについて話しているときは、それはあまり下手ではありません。
user2357112はモニカ

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

以前のバージョンで実行した場合のように、どこかにRUBY_VERSION <"2"の場合、 "abort" requires ruby​​ 2 "を追加すると、トリックが台無しになります
bazzargh

0

ハスケル

1つのランダムなものを使用して、別のランダムなものを作成します。この場合、カードをシャッフルして、サイコロのスローを生成します。

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

サイコロの面の数という1つの引数を取ります。出力は次のようになります:

./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.