Cần cho máy phát ngẫu nhiên dự đoán


151

Tôi là một nhà phát triển trò chơi web và tôi gặp vấn đề với các số ngẫu nhiên. Giả sử người chơi có 20% cơ hội nhận đòn chí mạng bằng thanh kiếm của mình. Điều đó có nghĩa là, 1 trong 5 lần truy cập nên rất quan trọng. Vấn đề là tôi có kết quả thực tế rất tệ - đôi khi người chơi nhận được 3 điểm trong 5 lần truy cập, đôi khi không có gì trong 15 lần truy cập. Các trận chiến khá ngắn (3-10 lần đánh), vì vậy điều quan trọng là có được sự phân phối ngẫu nhiên tốt.

Hiện tại tôi đang sử dụng PHP mt_rand(), nhưng chúng tôi chỉ chuyển mã của mình sang C ++, vì vậy tôi muốn giải quyết vấn đề này trong công cụ mới của trò chơi.

Tôi không biết liệu giải pháp là một số trình tạo ngẫu nhiên thống nhất hay có thể để nhớ các trạng thái ngẫu nhiên trước đó để buộc phân phối hợp lý.


58
Có khoảng 0,5% cơ hội của chính xác 3 lần truy cập quan trọng và 2 lần không quan trọng và 3,5% cơ hội của 15 lần truy cập không quan trọng liên tiếp, giả sử các số ngẫu nhiên thực sự.
Nixuz

10
+1 trở lên. Một đặc điểm của số ngẫu nhiên là bạn có được các ngoại lệ.
Mối quan tâmOfTunbridgeWells

44
@Nixus: Không, đó là khoảng 5% cơ hội của 3 lần truy cập quan trọng và 2 lần không quan trọng, bạn đang quên nhân với (5! / (3! * 2!)) = 10. Với mức độ tin cậy 95%, đó là không có ý nghĩa thống kê cho 3 lần tấn công quan trọng xảy ra trong 5 lần đình công.
erikkallen

7
Lúc đầu, tôi nghĩ đây là một câu hỏi ngớ ngẩn ... một lần nữa, tôi lại khiêm tốn vì SO.
SergioL

Câu trả lời:


39

Tôi đồng ý với các câu trả lời trước đó rằng sự ngẫu nhiên thực sự trong một số trò chơi nhỏ là không mong muốn - có vẻ như quá bất công cho một số trường hợp sử dụng.

Tôi đã viết một Shuffle Bag đơn giản như triển khai trong Ruby và đã thực hiện một số thử nghiệm. Việc thực hiện đã làm điều này:

  • Nếu nó vẫn có vẻ công bằng hoặc chúng tôi chưa đạt đến ngưỡng cuộn tối thiểu, nó sẽ trả về một cú đánh công bằng dựa trên xác suất bình thường.
  • Nếu xác suất quan sát được từ các cuộn quá khứ làm cho nó có vẻ không công bằng, nó sẽ trả về một cú đánh "công bằng".

Nó được coi là không công bằng dựa trên xác suất ranh giới. Chẳng hạn, với xác suất 20%, bạn có thể đặt 10% làm giới hạn dưới và 40% làm giới hạn trên.

Sử dụng các giới hạn đó, tôi thấy rằng với 10 lần truy cập, 14,2% thời gian thực hiện giả danh thực sự đã tạo ra kết quả nằm ngoài giới hạn đó . Khoảng 11% thời gian, 0 lượt truy cập quan trọng được ghi trong 10 lần thử. 3,3% thời gian, 5 hoặc nhiều lượt truy cập quan trọng đã hạ cánh xuống 10. Đương nhiên, sử dụng thuật toán này (với số lần lăn tối thiểu là 5), số tiền nhỏ hơn nhiều (0,03%) trong số các lần chạy "Công bằng" đã vượt quá giới hạn . Ngay cả khi cách triển khai dưới đây là không phù hợp (chắc chắn có thể thực hiện được nhiều điều thông minh hơn), điều đáng chú ý là thường thì người dùng của bạn sẽ cảm thấy không công bằng với giải pháp giả danh thực sự.

Đây là thịt của tôi FairishBagviết bằng Ruby. Toàn bộ triển khai và mô phỏng Monte Carlo nhanh chóng có sẵn ở đây (ý chính) .

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

Cập nhật: Sử dụng phương pháp này sẽ tăng xác suất tổng thể nhận được một đòn chí mạng, lên khoảng 22% khi sử dụng các giới hạn ở trên. Bạn có thể bù lại điều này bằng cách đặt xác suất "thực" của nó thấp hơn một chút. Xác suất 17,5% với sửa đổi công bằng mang lại xác suất dài hạn được quan sát là khoảng 20%, và giữ cho các hoạt động ngắn hạn cảm thấy công bằng.


Tôi nghĩ rằng đây là giải pháp tốt nhất phù hợp với nhu cầu của tôi. Shuffle bag được đề cập trong câu trả lời tốt nhất không phải là xấu, nhưng cần rất nhiều tính toán, và tôi thích giải pháp đơn giản nhất dẫn đến mục tiêu.
Nhà tư tưởng

Steve Rabin đã viết một bài viết thú vị về sự ngẫu nhiên trong các trò chơi. Nói tóm lại, hành vi "ngẫu nhiên" thực sự không thực sự "cảm thấy" ngẫu nhiên đối với hầu hết mọi người và các nghiên cứu đã ủng hộ điều này. Bài viết của ông có tên là Lọc ngẫu nhiên cho các quyết định AI và Logic trò chơi và xuất hiện trong "Trí tuệ lập trình trò chơi AI 2" (2003). Bạn nên kiểm tra nó, có thể sẽ hữu ích cho bạn.
Jeff Tucker

