ต้องการเครื่องกำเนิดไฟฟ้าแบบสุ่มที่คาดการณ์ได้


151

ฉันเป็นผู้พัฒนาเกมบนเว็บและฉันมีปัญหากับตัวเลขสุ่ม สมมติว่าผู้เล่นมีโอกาส 20% ที่จะได้รับการโจมตีด้วยดาบอย่างรุนแรง นั่นหมายความว่า 1 ใน 5 การเข้าชมควรสำคัญ ปัญหาคือฉันได้ผลลัพธ์ในชีวิตจริงที่แย่มาก - บางครั้งผู้เล่นจะได้รับ 3 crits ใน 5 ครั้งบางครั้งก็ไม่มี 15 ครั้ง การต่อสู้ค่อนข้างสั้น (3-10 ครั้ง) ดังนั้นสิ่งสำคัญคือต้องมีการกระจายแบบสุ่มที่ดี

ขณะนี้ฉันใช้ PHP mt_rand()แต่เราเพิ่งย้ายรหัสของเราไปยัง C ++ ดังนั้นฉันต้องการแก้ปัญหานี้ในเอ็นจิ้นใหม่ของเกม

ฉันไม่ทราบว่าวิธีการแก้ปัญหาเป็นเครื่องกำเนิดไฟฟ้าแบบสุ่มสม่ำเสมอหรืออาจจะจำรัฐสุ่มก่อนหน้านี้เพื่อบังคับให้มีการแจกแจงที่เหมาะสม


58
มีโอกาส 0.5% ของการเกิดคริติคอล 3 ครั้งและ 2 ครั้งที่ไม่วิพากษ์วิจารณ์ 2 ครั้งและ 3.5% โอกาสการเกิดคริติคอล 15 ครั้งติดต่อกันโดยสมมติว่ามีการสุ่มตัวเลขจริง
Nixuz

10
+1 ขึ้นไป คุณลักษณะหนึ่งของตัวเลขสุ่มคือคุณได้รับค่าผิดปกติ
ConcOfOfTunbridgeWells

45
@ นิกซัส: ไม่มันมีโอกาสประมาณ 5% จาก 3 เพลงฮิตและ 2 เพลงที่ไม่สำคัญคุณลืมที่จะคูณด้วย (5! / (3! * 2!)) = 10 ด้วยระดับความมั่นใจ 95% มันคือ ไม่น่าเป็นไปได้ที่สถิติจะเกิดขึ้น 3 ครั้งในการโจมตี 5 ครั้ง
erikkallen

7
ตอนแรกฉันคิดว่านี่เป็นคำถามที่งี่เง่า ... อีกครั้งฉันก็ถ่อมลงดังนั้น
SergioL

คำตอบ:


39

ฉันเห็นด้วยกับคำตอบก่อนหน้านี้ว่าการสุ่มตัวอย่างจริง ๆ ในเกมเล็ก ๆ บางเกมไม่เป็นที่น่าพอใจ - มันดูไม่ยุติธรรมสำหรับบางกรณีการใช้งาน

ฉันเขียน Shuffle Bag อย่างง่ายเช่นการนำไปใช้ใน Ruby และทำการทดสอบบางอย่าง การใช้งานทำสิ่งนี้:

  • หากดูเหมือนว่ายังยุติธรรมอยู่หรือเรายังไม่ถึงเกณฑ์ม้วนต่ำสุดก็จะส่งคืน Hit ที่ยุติธรรมตามความน่าจะเป็นปกติ
  • หากความน่าจะเป็นที่สังเกตได้จากม้วนที่ผ่านมาทำให้ดูเหมือนว่าไม่ยุติธรรมจะส่งคืน "การตีที่ยุติธรรม"

มันถือว่าไม่ยุติธรรมตามความน่าจะเป็นขอบเขต ตัวอย่างเช่นสำหรับความน่าจะเป็น 20% คุณสามารถตั้งค่า 10% เป็นขอบเขตล่างและ 40% เป็นขอบเขตบน

ใช้ขอบเขตที่ผมพบว่ามีวิ่ง 10 ฮิต14.2% ของเวลาการดำเนินงานที่แท้จริง pseudorandom ผลิตผลลัพธ์ที่อยู่นอกขอบเขตเหล่านั้น ประมาณ 11% ของเวลามีการทำคะแนนวิกฤติ 0 ครั้งใน 10 ครั้ง 3.3% ของเวลา, 5 ครั้งหรือมากกว่านั้นถูกวิพากษ์วิจารณ์อย่างรุนแรงจาก 10 โดยธรรมชาติแล้วการใช้อัลกอริธึมนี้ (ด้วยจำนวนรอบการหมุนต่ำสุด 5) จำนวนน้อยกว่ามาก (0.03%) ของการวิ่งแบบ "Fairish" . แม้ว่าการใช้งานด้านล่างจะไม่เหมาะสม (สิ่งที่ฉลาดกว่าสามารถทำได้แน่นอน) ก็เป็นที่น่าสังเกตว่าผู้ใช้ของคุณมักจะรู้สึกว่ามันไม่ยุติธรรมกับโซลูชันปลอมเทียมจริง ๆ

นี่คือเนื้อของฉันFairishBagเขียนในทับทิม การดำเนินการทั้งหมดและรวดเร็วในการจำลอง Monte Carlo สามารถใช้ได้ที่นี่ (สรุปสาระสำคัญ)

def fire!
  hit = if @rolls >= @min_rolls && observed_probability > @unfair_high
    false
  elsif @rolls >= @min_rolls && observed_probability < @unfair_low
    true
  else
    rand <= @probability
  end
  @hits += 1 if hit
  @rolls += 1
  return hit
end

def observed_probability
  @hits.to_f / @rolls
end

อัปเดต:การใช้วิธีนี้จะเพิ่มความน่าจะเป็นโดยรวมในการได้รับการโจมตีที่สำคัญถึงประมาณ 22% โดยใช้ขอบเขตด้านบน คุณสามารถชดเชยสิ่งนี้ได้โดยตั้งค่าความน่าจะเป็น "ของจริง" ให้ต่ำลงเล็กน้อย ความน่าจะเป็นที่ 17.5% เมื่อปรับเปลี่ยนแบบ fairish ให้ผลตอบแทนความน่าจะเป็นระยะยาวที่สังเกตได้ประมาณ 20% และทำให้ระยะสั้นมีความรู้สึกยุติธรรม


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

