นี่คือลูกเต๋าที่โชคดีของฉัน [ปิด]


10

ใช้โปรแกรมหรือฟังก์ชั่นที่จำลองลูกเต๋าทั่วไปสำหรับเกมสวมบทบาท ควรจัดการอย่างน้อย d6 และ d20 ซึ่งเป็นสองลูกเต๋าที่พบบ่อยที่สุด

อย่างไรก็ตามควรทำงานเป็นนักเล่นเกมสำเร็จรูปที่คาดหวังว่าพวกเขาจะทำงานและไม่ทำงานเหมือนลูกเต๋าจริง

มันเป็นเรื่องตลกระหว่างนักเล่นเกมว่าเราสามารถมีโชคดีเป็นพิเศษสำหรับการม้วนที่สำคัญมากโดยก่อนหน้านี้ได้โยนลูกเต๋าจำนวนมากเลือกผู้ที่ทำให้เกิด "1" จากนั้นโยนพวกเขาอีกครั้งจนกว่าคุณจะได้รับ บางอย่างที่กลิ้ง "1" หลาย ๆ ครั้ง จากนั้นให้คุณเก็บรักษาอย่างระมัดระวังเพราะพวกมันจะเรียงลำดับ 1 ครั้งหลาย ๆ ครั้งดังนั้นความน่าจะเป็นในการหมุนครั้งต่อไปควรจะต่ำมาก

แน่นอนว่านี่ไม่ใช่การทำงานของลูกเต๋าในชีวิตจริงเพราะการทอยลูกเต๋านั้นมีความเป็นอิสระทางสถิติ

ลูกเต๋าจำลองของคุณจะต้องนำมาพิจารณาก่อนหน้านี้และทำงานคล้ายกับวิธีที่นักการพนันในการเข้าใจผิดของนักการพนันคาดว่ามันจะทำงาน ตัวอย่างเช่นหากมีตัวเลขต่ำมากจะถูกหมุนความน่าจะเป็นของการหมุนหมายเลขที่สูงขึ้นควรเพิ่มขึ้น

อย่างไรก็ตามในขณะนี้คือการโกงที่คุณต้องซ่อนมันได้ดี ซึ่งหมายความว่าคุณไม่ควรเปิดเผยว่าคุณโกงโปรแกรม ซึ่งหมายความว่าการบันทึกผลลัพธ์ก่อนหน้าอย่างชัดเจนและอ่านทุกครั้งที่โยนจะน่าสงสัยเกินไป คุณต้องซ่อน "ทรัพย์สิน" ของลูกเต๋าของคุณและคะแนนโบนัสหากคุณทำให้มันเป็นไปได้ที่สามารถปฏิเสธได้และปลอมตัวเป็นข้อผิดพลาดที่ซื่อสัตย์ (ตัวอย่างเช่นคุณสร้างข้อบกพร่อง RNG ของคุณเองด้วยข้อบกพร่อง "ไม่ตั้งใจ")

ผู้ออกเสียงลงคะแนนโปรดคำนึงถึงว่า "ข้อบกพร่อง" นี้ซ่อนไว้ได้ดีเพียงใด

โปรแกรมควรมีความชัดเจนและไม่สับสน มันง่ายเกินไปที่จะซ่อนรหัสความชั่วร้ายในโปรแกรมที่สับสน


3
เรากำลังพูดถึงสิ่งที่ซ่อนอยู่ได้ดีแค่ไหน? IMO อะไรก็ตามที่เกินกว่าภาษาที่เทียบเท่าgetRandomBetween(1,d)จะทำให้ฉันมองลึกลงไป
Geobits

@Geobits: คุณสามารถหาตัวอย่างที่ดีมากสำหรับวิธีการแก้ปัญหาเล่ห์เหลี่ยมที่นี่: codegolf.stackexchange.com/questions/19569/ ...... ฉันหมายความว่าคุณสามารถทำอะไรได้ถ้าคุณให้เหตุผลว่ามันดีพอ โกหกคำโต
vsz

Godmaydamnit, java ไม่มีความต้องการที่มากพอสำหรับสิ่งที่เล่ห์เหลี่ยม ...
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เป็นเครื่องกำเนิดเชิงเส้นเชิงเส้นตรงไปตรงมาและใช้เทคนิคทิ้งเพื่อให้แน่ใจว่ามีความสม่ำเสมอดังนั้นจึงรับประกันได้ว่าในsizeตัวอย่างที่มีขนาดเล็กกว่า 2 ^ 48 จำนวนมาก ตัวเลขอย่างสม่ำเสมอตอบสนองความต้องการ


ไม่สามารถอธิบายได้ว่า java.util.random ทำงานอย่างไร
masterX244

การละทิ้งที่java.util.Randomดำเนินการมีน้อยมากที่จะทำอย่างไรกับพฤติกรรมของคำตอบนี้ จริงๆแล้วสิ่งที่คำตอบนี้อาศัยคือความจริงที่ว่า RNG ใด ๆjava.util.Randomมีจุดและถ้าคุณสร้างตัวเลขจำนวนหนึ่งตามลำดับของรอบระยะเวลาคุณสมบัติทางสถิติของมันจะพังลง นั่นไม่น่าสนใจมาก สิ่งเดียวกันนี้จะเกิดขึ้นได้แม้กับ RNG ที่ปลอดภัยด้วยการเข้ารหัสเช่น Blum Blum Shub ถ้าคุณวิ่งนานพอ
user2357112 รองรับ Monica

@ user2357112 การยกเลิกมีความเกี่ยวข้องเนื่องจากคำถามต้องมีความสม่ำเสมอไม่ใช่อคติขนาดเล็กถึงจำนวนน้อย ในความเห็นของฉันคำตอบนี้เป็นตัวอย่างของการใช้เล่ห์เหลี่ยม: การใช้งานไลบรารี่มาตรฐานในแบบที่แวบแรกเห็นว่าถูกต้องโปร่งใส แต่จริงๆแล้วมันใช้นอกพารามิเตอร์การออกแบบ
Peter Taylor

ค่อนข้างมากทุก RNG ทำสิ่งที่ทิ้งแม้ว่า มันไม่มีอะไรพิเศษ คุณสามารถใช้คำตอบนี้กับเครื่องกำเนิดเลขเทียมใด ๆ ได้อย่างแท้จริงเพราะหาก RNG 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])
...

ฉันจะเพิ่ม "ยกเลิก" ต้องใช้ 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

... และอื่น ๆ สำหรับการ์ดทั้งหมด (ไม่ได้พิมพ์ทิ้ง) ชัดเจนเกินไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.