@IanTerrell Sẽ tốt khi nói kích thước mẫu của các bài kiểm tra của bạn lớn như thế nào, tức là có bao nhiêu trận chiến để xác định các xác suất đó.

@ user677656: Đó là ý chính, nhưng nó là 100 nghìn
Ian Terrell

223

Điều đó có nghĩa là, 1 trong 5 lần truy cập nên rất quan trọng. Vấn đề là tôi có kết quả thực tế rất tệ - đôi khi người chơi nhận được 3 điểm trong 5 lần truy cập, đôi khi không có gì trong 15 lần truy cập.

Những gì bạn cần là một túi shuffle . Nó giải quyết vấn đề ngẫu nhiên thực sự là quá ngẫu nhiên cho các trò chơi.

Thuật toán là như thế này: Bạn đặt 1 lượt truy cập quan trọng và 4 lần không quan trọng vào một cái túi. Sau đó, bạn chọn ngẫu nhiên thứ tự của chúng trong túi và chọn ra từng cái một. Khi túi rỗng, bạn điền lại với cùng các giá trị và chọn ngẫu nhiên. Bằng cách đó, bạn sẽ nhận được trung bình 1 lượt truy cập quan trọng trên 5 lần truy cập và nhiều nhất là 2 lượt truy cập quan trọng và 8 lần không quan trọng liên tiếp. Tăng số lượng vật phẩm trong túi cho ngẫu nhiên hơn.

Dưới đây là một ví dụ về cách triển khai (bằng Java) và các trường hợp thử nghiệm mà tôi đã viết cách đây một thời gian.