Steve Rabin เขียนบทความที่น่าสนใจเกี่ยวกับการสุ่มในเกม ในระยะสั้นพฤติกรรม "สุ่ม" ที่แท้จริงไม่ได้ "รู้สึก" สุ่มสำหรับคนส่วนใหญ่และการศึกษาได้สำรองสิ่งนี้ไว้ บทความของเขาเรียกว่า Filtered Randomness สำหรับการตัดสินใจของ AI และตรรกะของเกมและปรากฏใน "AI Game Programming Wisdom 2" (2003) คุณควรตรวจสอบมันอาจจะเป็นประโยชน์กับคุณ
Jeff Tucker

@IanTerrell มันเป็นการดีที่จะระบุว่าขนาดตัวอย่างของการทดสอบของคุณใหญ่เพียงใดนั่นคือจำนวนการต่อสู้เพื่อตัดสินความน่าจะเป็นเหล่านั้น

@ user677656: มันอยู่ในส่วนสำคัญ แต่เป็น 100k
เอียน Terrell

223

นั่นหมายความว่า 1 ใน 5 การเข้าชมควรสำคัญ ปัญหาคือฉันได้ผลลัพธ์ในชีวิตจริงที่แย่มาก - บางครั้งผู้เล่นจะได้รับ 3 crits ใน 5 ครั้งบางครั้งก็ไม่มี 15 ครั้ง

สิ่งที่คุณต้องเป็นถุงสับเปลี่ยน มันแก้ปัญหาการสุ่มจริงเกินไปสุ่มเกินไปสำหรับเกม

อัลกอริธึมเกี่ยวกับเรื่องนี้: คุณใส่ 1 คริติคอลและฮิตที่ไม่สำคัญในถุง จากนั้นคุณสุ่มลำดับของพวกเขาในกระเป๋าแล้วหยิบออกทีละตัว เมื่อกระเป๋าว่างเปล่าคุณเติมอีกครั้งด้วยค่าเดียวกันและสุ่ม ด้วยวิธีนี้คุณจะได้รับการวิพากษ์โดยเฉลี่ย 1 ครั้งต่อการเข้าชม 5 ครั้งและมากที่สุด 2 ครั้งและ 8 ครั้งที่ไม่สำคัญในหนึ่งครั้ง เพิ่มจำนวนรายการในกระเป๋าเพื่อเพิ่มความสุ่ม

นี่คือตัวอย่างของการนำไปใช้ (ใน Java) และกรณีทดสอบของมันที่ฉันเขียนเมื่อไม่นานมานี้


21
+ 1 สำหรับความคิดที่ดีโดยไม่มีการวิจารณ์ ขยายขนาดกระเป๋าเพื่อการสุ่มในระดับที่สูงขึ้นและจัดการกับความแปรปรวนในโอกาสสำคัญระหว่างผู้เล่น (หากตัวแปร ofc)
TheMissingLINQ

16
คุณสามารถมีถุงขนาด 10 ใส่ 1 ตีบวกโอกาส 30% ของวินาที หากมีการเปลี่ยนแปลงโอกาสที่สำคัญคุณสามารถทิ้งกระเป๋าและเริ่มใหม่ โปรดทราบว่ารูปแบบใด ๆ นั้นมีความเสี่ยงที่ถ้าคุณ (หรือคู่ต่อสู้ของคุณ) ทราบถึงความน่าจะเป็นถึงการเกิดวิกฤตและขนาดของกระเป๋าคุณอาจทราบได้ว่าคุณจะไม่ได้รับโทษอีกจำนวนหนึ่ง สิ่งนี้อาจส่งผลต่อกลยุทธ์
Steve Jessop

3
ใช่ ... ในบางสิ่งเช่นนี้คุณเรียกใช้ริคคล้ายกับการนับไพ่ ฉันจะเสี่ยงกับคนขี้โกงหรือเข้าร่วมในการสังหารครั้งใหญ่ ... ผลลัพธ์ที่เป็นไปได้จำนวนหนึ่งที่มีขนาดเล็กอาจลดความเสี่ยงของการสูญเสียและเพิ่มโอกาสในการเป็น "เกม"
Matthew Whited

8
ฉันชอบไอเดียกระเป๋าแบบสุ่ม แต่ฉันไม่คิดว่าสิ่งนี้ตรงกับเกม "วิญญาณ" เพราะความน่าจะเป็นของคุณที่สำคัญ 20% (ซึ่งหมายความว่าคุณไม่สามารถทำได้ใน 10 ครั้ง) ไม่ใช่ความน่าจะเป็นอีกต่อไป มันจะกลายเป็น 1 ตีทุก ๆ 5 ฮิต ยิ่งไปกว่านั้นให้เปลี่ยนถุงถ้าการเปลี่ยนความน่าจะเป็นที่สำคัญจะทำให้เกิดความผิดพลาดในเกม หากการโจมตีที่สำคัญของฉันเสร็จสิ้นแล้วฉันจะเสกคาถาให้ตัวฉันเพื่อรับบทวิจารณ์ต่อไปก่อนหน้านี้: p
Michaël Carpentier

2
@ โจนาธาน: ทำให้ถุงมีขนาดใหญ่ที่คุณให้มันจริงเลิกทำถุงความคิดทั้งหมด: เพื่อให้แน่ใจว่าสิ่งที่เกิดขึ้น (ที่สำคัญที่จะทำได้) ภายในจำนวนที่ยอมรับได้ของการขว้าง การทำให้กระเป๋า 50000 ขนาดใหญ่นั้นใกล้เคียงกับการใช้ตัวสร้างตัวเลขสุ่ม
dstibbe

113

คุณเข้าใจผิดว่าการสุ่มหมายถึงอะไร

ข้อใดต่อไปนี้สุ่มมากขึ้น

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

ในขณะที่พล็อตที่สองดูกระจายอย่างเท่าเทียมกันยิ่งสุ่มเป็นพล็อตแรก จิตใจมนุษย์มักจะเห็นรูปแบบเป็นแบบสุ่มดังนั้นเราจึงเห็นกลุ่มในพล็อตแรกเป็นรูปแบบ แต่ไม่ใช่ - พวกมันเป็นเพียงส่วนหนึ่งของตัวอย่างที่เลือกแบบสุ่ม