21
+ 1 cho ý tưởng tốt mà không bị chỉ trích. Chia tỷ lệ túi cho mức độ ngẫu nhiên cao hơn và để xử lý các phương sai trong cơ hội quan trọng giữa những người chơi (nếu biến
ofc

16
Bạn có thể có kích thước túi là 10. Đặt trong 1 lần đánh, cộng với 30% cơ hội của một giây. Nếu cơ hội quan trọng thay đổi, bạn có thể vứt cái túi đi và bắt đầu một cái mới. Xin lưu ý rằng bất kỳ sơ đồ nào như vậy đều có nguy cơ rằng nếu bạn (hoặc đối thủ của bạn) biết xác suất tấn công quan trọng của bạn và kích thước của túi, đôi khi bạn có thể biết chắc chắn rằng mình sẽ không bị chỉ trích nữa đối với một số cuộn nhất định. Điều này có thể ảnh hưởng đến chiến thuật.
Steve Jessop

3
Vâng ... trong một cái gì đó như thế này, bạn chạy ricks tương tự như đếm thẻ. Tôi có mạo hiểm với một con chim cánh cụt hay tham gia vào vụ giết người lớn không ... một tập hợp nhỏ các kết quả tiềm năng có thể làm giảm nguy cơ mất mát và tăng cơ hội bị "đánh bạc"
Matthew Whited

8
Tôi thích ý tưởng túi xáo trộn nhưng tôi không nghĩ trò chơi này phù hợp với "tinh thần" của trò chơi bởi vì xác suất tấn công chí mạng của bạn là 20% (có nghĩa là bạn không thể làm gì trong 10 lần đánh) không còn là xác suất nữa. Nó trở thành chính xác 1 hit cứ sau 5 hit. Hơn nữa, việc lục lại túi nếu thay đổi xác suất trúng quan trọng sẽ gây ra trục trặc trong trò chơi. Nếu cú ​​đánh chí mạng của tôi đã được thực hiện, tôi sẽ tự đánh vần để nhận được lời phê bình tiếp theo sớm hơn: p
Michaël Carpentier

2
@Jonathan: làm cho chiếc túi có kích thước lớn mà bạn cung cấp cho nó thực sự hoàn tác toàn bộ ý tưởng túi: để đảm bảo điều gì đó xảy ra (mức độ quan trọng đạt được) trong một số lần ném chấp nhận được. Làm cho túi 50000 lớn gần giống như sử dụng trình tạo số ngẫu nhiên.
dstibbe

113

Bạn đã có một sự hiểu lầm về ý nghĩa ngẫu nhiên.

Cái nào trong số này là ngẫu nhiên hơn?

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Trong khi cốt truyện thứ hai trông phân bố đồng đều hơn, thì thực sự ngẫu nhiên hơn là cốt truyện đầu tiên. Tâm trí con người thường nhìn thấy các mẫu ngẫu nhiên, vì vậy chúng ta thấy các cụm trong cốt truyện đầu tiên là các mẫu, nhưng chúng không phải - chúng chỉ là một phần của một mẫu được chọn ngẫu nhiên.


25
Giải thích về Numb3rs!
RMAAlmeida

9
Về mặt kỹ thuật, bạn không thể đo lường sự ngẫu nhiên. Cả hai bản phân phối trông khá độc đoán với tôi, mặc dù dự đoán của tôi là cả hai đều được tạo bằng thuật toán. Bạn có thể thực hiện một số thử nghiệm trên lô đầu tiên và xác định rằng nó có khả năng đến từ một quy trình đặt các điểm theo phân phối thống nhất, nhưng bạn sẽ không thể kết luận rằng nó ngẫu nhiên hơn. Như một ví dụ mẫu, bạn có thể tạo một âm mưu như đầu tiên bằng cách sử dụng một bộ tạo cộng tuyến tính, sau đó tạo một âm mưu như thứ hai bằng cách sử dụng nhiễu khuếch đại từ một diode zener. Hãy thử từ không tương quan thay vì ngẫu nhiên.
Dietrich Epp

8
Bạn có thể đo xác suất phân phối nói là ngẫu nhiên.
ceejayoz


2
Công bằng mà nói, trong khi OP có thể không sử dụng các thuật ngữ chính xác, anh ta hiểu rằng trình tạo số ngẫu nhiên đang mang lại cho anh ta một cái gì đó giống như biểu đồ thứ nhất, khi anh ta muốn một cái gì đó giống như biểu đồ thứ hai hơn vì nó cảm thấy "công bằng" hơn với người dùng.
Kip

88

Đưa ra hành vi bạn yêu cầu, tôi nghĩ bạn đang chọn ngẫu nhiên biến sai.

Thay vì chọn ngẫu nhiên liệu lần truy cập này có quan trọng hay không, hãy thử ngẫu nhiên số lượt cho đến khi lần đánh quan trọng tiếp theo xảy ra. Ví dụ: chỉ cần chọn một số trong khoảng từ 2 đến 9 mỗi khi người chơi nhận được một lời phê bình, và sau đó đưa cho họ mức độ quan trọng tiếp theo sau khi nhiều vòng đấu đã trôi qua. Bạn cũng có thể sử dụng các phương pháp súc sắc để tiến gần hơn đến phân phối bình thường - ví dụ: bạn sẽ nhận được sự phê phán tiếp theo trong lượt 2D4.

Tôi tin rằng kỹ thuật này được sử dụng trong các game nhập vai có các cuộc chạm trán ngẫu nhiên trong thế giới bên kia - bạn chọn ngẫu nhiên một bộ đếm bước và sau nhiều bước đó, bạn lại bị tấn công. Cảm giác công bằng hơn rất nhiều vì bạn gần như không bao giờ bị hai lần chạm trán liên tiếp - nếu điều đó xảy ra dù chỉ một lần, người chơi sẽ trở nên cáu kỉnh.


Tôi nghĩ rằng đây là giải pháp tuyệt vời, nhưng cơ hội 80% thì sao?
Nhà tư tưởng

Tôi cũng thích sử dụng máy phát ngẫu nhiên đa chiều. Cơ hội để đánh + Cơ hội quyền lực + Cơ hội để phê phán. Cũng giống như gieo một vài con xúc xắc khác nhau trong D & D
Matthew Whited

Tôi thích ý tưởng này, và bạn hoàn toàn chính xác về điều ngược lại, điều đó đã được sử dụng trong tưởng tượng cuối cùng trong một thời gian rất dài, chẳng hạn
Ed James

Một vấn đề với điều này là nó chỉ hoạt động nếu xác suất quan trọng gần như không đổi giữa các lần truy cập. Giả sử rằng giữa trận chiến, người chơi sẽ sử dụng một câu thần chú nhân đôi khả năng bị tấn công chí mạng. Sau đó, làm thế nào để bạn điều chỉnh số lượt?
Alex319

+1 Rất đẹp, cũng xử lý xác suất trúng vòng ít hơn 20% rất dễ dàng.
Alice Purcell

53

Đầu tiên, xác định phân phối "thích hợp". Các số ngẫu nhiên là, ngẫu nhiên, ngẫu nhiên - kết quả bạn thấy hoàn toàn phù hợp với tính ngẫu nhiên (giả).

Mở rộng về điều này, tôi cho rằng những gì bạn muốn là một chút cảm giác "công bằng", vì vậy người dùng không thể đi 100 lượt mà không thành công. Nếu vậy, tôi sẽ theo dõi số lần thất bại kể từ lần thành công cuối cùng và cân nhắc kết quả được tạo ra. Giả sử bạn muốn 1 trong 5 cuộn để "thành công". Vì vậy, bạn tạo ngẫu nhiên một số từ 1 đến 5 và nếu đó là 5, thật tuyệt.

Nếu không, ghi lại thất bại và lần sau, tạo một số từ 1 đến 5, nhưng thêm vào, sàn (numFailures / 2). Vì vậy, lần này, một lần nữa, họ có cơ hội 1 trên 5. Nếu họ thất bại, lần sau, khoảng thời gian chiến thắng là 4 5; 2 trong 5 cơ hội thành công. Với những lựa chọn này, sau 8 lần thất bại, họ chắc chắn sẽ thành công.


Trên lưu ý đó ... các phạm vi số ngẫu nhiên sẽ ảnh hưởng đến phân phối ... ví dụ: chọn Random r = new Random (); r.Tiếp theo (1,5) so với r. Tiếp theo (1, 1000000)% 200000
Eoin Campbell

23
+1 khi thấy vấn đề đằng sau yêu cầu thay vì nói với OP, anh ta hiểu nhầm ngẫu nhiên.
Boris Callens

4
Lưu ý rằng nếu bạn làm điều này, thì tỷ lệ thành công chung của họ sẽ lớn hơn 1 trên 5. Cách xung quanh là (ví dụ) chọn ngẫu nhiên 20 số khác nhau trong phạm vi 1..100 và xác định trước rằng những số đó sẽ là những lời phê bình của họ. Đó là một loạt các sổ sách kế toán, mặc dù.
Steve Jessop

"Sẽ lớn hơn 1 trên 5" - ý tôi là sẽ lâu dài.
Steve Jessop

Bạn có thể thu nhỏ xác suất bắt đầu xuống một chút, để tỷ lệ chung giảm xuống 1/5. Tôi đã không biết bạn phải giảm bao nhiêu, nhưng mọi thứ đều liên tục nên phải có câu trả lời đúng.
Steve Jessop

35

Làm thế nào về việc thay thế mt_rand () bằng một cái gì đó như thế này?

Truyện tranh XKCD (RFC 1149.5 chỉ định 4 là số ngẫu nhiên được hiệu chỉnh theo tiêu chuẩn của IEEE.)

(RFC 1149.5 chỉ định 4 là số ngẫu nhiên được hiệu chỉnh theo tiêu chuẩn của IEEE.)

Từ XKCD .


Tốt, nhưng điều này sẽ giải quyết vấn đề phân phối số ngẫu nhiên OP? ;-)
Arjan Einbu

Không thực sự; Anh ta yêu cầu một RNG không ngẫu nhiên, mà anh ta có thể sử dụng chức năng này; nhưng những gì anh ấy thực sự muốn được giải thích tốt hơn bằng câu trả lời hàng đầu hiện tại ( stackoverflow.com/questions/910215/910224#910224 )
Colin Pickard

28
Điều này là ngẫu nhiên hơn OP muốn
Çağdaş Tekin

-1 vì RFC1149 không có phần 5 (và thay vào đó, không có 1149,5); +1 cho tính ngẫu nhiên công bằng.
greyfade

34

Hy vọng bài viết này sẽ hỗ trợ bạn: http://web.archive.org/web/20090103063439/http://www.gamedev.net:80/reference/design/features/randomness/

Phương pháp tạo 'số ngẫu nhiên' này phổ biến trong các trò chơi rpg / mmorpg.

Vấn đề nó giải quyết là đây (giải nén):

Một con nhện lưỡi kiếm ở cổ họng của bạn. Nó đánh và bạn bỏ lỡ. Nó đánh một lần nữa và bạn lại bỏ lỡ. Và lặp đi lặp lại, cho đến khi bạn không còn gì để đánh. Bạn đã chết và có một con nhện nặng hai tấn đang hả hê trên xác chết của bạn. Không thể nào? Không thể cải thiện? Đúng. Nhưng được cung cấp đủ người chơi và có đủ thời gian, điều không thể trở nên gần như chắc chắn. Đó không phải là con nhện lưỡi kiếm cứng, nó chỉ là sự xui xẻo. Bực bội như thế nào. Nó đủ để làm cho một người chơi muốn bỏ.


1
Tôi đã nghe một biến thể về điều này - "một trong một triệu sự kiện xảy ra 6.000 lần trong dân số thế giới".
ceejayoz

19

Những gì bạn muốn không phải là số ngẫu nhiên, mà là những con số có vẻ ngẫu nhiên đối với con người. Những người khác đã đề xuất các thuật toán riêng lẻ, có thể giúp bạn, như Shuffle Bad.

Để có phân tích chi tiết và sâu rộng về miền này, hãy xem Trí tuệ lập trình trò chơi AI 2 . Toàn bộ cuốn sách đáng đọc cho bất kỳ nhà phát triển trò chơi nào, ý tưởng về "những con số dường như ngẫu nhiên" được xử lý trong chương:

Tính ngẫu nhiên được lọc cho các quyết định AI và Logic trò chơi :

Tóm tắt: Sự khôn ngoan thông thường cho thấy rằng trình tạo số ngẫu nhiên càng tốt, trò chơi của bạn sẽ càng khó đoán hơn. Tuy nhiên, theo các nghiên cứu tâm lý học, sự ngẫu nhiên thực sự trong thời gian ngắn thường có vẻ không hợp lý với con người. Bài viết này cho thấy cách đưa ra các quyết định AI ngẫu nhiên và logic trò chơi trông ngẫu nhiên hơn đối với người chơi, trong khi vẫn duy trì tính ngẫu nhiên thống kê mạnh mẽ.

Bạn cũng có thể tìm thấy một chương thú vị khác:

Thống kê số ngẫu nhiên

Tóm tắt: Số ngẫu nhiên được sử dụng nhiều nhất bởi Trí tuệ nhân tạo và các trò chơi nói chung. Bỏ qua tiềm năng của họ là làm cho trò chơi trở nên dễ đoán và nhàm chán. Sử dụng chúng không đúng cách có thể tệ như bỏ qua chúng hoàn toàn. Hiểu cách tạo số ngẫu nhiên, giới hạn và khả năng của chúng, có thể loại bỏ nhiều khó khăn khi sử dụng chúng trong trò chơi của bạn. Bài viết này cung cấp cái nhìn sâu sắc về các số ngẫu nhiên, thế hệ của chúng và các phương pháp để phân tách các số tốt và xấu.


8

Chắc chắn bất kỳ thế hệ số ngẫu nhiên có cơ hội sản xuất chạy như vậy? Bạn sẽ không nhận được một mẫu đủ lớn trong 3-10 cuộn để xem tỷ lệ phần trăm phù hợp.

Có lẽ những gì bạn muốn là một ngưỡng thương xót ... hãy nhớ 10 cuộn cuối cùng và nếu họ không có một đòn chí mạng nào, hãy cho họ một người chơi miễn phí. Làm mịn các cáp treo và mũi tên ngẫu nhiên.


8

Giải pháp của bạn tốt nhất có thể play-thử nghiệm với nhiều khác nhau không sơ đồ ngẫu nhiên và chọn một phương án khiến người chơi hài lòng nhất.

Bạn cũng có thể thử chính sách lùi cho cùng một số trong một cuộc chạm trán nhất định, ví dụ: nếu người chơi cuộn một 1lượt trong lượt đầu tiên của họ chấp nhận nó. Để có được một cái khác 1họ cần phải lăn 2 1s liên tiếp. Để có được một phần ba 1họ cần 3 liên tiếp, ad infinitum.


7

Thật không may, những gì bạn đang yêu cầu thực sự là một trình tạo số không ngẫu nhiên - bởi vì bạn muốn tính đến các kết quả trước đó khi xác định số tiếp theo. Đây không phải là cách mà các trình tạo số ngẫu nhiên làm việc tôi sợ.

Nếu bạn muốn 1 trong số 5 lần truy cập là quan trọng thì chỉ cần chọn một số trong khoảng từ 1 đến 5 và nói rằng lần truy cập đó sẽ rất quan trọng.


1
anh ấy muốn trò chơi ngẫu nhiên thân thiện, nếu bạn sử dụng các số được tạo ngẫu nhiên nghiêm ngặt trong một số trường hợp bạn sẽ có kết quả "ngẫu nhiên Hàn Quốc". Đó là những kết quả ngẫu nhiên khiến người chơi tức giận và thất vọng quá thường xuyên (hỏi bất kỳ người chơi dòng 2 nào);)
Juan Techera