25
คำอธิบายที่ดีของ Numb3rs!
RMAAlmeida

9
เทคนิคการพูดคุณไม่สามารถวัดแบบแผนได้ ดิสทริบิวชันทั้งคู่ดูเหมือนว่าฉันจะเป็นผู้กำหนดเองแม้ว่าฉันจะเดาว่าอัลกอริทึมนั้นสร้าง คุณสามารถทำการทดสอบจำนวนหนึ่งในพล็อตแรกและพิจารณาว่าเป็นไปได้ว่ามาจากกระบวนการที่ให้คะแนนตามการแจกแจงแบบเดียวกัน แต่คุณจะไม่สามารถสรุปได้ว่ามันเป็นการสุ่มมากขึ้น ในฐานะที่เป็นตัวอย่างคุณสามารถสร้างพล็อตแบบแรกโดยใช้เครื่องกำเนิดไฟฟ้าเชิงเส้นเชิงเส้นจากนั้นสร้างพล็อตแบบที่สองโดยใช้เสียงขยายเสียงจากซีเนอร์ไดโอด ลองใช้คำที่ไม่เกี่ยวข้องแทนการสุ่ม
Dietrich Epp

8
คุณสามารถวัดความน่าจะเป็นที่การกระจายดังกล่าวสุ่ม
ceejayoz


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

88

จากพฤติกรรมที่คุณต้องการฉันคิดว่าคุณกำลังสุ่มตัวแปรผิด

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

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


ฉันคิดว่านี่เป็นทางออกที่ยอดเยี่ยม แต่โอกาส 80% มีอะไรบ้าง
นักคิด

ฉันชอบที่จะใช้เครื่องกำเนิดไฟฟ้าแบบสุ่มหลายมิติในบางครั้งเช่นกัน โอกาสที่จะกด + โอกาสที่จะเพิ่มกำลัง + โอกาสเสี่ยงเป็นวิกฤต เช่นเดียวกับการทอยลูกเต๋าที่แตกต่างกันหลายตัวใน D&D
Matthew Whited

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

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

+1 ดีมากและจัดการความน่าจะเป็นที่จะได้รับผลกระทบน้อยกว่า 20% อย่างง่ายดาย
อลิซเพอร์เซลล์

53

ก่อนกำหนดการกระจาย "เหมาะสม" ตัวเลขสุ่มเป็นแบบสุ่ม - ผลลัพธ์ที่คุณเห็นมีความสอดคล้องกับการสุ่ม (หลอก) ทั้งหมด

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

ถ้าไม่ให้บันทึกความล้มเหลวและในครั้งต่อไปให้สร้างตัวเลขจาก 1 ถึง 5 แต่เพิ่มเมื่อพูด, floor (numFailures / 2) ดังนั้นในครั้งนี้พวกเขามีโอกาส 1 ใน 5 หากพวกเขาล้มเหลวในครั้งต่อไปช่วงเวลาชนะคือ 4 และ 5; โอกาส 2 ใน 5 ของความสำเร็จ ด้วยตัวเลือกเหล่านี้หลังจากความล้มเหลว 8 ครั้งพวกเขาจะประสบความสำเร็จ


ในบันทึกนั้น ... จะมีช่วงสุ่มตัวเลขส่งผลกระทบต่อการกระจาย ... เช่นเลือกสุ่ม r = ใหม่สุ่ม (); r.Next (1,5) กับ r.Next (1, 1000000)% 200000
Eoin Campbell

23
+1 เมื่อเห็นปัญหาที่อยู่เบื้องหลังคำขอแทนที่จะบอก OP ว่าเขาเข้าใจผิดแบบสุ่ม
Boris Callens

4
โปรดทราบว่าถ้าคุณทำเช่นนี้สัดส่วนความสำเร็จโดยรวมของพวกเขาจะมากกว่า 1 ใน 5 วิธีที่จะ (ตัวอย่าง) เลือก 20 ตัวเลขที่แตกต่างกันโดยการสุ่มจากช่วง 1..100 และกำหนดไว้ล่วงหน้าว่าจะ เป็นสิ่งสำคัญ แม้ว่าจะมีการทำบัญชีมากกว่า
Steve Jessop

"จะมากกว่า 1 ใน 5" - คาดว่าจะอยู่ในระยะยาวฉันหมายถึง
Steve Jessop

คุณสามารถลดความน่าจะเป็นเริ่มต้นลงได้เล็กน้อยเพื่อให้สัดส่วนโดยรวมลดลงเหลือ 1/5 ฉันไม่ได้คิดออกว่าคุณต้องลดมันลงเท่าไหร่ แต่ทุกอย่างดำเนินไปอย่างต่อเนื่อง
Steve Jessop

35

วิธีการแทนที่ mt_rand () ด้วยสิ่งนี้?

การ์ตูน XKCD (RFC 1149.5 ระบุ 4 เป็นหมายเลขสุ่มมาตรฐาน IEEE-vetted)

(RFC 1149.5 ระบุ 4 เป็นหมายเลขสุ่มมาตรฐาน IEEE-vetted)

จากXKCD


ดี แต่จะแก้ปัญหาการกระจายหมายเลขสุ่มของ OP หรือไม่ ;-)
Arjan Einbu