Do đó, nếu cú ​​đánh đầu tiên là một cú đánh, bốn cú đánh tiếp theo sẽ không xảy ra. Nghe có vẻ như đây là những gì OP muốn, nhưng khi bạn nói nó như thế này, nó nghe có vẻ chậm lại. Bạn nhận được UV của tôi cho điều đó.
belgariontheking

-1 bạn có vẻ khó hiểu "ngẫu nhiên" với "không nhớ" - en.wikipedia.org/wiki/Memorylessness
Alice Purcell

7

mt_rand () dựa trên triển khai Mersenne Twister , có nghĩa là nó mang lại một trong những phân phối ngẫu nhiên tốt nhất bạn có thể nhận được.

Rõ ràng những gì bạn muốn không phải là ngẫu nhiên, vì vậy bạn nên bắt đầu chỉ định chính xác những gì bạn muốn. Bạn có thể nhận ra rằng bạn có những kỳ vọng mâu thuẫn - rằng kết quả thực sự ngẫu nhiên và không thể dự đoán được, nhưng đồng thời chúng không nên thể hiện các biến thể cục bộ từ xác suất đã nêu - nhưng sau đó nó có thể dự đoán được. Nếu bạn đặt tối đa 10 lần không liên tiếp, thì bạn vừa nói với người chơi "nếu bạn có 9 lần không liên tiếp, thì lần tiếp theo sẽ rất quan trọng với sự chắc chắn 100%" - bạn có thể như cũng không bận tâm với sự ngẫu nhiên cả.


6

Qua một số lượng nhỏ các bài kiểm tra như vậy, bạn sẽ mong đợi kết quả như vậy:

Sự ngẫu nhiên thực sự chỉ có thể dự đoán được trên một kích thước tập hợp khổng lồ, như vậy hoàn toàn có thể lật một đồng xu và nhận được 3 lần liên tiếp lần đầu tiên, tuy nhiên trong vài triệu lần lật bạn sẽ kết thúc với khoảng 50-50.


7
Mặc dù vẫn có cơ hội sau vài triệu lần lật, bạn vẫn sẽ chỉ nhìn thấy một mặt của đồng tiền. Mặc dù nếu điều này xảy ra, có lẽ bạn đang ngồi quá gần với một ổ đĩa không có khả năng vô hạn: P
Grant Peters

haha, vâng, nhưng cơ hội rất thấp đến mức các định luật toán học nói rằng bạn sẽ thấy một phân phối chẵn (ish).
Ed James

6

Tôi thấy rất nhiều câu trả lời đề nghị theo dõi các số được tạo trước đó hoặc xáo trộn tất cả các giá trị có thể.

Cá nhân, tôi không đồng ý rằng 3 crits liên tiếp là xấu. Tôi cũng không đồng ý rằng 15 lần không liên tiếp là xấu.

Tôi sẽ giải quyết vấn đề, bằng cách sửa đổi cơ hội phê bình nó sau mỗi số. Ví dụ (để thể hiện ý tưởng):

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
}

Bạn càng không nhận được một lời phê bình - bạn càng có nhiều cơ hội cho hành động tiếp theo của mình để phê bình. Thiết lập lại tôi bao gồm là hoàn toàn tùy chọn và nó sẽ cần thử nghiệm để biết liệu nó có cần thiết hay không. Có thể hoặc không mong muốn đưa ra xác suất cao hơn về một lần phê bình cho nhiều hơn một hành động liên tiếp, sau một chuỗi hành động dài không phê bình.

Chỉ cần ném 2 xu của tôi ...


Tôi thích cách tiếp cận này. Tôi có thể sẽ làm điều đó theo cách khác. Bắt đầu với cơ hội thấp hơn và xây dựng tối đa 20% + một số phần trăm được thêm vào cho đến khi nó đạt và đặt lại một lần nữa với số tiền thấp.
Matthew

5

Một vài câu trả lời hàng đầu là những lời giải thích tuyệt vời, vì vậy tôi sẽ chỉ tập trung vào một thuật toán cho phép bạn kiểm soát xác suất của "các vệt xấu" trong khi không bao giờ trở nên xác định. Đây là những gì tôi nghĩ bạn nên làm:

Thay vì chỉ định p , tham số của phân phối Bernoulli, là xác suất của một lần truy cập quan trọng, hãy chỉ định ab , các tham số của phân phối beta, "liên hợp trước" của phân phối Bernoulli. Bạn cần theo dõi AB , số lần truy cập quan trọng và không quan trọng cho đến nay.

Bây giờ, để chỉ định ab , đảm bảo rằng a / (a ​​+ b) = p, cơ hội của một đòn chí mạng. Điều gọn gàng là (a + b) định lượng mức độ bạn muốn A / (A + B) gần với p nói chung.

Bạn làm mẫu của bạn như thế này:

hãy p(x)là hàm mật độ xác suất của phân phối beta. Nó có sẵn ở nhiều nơi, nhưng bạn có thể tìm thấy nó trong GSL dưới dạng gsl_ran_beta_pdf.

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

Chọn một điểm nhấn quan trọng bằng cách lấy mẫu từ phân phối bernoulli với xác suất p_1 / (p_1 + p_2)

Nếu bạn thấy rằng các số ngẫu nhiên có quá nhiều "vệt xấu", hãy tăng tỷ lệ ab , nhưng trong giới hạn, khi ab đi đến vô cùng, bạn sẽ có cách tiếp cận túi xáo trộn được mô tả trước đây.

Nếu bạn thực hiện điều này, xin vui lòng cho tôi biết làm thế nào nó đi!


5

Nếu bạn muốn phân phối không khuyến khích các giá trị lặp lại, bạn có thể sử dụng thuật toán từ chối lặp lại đơn giản.

ví dụ

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

Mã này từ chối các giá trị lặp lại 95% thời gian, làm cho việc lặp lại không thể xảy ra nhưng không phải là không thể. Theo thống kê thì nó hơi xấu, nhưng có lẽ nó sẽ tạo ra kết quả mà bạn muốn. Tất nhiên, nó sẽ không ngăn chặn phân phối như "5 4 5 4 5". Bạn có thể nhận fancier và từ chối lần thứ hai (nói) 60% thời gian và lần thứ ba cuối cùng (nói) 30%.

Tôi không khuyên đây là thiết kế trò chơi hay. Đơn giản chỉ cần đề xuất làm thế nào để đạt được những gì bạn muốn.


Một số giá trị trong trò chơi của tôi như đòn chí mạng không thể có hơn 50% cơ hội, vì vậy tôi sẽ chặn việc lặp lại, nhưng điều này làm giảm cơ hội sự kiện cho một số phần trăm.
Nhà tư tưởng

4

Nó không thực sự rõ ràng những gì bạn muốn. Có thể tạo một hàm sao cho 5 lần đầu tiên bạn gọi nó, nó sẽ trả về các số 1-5 theo thứ tự ngẫu nhiên.

Nhưng điều đó không thực sự ngẫu nhiên. Người chơi sẽ biết rằng mình sẽ nhận được đúng 5 điểm trong 5 lần tấn công tiếp theo. Nó có thể là những gì bạn muốn mặc dù, và trong trường hợp đó, bạn chỉ cần tự mình viết mã. (tạo một mảng chứa các số và sau đó xáo trộn chúng)

Ngoài ra, bạn có thể tiếp tục sử dụng phương pháp hiện tại của mình và cho rằng kết quả hiện tại của bạn là do trình tạo ngẫu nhiên xấu. Lưu ý rằng không có gì sai với số hiện tại của bạn. Giá trị ngẫu nhiên là ngẫu nhiên. đôi khi bạn nhận được 2, 3 hoặc 8 giá trị tương tự trong một hàng. Bởi vì chúng là ngẫu nhiên. Một trình tạo ngẫu nhiên tốt chỉ đảm bảo rằng trung bình, tất cả các số sẽ được trả về như nhau thường xuyên.

Tất nhiên, nếu bạn đang sử dụng một trình tạo ngẫu nhiên xấu, điều đó có thể đã làm sai lệch kết quả của bạn và nếu vậy, chỉ cần chuyển sang một trình tạo ngẫu nhiên tốt hơn sẽ khắc phục vấn đề. (Kiểm tra thư viện Boost.Random để biết các trình tạo tốt hơn)