ไม่ได้จริงๆ เขาขอ RNG แบบไม่สุ่มซึ่งเขาสามารถใช้ฟังก์ชั่นนี้ได้ แต่สิ่งที่เขาต้องการจริงๆจะดีกว่าที่อธิบายได้ด้วยคำตอบที่ปัจจุบันบน ( stackoverflow.com/questions/910215/910224#910224 )
โคลิน Pickard

28
นี่เป็นแบบสุ่มมากกว่าที่ OP ต้องการ
Çağdaş Tekin

-1 เนื่องจาก RFC1149 ไม่มีส่วนที่ 5 (และสลับกันไม่มีหมายเลข 1,149.5); +1 สำหรับการสุ่มแบบยุติธรรม
greyfade

34

หวังว่าบทความนี้จะช่วยคุณ: http://web.archive.org/web/20090103063439/http://www.gamedev.net:80/reference/design/features/randomness/

วิธีการสร้าง 'สุ่มหมายเลข' นี้เป็นเรื่องธรรมดาในเกม rpg / mmorpg

ปัญหาที่แก้ได้คือ (แยก):

แมงมุมใบมีดอยู่ที่ลำคอของคุณ มันฮิตและคุณพลาด มันฮิตอีกครั้งและคุณพลาดอีกครั้ง และอีกครั้งและอีกครั้งจนกระทั่งไม่มีอะไรเหลือให้คุณตี คุณตายแล้วและยังมีปลาทูสองตันส่องดูศพของคุณ เป็นไปไม่ได้? ไม่น่าจะเป็นไปได้? ใช่. แต่ให้ผู้เล่นมากพอและให้เวลามากพอ ไม่ใช่ว่าแมงมุมใบมีดเป็นเรื่องยากมันเป็นเพียงโชคร้าย น่าผิดหวังแค่ไหน ก็เพียงพอแล้วที่จะทำให้ผู้เล่นต้องการเลิกเล่น


1
ฉันเคยได้ยินเรื่องนี้ - "หนึ่งในล้านเหตุการณ์เกิดขึ้น 6,000 ครั้งในประชากรโลก"
ceejayoz

19

สิ่งที่คุณต้องการไม่ใช่ตัวเลขสุ่ม แต่เป็นตัวเลขที่ดูเหมือนสุ่มสำหรับมนุษย์ อื่น ๆ ได้แนะนำอัลกอริทึมของแต่ละบุคคลแล้วซึ่งสามารถช่วยคุณได้เช่น Shuffle Bad

สำหรับรายละเอียดที่ดีและการวิเคราะห์ที่กว้างขวางของโดเมนนี้ดูAI เกม Programming ภูมิปัญญา 2 หนังสือทั้งเล่มคุ้มค่าที่จะอ่านสำหรับผู้พัฒนาเกมใด ๆ แนวคิดของ "ตัวเลขสุ่มดูเหมือน" นั้นได้รับการจัดการในบท:

กรองแบบสุ่มสำหรับการตัดสินใจ AI และลอจิกเกม :

บทคัดย่อ: ภูมิปัญญาดั้งเดิมแสดงให้เห็นว่ายิ่งตัวสร้างตัวเลขสุ่มดีขึ้นเท่าไหร่เกมของคุณก็จะไม่สามารถคาดเดาได้มากขึ้น อย่างไรก็ตามจากการศึกษาทางจิตวิทยาพบว่าการสุ่มตัวอย่างที่แท้จริงในระยะสั้นมักจะดูไร้เหตุผลต่อมนุษย์ บทความนี้แสดงวิธีการตัดสินใจ AI แบบสุ่มและตรรกะของเกมดูสุ่มขึ้นสำหรับผู้เล่นในขณะที่ยังคงรักษาแบบแผนทางสถิติที่แข็งแกร่ง

คุณอาจพบอีกบทที่น่าสนใจ:

สถิติของตัวเลขสุ่ม

บทคัดย่อ: ตัวเลขสุ่มถูกใช้อย่างหนักที่สุดโดยปัญญาประดิษฐ์และเกมโดยทั่วไป การเพิกเฉยต่อศักยภาพของพวกเขาคือทำให้เกมคาดเดาได้และน่าเบื่อ การใช้งานอย่างไม่ถูกต้องอาจเป็นเรื่องเลวร้าย ทำความเข้าใจถึงวิธีการสร้างตัวเลขสุ่มข้อ จำกัด และความสามารถของพวกเขาสามารถขจัดปัญหามากมายในการใช้งานในเกมของคุณ บทความนี้นำเสนอข้อมูลเชิงลึกเกี่ยวกับตัวเลขสุ่มการสร้างและวิธีการแยกคนดีจากคนเลว


8

แน่นอนว่าการสร้างเลขสุ่มใด ๆ มีโอกาสที่จะสร้างการวิ่งเช่นนี้หรือไม่? คุณจะไม่ได้รับชุดตัวอย่างขนาดใหญ่พอใน 3-10 ม้วนเพื่อดูเปอร์เซ็นต์ที่เหมาะสม

บางทีสิ่งที่คุณต้องการคือขีด จำกัด แห่งความเมตตา ... จำ 10 ม้วนสุดท้ายและถ้าพวกเขาไม่ได้มีการโจมตีที่รุนแรงให้แจกฟรี ปรับความนุ่มนวลของสลิงและลูกศรด้วยการสุ่ม


8

ทางออกที่ดีที่สุดของคุณอาจเป็นการทดสอบการเล่นด้วยแผนการสุ่มที่แตกต่างหลากหลายและเลือกแผนการที่ทำให้ผู้เล่นมีความสุขที่สุด

คุณอาจลองใช้นโยบายถอยกลับสำหรับหมายเลขเดียวกันในการเผชิญหน้าที่กำหนดเช่นหากผู้เล่นหมุน1ในเทิร์นแรกของพวกเขายอมรับ หากต้องการได้อีกสิ่งหนึ่ง1พวกเขาจำเป็นต้องหมุน 2 1วินาทีติดต่อกัน ในการรับหนึ่งในสาม1พวกเขาต้องการ 3 ในแถว, infinitum ad


7

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

หากคุณต้องการให้ 1 ในทุก ๆ 5 เพลงมีความสำคัญคุณควรเลือกตัวเลขระหว่าง 1 ถึง 5 และบอกว่าการโจมตีนั้นจะเป็นสิ่งสำคัญ


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

ดังนั้นหากการโจมตีครั้งแรกเป็น crit การตีสี่ครั้งต่อไปจะไม่เกิดขึ้น ฟังดูเหมือนว่านี่คือสิ่งที่ OP ต้องการ แต่เมื่อคุณพูดอย่างนี้มันจะฟังไม่ออก คุณได้รับ UV ของฉันสำหรับสิ่งนั้น
belgariontheking

-1 คุณดูเหมือนสับสน "สุ่ม" กับ "memoryless" - en.wikipedia.org/wiki/Memorylessness
Alice Purcell

7

mt_rand () ขึ้นอยู่กับการใช้งานของMersenne Twisterซึ่งหมายความว่ามันให้การแจกแจงแบบสุ่มที่ดีที่สุดที่คุณจะได้รับ

เห็นได้ชัดว่าสิ่งที่คุณต้องการไม่ได้เป็นแบบสุ่มดังนั้นคุณควรเริ่มต้นระบุสิ่งที่คุณต้องการ คุณอาจรู้ว่าคุณมีความคาดหวังที่ขัดแย้งกัน - ผลลัพธ์ควรสุ่มอย่างแท้จริงและไม่สามารถคาดเดาได้ แต่ในเวลาเดียวกันพวกเขาไม่ควรแสดงรูปแบบท้องถิ่นจากความน่าจะเป็นที่ระบุไว้ - แต่จากนั้นจะสามารถคาดเดาได้ หากคุณตั้งค่าการไม่ crits สูงสุด 10 ครั้งติดต่อกันคุณจะบอกผู้เล่นว่า "ถ้าคุณมี 9 non-crits ต่อเนื่องคนต่อไปจะสำคัญอย่างแน่นอน 100%" - คุณอาจจะ ไม่รำคาญกับการสุ่มเลย


6

จากการทดสอบจำนวนเล็กน้อยคุณควรคาดหวังผลลัพธ์เช่นนั้น:

การสุ่มตัวอย่างที่แท้จริงนั้นสามารถคาดเดาได้เฉพาะขนาดที่ใหญ่มากเช่นมันเป็นไปได้ที่จะพลิกเหรียญและได้หัว 3 ครั้งติดต่อกันในครั้งแรกอย่างไรก็ตามการโยนไม่กี่ล้านครั้งคุณจะจบลงด้วยประมาณ 50-50


7
แม้ว่าจะมีโอกาสที่หลังจากผ่านไปไม่กี่ล้านครั้งคุณก็จะเห็นเพียงด้านเดียวของเหรียญ แม้ว่าสิ่งนี้เคยเกิดขึ้นคุณอาจนั่งอยู่ใกล้เกินไปไดรฟ์ไม่น่าจะเป็นไปไม่ได้: P
Grant Peters

ฮ่าฮ่าใช่ แต่โอกาสนั้นต่ำมากอย่างไม่น่าเชื่อว่ากฎของคณิตศาสตร์บอกว่าคุณควรเห็นการกระจายแบบสม่ำเสมอ (ish)
Ed James

6

ฉันเห็นคำตอบมากมายที่แนะนำให้ติดตามหมายเลขที่สร้างขึ้นก่อนหน้านี้หรือเพื่อสลับค่าที่เป็นไปได้ทั้งหมด

โดยส่วนตัวฉันไม่เห็นด้วยว่า 3 crits ในแถวไม่ดี และฉันก็ไม่เห็นด้วยว่า 15 crits ในแถวไม่ดี

ฉันจะแก้ปัญหาโดยแก้ไขโอกาส crit ด้วยตนเองหลังจากแต่ละหมายเลข ตัวอย่าง (เพื่อแสดงความคิด):

int base_chance = 20;
int current_chance = base_chance;

int hit = generate_random_number(0, 100) + 1; // anything from 1 to 100
if(hit < current_chance)//Or whatever method you use to check
{
    //crit!
    if(current_chance > base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 0.8; // decrease the crit chance for the NEXT hit.
}
else
{
    //no crit.
    if(current_chance < base_chance)
        current_chance = base_chance; // reset the chance.
    else
        current_chance *= 1.1; // increase the crit chance for the NEXT hit.
    //raise the current_chance
}

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

เพียงแค่โยนใน 2 เซ็นต์ของฉัน ...


ฉันชอบแนวทางแบบนี้ ฉันอาจจะทำอย่างอื่น เริ่มต้นด้วยโอกาสที่ต่ำกว่าและสร้างสูงสุดได้สูงสุด 20% + เพิ่มเปอร์เซ็นต์บางส่วนจนกว่าจะถึงและจะรีเซ็ตเป็นจำนวนที่ต่ำ
Matthew

5

คำตอบไม่กี่ชั้นนำที่มีคำอธิบายที่ดีดังนั้นฉันจะมุ่งเน้นไปที่ขั้นตอนวิธีการที่จะช่วยให้คุณสามารถควบคุมความน่าจะเป็นของ "ลายเส้นเลว" ในขณะที่ไม่เคยกลายเป็นกำหนด นี่คือสิ่งที่ฉันคิดว่าคุณควรทำ:

แทนที่จะระบุpพารามิเตอร์ของการแจกแจงเบอร์นูลลีซึ่งเป็นความน่าจะเป็นของคุณในการเข้าตีวิกฤติระบุaและbพารามิเตอร์ของการแจกแจงแบบเบต้า "คอนจูเกตก่อนหน้า" ของการแจกแจงเบอร์นูลี คุณต้องติดตามAและBจำนวนการโจมตีที่สำคัญและไม่ร้ายแรง

ตอนนี้ในการระบุaและbให้แน่ใจว่า a / (a ​​+ b) = p ซึ่งเป็นโอกาสของการโจมตีคริติคอล สิ่งที่เรียบร้อยก็คือ (a + b) บอกปริมาณที่คุณต้องการให้ A / (A + B) ใกล้เคียงกับ p โดยทั่วไป

คุณสุ่มตัวอย่างแบบนี้:

อนุญาตให้p(x)ฟังก์ชันความหนาแน่นของความน่าจะเป็นของการแจกแจงเบต้า มันมีอยู่ในหลาย ๆ ที่ แต่คุณสามารถหาได้ใน GSL เป็น gsl_ran_beta_pdf

S = A+B+1
p_1 = p((A+1)/S)
p_2 = p(A/S)

เลือกการเข้าชมที่สำคัญโดยการสุ่มตัวอย่างจากการแจกแจงเบอโนลลีด้วยความน่าจะเป็น p_1 / (p_1 + p_2)

หากคุณพบว่าตัวเลขสุ่มมี "เส้นริ้วเลว" มากเกินไปขยายขนาดaและbแต่ในขีด จำกัด เมื่อaและbไปไม่มีที่สิ้นสุดคุณจะมีวิธีถุงแบบสุ่มที่อธิบายไว้ก่อนหน้านี้

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


5

หากคุณต้องการการกระจายที่ไม่สนับสนุนค่าซ้ำคุณสามารถใช้อัลกอริธึมการปฏิเสธซ้ำแบบง่าย ๆ ได้

เช่น

int GetRand(int nSize)
{
    return 1 + (::rand() % nSize);
}
int GetDice()
{
    static int nPrevious=-1;
    while (1) {
        int nValue = GetRand(6);
        // only allow repeat 5% of the time
        if (nValue==nPrevious && GetRand(100)<95)
            continue;
        nPrevious = nValue;
        return nValue;
    }
}

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

ฉันไม่แนะนำสิ่งนี้เป็นการออกแบบเกมที่ดี เพียงแค่แนะนำวิธีการบรรลุสิ่งที่คุณต้องการ


ค่าบางอย่างในเกมของฉันเช่นการโจมตีแบบคริติคอลไม่สามารถมีโอกาสได้มากกว่า 50% ดังนั้นฉันจึงปิดกั้นการทำซ้ำทุกครั้ง แต่สิ่งนี้จะช่วยลดโอกาสการเกิดเปอร์เซ็นต์
นักคิด

4

ไม่ชัดเจนว่าคุณต้องการอะไร มันเป็นไปได้ที่จะสร้างฟังก์ชั่นที่ 5 ครั้งแรกที่คุณเรียกมันมันจะส่งกลับตัวเลข 1-5 ตามลำดับแบบสุ่ม

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

อีกวิธีหนึ่งคุณสามารถใช้วิธีการปัจจุบันของคุณต่อไปและสมมติว่าผลลัพธ์ปัจจุบันของคุณเกิดจากตัวสร้างแบบสุ่มไม่ดี โปรดทราบว่าอาจไม่มีอะไรผิดปกติกับหมายเลขปัจจุบันของคุณ ค่าสุ่มเป็นแบบสุ่ม บางครั้งคุณได้รับ 2, 3 หรือ 8 ของค่าเดียวกันในแถว เพราะพวกมันสุ่ม เครื่องกำเนิดไฟฟ้าแบบสุ่มที่ดีเพียงแค่รับประกันว่าโดยเฉลี่ยตัวเลขทั้งหมดจะถูกส่งคืนอย่างเท่าเทียมกัน

แน่นอนถ้าคุณใช้ตัวสร้างแบบสุ่มที่ไม่ดีนั่นอาจทำให้ผลลัพธ์ของคุณเบ้และถ้าเป็นเช่นนั้นการเปลี่ยนไปใช้ตัวสร้างแบบสุ่มที่ดีกว่านั้นควรแก้ไขปัญหา (ตรวจสอบห้องสมุด Boost.Random สำหรับเครื่องกำเนิดไฟฟ้าที่ดีกว่า)

หรือคุณสามารถจำค่า N สุดท้ายที่ส่งคืนโดยฟังก์ชันสุ่มของคุณและชั่งน้ำหนักผลลัพธ์เหล่านั้น (ตัวอย่างง่ายๆคือ "สำหรับผลลัพธ์ใหม่แต่ละครั้งมีโอกาส 50% ที่เราควรทิ้งค่าและรับใหม่"

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


ที่จริงแล้วฟังก์ชั่นที่เขาใช้นั้นเหมือนกับ RNG ที่ดีที่สุดในบูสเตอร์เพิ่ม
Michael Borgwardt

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

4

คุณสามารถสร้างรายการที่มีตัวเลขตั้งแต่ 1 ถึง 5 และเรียงลำดับตามการสุ่ม จากนั้นทำตามรายการที่คุณสร้าง คุณมีการรับประกันว่าจะได้รับทุกหมายเลขอย่างน้อยหนึ่งครั้ง ... เมื่อคุณผ่าน 5 หมายเลขแรกเพียงแค่สร้างอีก 5 หมายเลข ...


4

ฉันแนะนำระบบเปอร์เซ็นต์โปรเกรสซีฟเช่น Blizzard ใช้: http://www.shacknews.com/onearticle.x/57886

โดยทั่วไปคุณจะหมุน RNG จากนั้นเปรียบเทียบกับค่าเพื่อพิจารณาว่าประสบความสำเร็จหรือไม่ ที่อาจมีลักษณะ:

if ( randNumber <= .2 ) {
   //Critical
} else {
   //Normal
}

สิ่งที่คุณต้องทำคือการเพิ่มโอกาสพื้นฐาน ...

if (randNumber <= .2 + progressiveChance ) {
   progressiveChance = 0;
   //Critical
} else {
   progressiveChance += CHANCE_MODIFIER;
   //Normal hit
}

ถ้าคุณต้องการที่จะเป็นแฟนซีมากขึ้นมันค่อนข้างง่ายที่จะเพิ่มในมากขึ้น คุณสามารถกำหนดจำนวนเงินที่ ProChanceChance สามารถหลีกเลี่ยงโอกาสวิกฤติได้ 100% หรือรีเซ็ตในบางเหตุการณ์ คุณยังสามารถเพิ่ม ProgressiveChance ในจำนวนที่น้อยลงในแต่ละบูสต์ด้วย ProgressiveChance + = (1 - ProgressiveChance) * SCALE ที่ SCALE <1


4

ถ้าคุณคิดเลขเพียงเล็กน้อยคุณอาจลองแจกแจงแบบเอ็กซ์โปเนนเชียล

ตัวอย่างเช่นถ้า lambda = 0.5 ค่าที่คาดหวังคือ 2 (ไปอ่านบทความนั้น) หมายความว่าคุณน่าจะได้รับผลกระทบมากที่สุดทุกครั้งที่ 2 (เช่น 50%, huh?) แต่ด้วยการกระจายความน่าจะเป็นเช่นนั้นคุณจะพลาดแน่นอน (หรือทำตรงกันข้ามกับสิ่งใด ๆ ) ที่เทิร์นที่ 0 (เหตุการณ์ที่เกิดขึ้นแล้วและมีการรีเซ็ต turn_counter) มีโอกาส 40% ที่จะตีเทิร์นถัดไปประมาณ 65% โอกาสที่จะทำมันเป็นครั้งที่ 2 (ถัดไปหลังจากถัดไป) เปิดประมาณ 80% ที่จะตี 3 และอื่น ๆ

จุดประสงค์ทั้งหมดของการกระจายนั้นคือถ้ามีโอกาสถูก 50% และเขาพลาด 3 ครั้งติดต่อกันเขาจะรีบร้อน (ดีกว่าโอกาส 80% และเพิ่มทุก ๆ รอบต่อไป) มันนำไปสู่ผลลัพธ์ที่ "ยุติธรรม" มากขึ้นรักษาโอกาส 50% โดยไม่เปลี่ยนแปลง

รับโอกาส 20% ในการทำคริติคุณ

  • 17% to crit เทิร์นที่ 1
  • 32% ไปเป็น Crit เทิร์นที่ 2 หากไม่มี crit เกิดขึ้นในเทิร์นก่อนหน้าทั้งหมด
  • 45% ไปเป็น crit เทิร์นที่ 3 หากไม่มี crit เกิดขึ้นในเทิร์นก่อนหน้าทั้งหมด
  • 54% ไปเป็น crit เทิร์นที่ 4 หากไม่มี crit เกิดขึ้นในรอบก่อนหน้าทั้งหมด
  • ...
  • 80% ถึงคริติตที่ 8 หากไม่มี crit เกิดขึ้นในรอบก่อนหน้าทั้งหมด

ยังคงมีโอกาสประมาณ 0.2% (เทียบกับ 5% เหล่านั้น) ของ 3 crits + 2 non-crits ใน 5 รอบ และมีโอกาส 14% ของการไม่เกิดเหตุ 4 ครั้ง, 5% จาก 5, 1.5% สำหรับ 6, 0.3% สำหรับ 7, 0.07% สำหรับ 8 ครั้งไม่ใช่การเกิดเหตุ ฉันเดิมพันว่า "ยุติธรรมมากกว่า" มากกว่า 41%, 32%, 26%, 21% และ 16%

หวังว่าคุณจะไม่เบื่อจนตาย


นี่คล้ายกับโซลูชันของฉันยกเว้นว่าจะ "จดจำ" เวลาเท่านั้นนับตั้งแต่การโจมตีครั้งสำคัญครั้งล่าสุด ภายใต้โซลูชันนี้สตริงการเข้าชมที่สำคัญ 4 รายการจะเหมือนกับการตี 1 ครั้งที่สำคัญจนถึงความน่าจะเป็นเกี่ยวกับอนาคต ดังนั้นหากการวิพากษ์วิจารณ์ที่สำคัญนั้นดีทางออกนี้จะจำกัดความเสี่ยงของคุณ แต่ไม่ใช่อัพไซด์ของคุณ โซลูชันของฉันมีผลต่อทั้งสองอย่าง
Neil G

เห็นได้ชัดว่าการแก้ปัญหาที่แตกต่างมีประโยชน์ของตัวเอง หนึ่งนี้มุ่งเน้นไปที่การรักษาความสะอาดแบบสุ่มจากมุมมองวิทยาศาสตร์ ไม่ได้หมายความว่ามันจะดีกว่าถุงแบบสุ่มหรืออย่างอื่น มันเป็นเพียงทางออกที่น่าลอง
มืด

3

สิ่งที่เกี่ยวกับการทำให้โอกาสเกิดวิกฤตนั้นขึ้นอยู่กับการโจมตี N ครั้งสุดท้าย รูปแบบที่เรียบง่ายอย่างหนึ่งคือโซ่มาร์คอฟบางชนิด: http://en.wikipedia.org/wiki/Markov_chainแต่รหัสนั้นง่ายมาก ๆ


IF turns_since_last_critical < M THEN 
   critial = false
   turns_since_last_critical++;
ELSE
   critial = IsCritical(chance);
   IF Critial THEN
       turns_since_last_critica = 0;
   ELSE
       turns_since_last_critica++;
   END IF;
END IF;

แน่นอนว่าคุณต้องสร้างคณิตศาสตร์ของคุณเพราะโอกาสของการวิพากษ์จะต่ำกว่าโอกาสของการวิพากษ์วิจารณ์เมื่อคุณรู้ว่ามันเปลี่ยนไปพอตั้งแต่ครั้งสุดท้าย


คุณได้รับผลกระทบส่วนใหญ่เพียงแค่ทำการโจมตีครั้งสุดท้ายในบัญชี ให้ P เป็นอัตราการยิงที่สังเกต, R อัตราการยิงหลังจากพลาดและ R / 2 อัตราการยิงหลังจากการยิง ตามคำนิยาม ณ จุดใดก็ตามคุณมีโอกาสที่จะตี P = P * R + (1-P) * (R / 2) ซึ่งหมายความว่า P = R / (2-R)
MSalters

2

OP,

ค่อนข้างมากถ้าคุณต้องการให้มันยุติธรรมมันจะไม่ถูกสุ่ม

ปัญหาของเกมของคุณคือความยาวของการแข่งขันที่เกิดขึ้นจริง การจับคู่ที่นานขึ้นคือการสุ่มน้อยลงที่คุณจะได้เห็น (crits จะมีค่า 20%) และการเข้าใกล้ค่าที่คุณตั้งใจ

คุณมีสองตัวเลือกคำนวณการโจมตีล่วงหน้าจากการหมุนครั้งก่อน ซึ่งคุณจะได้รับหนึ่งคริติคอลทุก ๆ 5 ครั้ง (ขึ้นอยู่กับคุณ 20%) แต่คุณสามารถทำการสั่งซื้อแบบสุ่ม

listOfFollowingAttacks = {Hit, Hit, Hit, Miss, Crit};

นั่นคือรูปแบบที่คุณต้องการ ดังนั้นให้เลือกแบบสุ่มจากรายการนั้นจนกว่าจะว่างเปล่ามันจะสร้างใหม่อีกครั้ง

นั่นเป็นรูปแบบที่ฉันสร้างขึ้นสำหรับเกมของฉันมันทำงานได้ค่อนข้างดีสำหรับสิ่งที่ฉันต้องการให้ทำ

ตัวเลือกที่สองของคุณคือเพิ่มโอกาสในการโจมตีคุณอาจจะเห็นจำนวนที่มากขึ้นในตอนท้ายของการโจมตีทั้งหมด (สมมุติว่าการแข่งขันของคุณจบลงอย่างรวดเร็ว) โอกาสที่% น้อยลงคุณจะได้รับ RNG มากขึ้น


2

คุณกำลังดูการกระจายเชิงเส้นเมื่อคุณอาจต้องการการกระจายตัวแบบปกติ

หากคุณจำย้อนกลับไปในวัยเด็กของคุณในการเล่น D & D คุณจะถูกขอให้ย้อนตายหลายด้าน n แล้วรวมผล

ตัวอย่างเช่นการกลิ้งตาย 4 ด้าน 6 x แตกต่างจากลูกเต๋ากลิ้ง 1 x 24 หน้า


2

City of Heroes มีกลไกที่เรียกว่า "streakbreaker" ซึ่งสามารถแก้ปัญหานี้ได้อย่างแน่นอน วิธีการทำงานของมันคือหลังจากที่สายของความยาวที่เกี่ยวข้องกับความน่าจะเป็นตีต่ำสุดในสายการโจมตีครั้งต่อไปจะรับประกันได้ว่าจะได้รับความนิยม ตัวอย่างเช่นหากคุณพลาดการโจมตีที่มีโอกาสถูกโจมตีมากกว่า 90% การโจมตีครั้งต่อไปของคุณจะถูกโจมตีอัตโนมัติ แต่หากโอกาสการโจมตีของคุณต่ำกว่าเช่น 60% คุณจะต้องมีการพลาดต่อเนื่องหลายครั้งเพื่อเรียก "streakbreaker" (I ไม่ทราบจำนวนที่แน่นอน)


2

ข้อความแสดงแทน

อันนี้สามารถคาดเดาได้จริง ๆ ... แต่คุณไม่สามารถแน่ใจได้


นี่ควรเป็นรูปพื้นหลังเดสก์ท็อปของฉัน !!

0

วิธีการเกี่ยวกับน้ำหนักค่าหรือไม่

ตัวอย่างเช่นหากคุณมีโอกาส 20% ที่จะเกิดการโจมตีคริติคอลให้สร้างตัวเลขระหว่าง 1 ถึง 5 โดยมีหนึ่งหมายเลขที่แทนการโจมตีคริติคอลหรือจำนวนระหว่าง 1 ถึง 100 กับ 20 หมายเลขที่เป็นคริติคอล

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


และทำไมถึงสร้างความแตกต่าง? มีโอกาสที่เท่าเทียมกันที่จะได้รับความสำคัญสำหรับตัวเลขทั้งสองชุด
samjudson

เผง ฉันแค่นำเสนอสองตัวเลือกสำหรับเขาสำหรับตัวอย่างของเขา 20% แม้ว่า 100 อาจจะทำงานได้ดีขึ้นถ้าคุณกำลังจัดการกับเปอร์เซ็นต์จำนวนเต็มเนื่องจากคุณจะต้องจำลอง "ตาย" เพียงหนึ่งเดียวถ้าคุณต้องการคิดแบบนั้น
Thomas Owens

ตัวเลือกที่คุณนำเสนอนั้นเป็นสิ่งที่เขาทำอยู่แล้ว
ceejayoz

2
ไม่ใช่เพื่อสิ่งที่เขาต้องการ เขาต้องการตัวสร้างตัวเลขที่ไม่สุ่มแม้ว่าเขาคิดว่ามันเรียกว่าเครื่องกำเนิดตัวเลขแบบสุ่ม
ceejayoz

0

ปฏิกิริยาเมื่อ: "ปัญหาคือฉันได้ผลลัพธ์ที่แย่มากในชีวิตจริง - บางครั้งผู้เล่นจะได้รับ 3 crits ใน 5 ครั้งบางครั้งก็ไม่มี 15 ครั้ง"

คุณมีโอกาสสักแห่งระหว่าง 3 ถึง 4% ที่จะไม่ได้อะไรเลยใน 15 ครั้ง ...


เมื่อคุณมีผู้เล่น 3,500 คนต่อสู้ออนไลน์ 10,000 ครั้งในหนึ่งนาทีปัญหาที่เกิดขึ้นใน 3% ของการต่อสู้เป็นปัญหาที่พบบ่อยมาก
นักคิด

จากนั้นอีกครั้งโชคร้ายที่เกิดขึ้นใน 3% ของการต่อสู้ยังคงเป็นเพียงโชคร้าย
MSalters

0

ฉันจะเสนอต่อไปนี้ "ตาย putback ล่าช้าแบบสุ่ม":

  • รักษาสองอาร์เรย์หนึ่ง ( in-array) แรกเริ่มเต็มไปด้วยค่าจาก 0 ถึง n-1, อื่น ๆ ( out-array) ที่ว่างเปล่า
  • เมื่อมีการร้องขอผลลัพธ์:
    • ส่งคืนค่าสุ่มจากค่าที่กำหนดทั้งหมดในin-array
    • ย้ายค่านี้จากin-arrayไปยังout-array
    • เลื่อนไปหนึ่งองค์ประกอบ(เหนือองค์ประกอบทั้งหมดรวมถึงองค์ประกอบที่ไม่ได้กำหนด!) จากout-arrayด้านหลังเข้าสู่in-array

นี้มีคุณสมบัติที่ว่ามันจะ "ตอบสนอง" ช้ากว่าที่ใหญ่กว่าnคือ ตัวอย่างเช่นหากคุณต้องการโอกาส 20% การตั้งค่าnเป็น 5 และการกดปุ่มบน 0 คือ "สุ่มน้อย" กว่าการตั้งค่าnถึง 10 และกดปุ่มบน 0 หรือ 1 และทำให้ 0 ถึง 199 จาก 1,000 จะเป็นเกือบ แยกไม่ออกจากการสุ่มอย่างแท้จริงผ่านกลุ่มตัวอย่างขนาดเล็ก คุณจะต้องปรับnให้เป็นขนาดตัวอย่างของคุณ


0

คำนวณการโจมตีแบบคริติคอลล่วงหน้าสำหรับผู้เล่นแต่ละคน

// OBJECT
//...
// OnAttack()
//...
c_h = c_h -1;
if ( c_h == 0 ) {
 // Yes, critical hit!
 c_h = random(5) + 1 // for the next time
 // ...
}

0

ฉันคิดว่าบางทีคุณกำลังใช้ฟังก์ชันการแจกแจงแบบสุ่มผิด คุณอาจไม่ต้องการให้มีการแจกแจงเลขคู่ ลองใช้การแจกแจงแบบปกติแทนเพื่อให้การโจมตีที่สำคัญกลายเป็นเรื่องแปลกไปมากกว่าการเข้าชมแบบ 'ปกติ'

ฉันทำงานกับ Java ดังนั้นฉันจึงไม่แน่ใจว่าคุณจะหาบางสิ่งสำหรับ C ++ ที่ให้ตัวเลขสุ่มกับการแจกแจงแบบปกติ แต่ต้องมีบางอย่างออกมา

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