Ngoài ra, bạn có thể nhớ các giá trị N cuối cùng được trả về bởi hàm ngẫu nhiên của bạn và cân nhắc kết quả của các giá trị đó. (một ví dụ đơn giản sẽ là "cho mỗi lần xuất hiện của kết quả mới, có 50% cơ hội chúng ta nên loại bỏ giá trị và nhận một giá trị mới"

Nếu tôi phải đoán, tôi sẽ nói rằng gắn bó với sự ngẫu nhiên "thực tế" là đặt cược tốt nhất của bạn. Hãy chắc chắn rằng bạn sử dụng một trình tạo ngẫu nhiên tốt, và sau đó tiếp tục theo cách bạn đang làm.


Trên thực tế, chức năng anh ta đang sử dụng giống như RNG tốt nhất trong thư viện boost.
Michael Borgwardt

MT không phải là "tốt nhất", cuối cùng tôi đã kiểm tra. Nó đẹp, đơn giản và nhanh chóng, nhưng nó không tạo ra sự phân phối tốt nhất. Dù sao, lấy một triệu số ngẫu nhiên và kiểm tra phân phối. Tìm hiểu xem chức năng ngẫu nhiên của bạn thực sự cung cấp cho bạn một phân phối thống nhất hay không. Nếu không, hãy tìm một máy phát tốt hơn. Nếu có, hãy hút nó lên và chấp nhận hàng crits thỉnh thoảng, hoặc gian lận và làm cho kết quả ít ngẫu nhiên hơn và dễ dự đoán hơn.
jalf

4

Bạn có thể tạo một danh sách chứa các số từ 1 đến 5 và sắp xếp chúng theo ngẫu nhiên. Sau đó, chỉ cần đi qua danh sách bạn tạo ra. Bạn có đảm bảo chạy vào mọi số ít nhất một lần ... Khi bạn vượt qua 5 số đầu tiên, chỉ cần tạo 5 số khác ...


4

Tôi khuyên dùng hệ thống tỷ lệ phần trăm lũy tiến như Blizzard sử dụng: http://www.shacknews.com/onearticle.x/57886

Nói chung, bạn cuộn RNG sau đó so sánh nó với một giá trị để xác định xem thành công hay không. Điều đó có thể trông giống như:

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

Tất cả những gì bạn cần làm là thêm vào một sự gia tăng lũy ​​tiến trong cơ hội cơ bản ...

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

Nếu bạn cần nó trở nên lạ mắt hơn, thật dễ dàng để thêm vào. Bạn có thể giới hạn số tiền mà ProgressiveChance có thể nhận được để tránh cơ hội quan trọng 100% hoặc đặt lại nó vào một số sự kiện nhất định. Bạn cũng có thể tăng lũy ​​tiến với số lượng nhỏ hơn mỗi lần tăng với thứ gì đó như lũy tiến + = (1 - lũy tiến) * SCALE trong đó SCALE <1.


4

Chà, nếu bạn học toán một chút, có lẽ bạn có thể thử phân phối theo cấp số nhân

Ví dụ: nếu lambda = 0,5, giá trị mong đợi là 2 (hãy đọc bài viết đó!), Có nghĩa là bạn rất có thể sẽ nhấn / crit / bất cứ điều gì mỗi lượt thứ 2 (như 50%, hả?). Nhưng với phân phối xác suất như vậy, bạn sẽ bỏ lỡ xác định (hoặc làm ngược lại với bất cứ điều gì) ở lượt thứ 0 (một sự kiện, trong đó sự kiện đã xảy ra và Turn_count đã được đặt lại), có 40% cơ hội để đánh lượt tiếp theo, khoảng 65% cơ hội để thực hiện lần thứ 2 (tiếp theo sau tiếp theo), khoảng 80% để đạt hạng 3 và cứ thế.

Toàn bộ mục đích của phân phối đó là nếu một người có 50% cơ hội trúng và anh ta bỏ lỡ 3 lần liên tiếp, anh ta sẽ nhanh nhẹn (tốt, hơn 80% cơ hội, và nó tăng mỗi lượt tiếp theo). Nó dẫn đến kết quả "công bằng" hơn, giữ nguyên 50% cơ hội không thay đổi.

Nắm bắt 20% cơ hội của bạn, bạn có

  • 17% để phê bình lượt đầu tiên
  • 32% để crit lượt thứ 2, nếu không có crit xảy ra trong tất cả các lần trước.
  • 45% để crit lượt thứ 3, nếu không có crit xảy ra trong tất cả các lần trước.
  • 54% để crit lượt thứ 4, nếu không có crit xảy ra trong tất cả các lần trước.
  • ...
  • 80% để crit lượt thứ 8, nếu không có crit xảy ra trong tất cả các lần trước.

Nó vẫn còn khoảng 0,2% (so với 5%) cơ hội 3 crits + 2 non-crits trong 5 lượt tiếp theo. Và có 14% cơ hội của 4 kết quả không phải là crits, 5% của 5, 1,5% cho 6, 0,3% cho 7, 0,07% cho 8 kết quả không phải là crits. Tôi đặt cược "công bằng hơn" của nó hơn 41%, 32%, 26%, 21% và 16%.

Hy vọng bạn vẫn không chán đến chết.


Điều này khá giống với giải pháp của tôi, ngoại trừ việc nó chỉ "nhớ" thời gian kể từ lần tấn công quan trọng cuối cùng. Theo giải pháp này, một chuỗi gồm 4 lần truy cập quan trọng giống như chuỗi 1 lần truy cập quan trọng theo xác suất về tương lai. Vì vậy, nếu các lượt truy cập quan trọng là tốt, giải pháp này sẽ hạn chế rủi ro nhược điểm của bạn, nhưng không phải là nhược điểm của bạn. Giải pháp của tôi ảnh hưởng đến cả hai.
Neil G

Rõ ràng là các giải pháp khác nhau có lợi ích riêng của họ. Điều này tập trung vào việc giữ sự ngẫu nhiên sạch sẽ từ quan điểm khoa học. Điều đó không có nghĩa, bằng cách nào đó nó tốt hơn so với túi xáo trộn hoặc bất cứ thứ gì khác. Đó chỉ là một giải pháp có vẻ đáng để thử.
Tối

3

Điều gì về việc làm cho cơ hội quan trọng phụ thuộc vào các cuộc tấn công N cuối cùng. Một sơ đồ đơn giản là một loại chuỗi markov: http://en.wikipedia.org/wiki/Markov_chain nhưng dù sao mã cũng rất đơn giản.


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;

Tất nhiên bạn phải thực hiện toán học của mình vì cơ hội phê bình thấp hơn cơ hội phê bình một khi bạn biết rằng nó đã đủ lượt kể từ lần cuối cùng


Bạn nhận được hầu hết các hiệu ứng bằng cách chỉ thực hiện cuộc tấn công cuối cùng trong tài khoản. Gọi P là tỷ lệ trúng được quan sát, R tỷ lệ trúng sau một lần bỏ lỡ và R / 2 tỷ lệ trúng sau một lần đánh. Theo định nghĩa, tại bất kỳ thời điểm nào, sau đó bạn có cơ hội đạt P = P * R + (1-P) * (R / 2). Điều này có nghĩa là P = R / (2-R)
MSalters

2

OP

Khá nhiều, nếu bạn muốn nó công bằng, nó sẽ không phải là ngẫu nhiên.

Vấn đề của trò chơi của bạn là độ dài trận đấu thực tế. Trận đấu càng dài, bạn sẽ thấy càng ít sự ngẫu nhiên (crits sẽ có xu hướng là 20%) và nó sẽ tiếp cận các giá trị dự định của bạn.

Bạn có hai tùy chọn, tính toán trước các cuộc tấn công dựa trên các cuộn trước đó. Bạn sẽ nhận được một crit cứ sau 5 lần tấn công (dựa trên 20% của bạn), nhưng bạn có thể thực hiện thứ tự nó xảy ra ngẫu nhiên.

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

Đó là mẫu bạn muốn. Vì vậy, làm cho nó chọn ngẫu nhiên từ danh sách đó, cho đến khi trống, họ tạo lại nó.

Đó là một mô hình tôi đã tạo cho trò chơi của mình, nó hoạt động khá tốt, cho những gì tôi muốn nó làm.

tùy chọn thứ hai của bạn, sẽ là, tăng cơ hội phê bình, có lẽ bạn sẽ thấy một số chẵn hơn vào cuối tất cả các cuộc tấn công (giả sử rằng các trận đấu của bạn kết thúc khá nhanh). Càng ít% cơ hội, bạn càng nhận được nhiều RNG.


2

Bạn đang xem một phân phối tuyến tính, khi bạn có thể muốn một phân phối bình thường.

Nếu bạn còn nhớ hồi còn trẻ chơi D & D, bạn đã được yêu cầu lăn nhiều cái chết hai mặt, sau đó tổng hợp kết quả.

Ví dụ, lăn xúc xắc 4 x 6 mặt khác với lăn xúc xắc 1 x 24 mặt.


2

City of Heroes thực sự có một thợ máy gọi là "streakbreaker" giải quyết chính xác vấn đề này. Cách thức hoạt động của nó là sau khi một chuỗi bỏ lỡ có độ dài liên quan đến xác suất trúng thấp nhất trong chuỗi, cuộc tấn công tiếp theo được đảm bảo là một cú đánh. Ví dụ: nếu bạn bỏ lỡ một cuộc tấn công với hơn 90% để có cơ hội thì cuộc tấn công tiếp theo của bạn sẽ tự động tấn công, nhưng nếu cơ hội trúng của bạn thấp hơn như 60% thì bạn sẽ cần phải có một vài lần bỏ lỡ liên tiếp để kích hoạt "kẻ tấn công" (tôi không biết con số chính xác)


2

văn bản thay thế

Điều này thực sự có thể dự đoán được ... nhưng bạn không bao giờ có thể chắc chắn.


Đây phải là hình nền máy tính của tôi !!

0

Làm thế nào về trọng số giá trị?

Ví dụ: nếu bạn có 20% cơ hội để đánh chí mạng, hãy tạo một số từ 1 đến 5 với một số đại diện cho một đòn chí mạng hoặc một số từ 1 đến 100 với 20 số là một đòn chí mạng.

Nhưng miễn là bạn đang làm việc với các số ngẫu nhiên hoặc giả ngẫu nhiên, không có cách nào có khả năng tránh kết quả mà bạn hiện đang thấy. Đó là bản chất của sự ngẫu nhiên.


Và tại sao điều đó sẽ làm cho bất kỳ sự khác biệt? Có một cơ hội chính xác như nhau để có được một chỉ trích cho cả hai bộ số.
samjudson

Chính xác. Tôi chỉ đưa ra hai lựa chọn cho anh ấy cho ví dụ 20% của anh ấy. Mặc dù 100 có thể sẽ hoạt động tốt hơn nếu bạn đang xử lý toàn bộ tỷ lệ phần trăm, vì bạn chỉ cần mô phỏng một "chết", nếu bạn muốn nghĩ về nó như thế.
Thomas Owens

Các tùy chọn bạn đang trình bày chính xác là những gì anh ấy đã làm.
ceejayoz

2
Không phải vì những gì anh ấy muốn. Anh ta muốn một trình tạo số không ngẫu nhiên, ngay cả khi anh ta nghĩ rằng đó được gọi là trình tạo số ngẫu nhiên.
ceejayoz

0

Phản ứng về: "Vấn đề là tôi nhận được kết quả thực tế rất tệ - đôi khi người chơi nhận được 3 điểm trong 5 lần truy cập, đôi khi không có gì trong 15 lần truy cập."

Bạn có cơ hội ở đâu đó trong khoảng từ 3 đến 4% khi không nhận được gì trong 15 lần truy cập ...


Khi bạn có 3500 người chơi trực tuyến chiến đấu 10000 trận trong một phút, vấn đề xảy ra trong 3% trận chiến là vấn đề rất phổ biến.
Nhà tư tưởng

Sau đó, một lần nữa, xui xẻo xảy ra trong 3% trận chiến vẫn chỉ là xui xẻo.
MSalters

0

Tôi sẽ đề xuất "cái chết ngẫu nhiên bị trì hoãn" sau đây:

  • Duy trì hai mảng, một (in-array ban đầu chứa đầy các giá trị từ 0 đến n-1, còn lại ( out-array) trống
  • Khi một kết quả được yêu cầu:
    • trả về một giá trị ngẫu nhiên từ tất cả các giá trị được xác định trongin-array
    • di chuyển giá trị này từ in-arrayđếnout-array
    • di chuyển một yếu tố ngẫu nhiên (trên tất cả các yếu tố, bao gồm cả yếu tố không xác định!) từ out-arraytrở lại vàoin-array

Điều này có đặc tính là nó sẽ "phản ứng" chậm hơn khi n lớn hơn . Ví dụ: nếu bạn muốn có 20% cơ hội, đặt n thành 5 và nhấn 0 là "ít ngẫu nhiên" hơn so với cài đặt n thành 10 và nhấn 0 hoặc 1, và biến 0 thành 199 trên 1000 sẽ gần như không thể phân biệt với sự ngẫu nhiên thực sự trên một mẫu nhỏ. Bạn sẽ phải điều chỉnh n theo kích thước mẫu của bạn.


0

Tính toán trước một đòn chí mạng ngẫu nhiên cho mỗi người chơi.

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

0

Tôi nghĩ có lẽ bạn đang sử dụng chức năng phân phối ngẫu nhiên sai. Bạn có thể không muốn phân phối đồng đều trên các số. Thay vào đó, hãy thử phân phối bình thường để các lượt truy cập quan trọng trở nên không phổ biến hơn các lượt truy cập 'thông thường'.

Tôi làm việc với Java vì vậy tôi không chắc chắn nơi bạn có thể tìm thấy thứ gì đó cho C ++, cung cấp cho bạn các số ngẫu nhiên với phân phối bình thường nhưng phải có một cái gì đó ở ngoài đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.