[英]Where am I losing randomness?
因此,我正在構建一個石頭,紙,剪刀的游戲。 我想獲得math.random()來給我一個隨機的結果,並將其與用戶選擇的結果進行比較。
它主要工作。 我什至以為它可以完全工作一段時間,但是在某些時候我正在失去隨機性。
為了進行嘗試,我輸入了一個固定的“用戶”選項,並使用setInterval(myfunction,20)將代碼運行了數百次。 他們總是取得不平衡的勝利,並且總是有相同的結果:
如果我使用playerPick = 1來運行它,則計算機將始終獲勝。
如果我使用playerPick = 2或3運行它,則用戶總是獲勝。
誰能看到我發呆的地方?
//Global variable and constants.
const ROCK = 1;
const PAPER = 2;
const SCISSORS = 3;
//This is the game.
function whoWins(){
const playerPick = 2; //for debugging, it can be 1, 2, or 3.
const computer = computerPick();
if (playerPick == computer){
return draw();
} else if (playerPick == 1 && computer == 2){
return lose();
} else if (playerPick == 2 && computer == 3){
return lose();
} else if (playerPick == 3 && computer == 1){
return lose();
} else {
return win();
}
}
//These are the inputs for the game.
rockButton.addEventListener('click', () => {
playerPick = ROCK;
return whoWins()});
paperButton.addEventListener('click', () => {
playerPick = PAPER;
return whoWins()});
scissorsButton.addEventListener('click', () => {
playerPick = SCISSORS;
return whoWins()});
function computerPick() {
let computerChoice = '';
const getRandom = Math.random;
if (getRandom() >= 2/3) {
computerChoice = ROCK;
} else if (getRandom() >= 1/3){
computerChoice = PAPER;
} else {
computerChoice = SCISSORS;
}
return computerChoice;
}
我對這一切都很陌生,但這仍然不是隨機的。
正如應該在一次調用Math.random的注釋中所提到的那樣,這應該是一個簡單的解決方法,否則概率會發生偏差。
我認為,使用原始代碼,PAPER的概率應為0.66 * 0.66 =〜44%,SCISSORS的概率將為0.66 * 0.33 =〜22%。 新功能應解決此問題。
const ROCK = 1; const PAPER = 2; const SCISSORS = 3; // Original computerPick function function computerPickOriginal() { let computerChoice = ''; const getRandom = Math.random; if (getRandom() >= 2/3) { computerChoice = ROCK; } else if (getRandom() >= 1/3){ computerChoice = PAPER; } else { computerChoice = SCISSORS; } return computerChoice; } // Fixed computerPick function. function computerPick() { let computerChoice = ''; const choice = Math.random(); if (choice >= 2/3) { computerChoice = ROCK; } else if (choice >= 1/3){ computerChoice = PAPER; } else { computerChoice = SCISSORS; } return computerChoice; } function decodeChoice(choice) { if (choice == ROCK) return "Rock"; if (choice == PAPER) return "Paper"; if (choice == SCISSORS) return "Scissors"; } // Check the distribution of each version of the code. console.log("Checking distributions (10000 picks).."); let original_counts = {}; let counts = {}; for(let i = 0; i < 10000; i++) { let k = computerPick(); counts[k] = (counts[k] || 0) + 1; let k2 = computerPickOriginal(); original_counts[k2] = (original_counts[k2] || 0) + 1; } console.log('Computer Pick Distribution (original): ', Object.entries(original_counts).map(([key,value]) => `${decodeChoice(key)}: ${value}`)); console.log('Computer Pick Distribution (fixed): ', Object.entries(counts).map(([key,value]) => `${decodeChoice(key)}: ${value}`));
為了將來參考,您可能會發現使用數組更容易。
const getRandomChoice = () => { const options = ['Rock', 'Paper', 'Scissors']; const randomIndex = Math.floor(Math.random() * options.length); const choice = options[randomIndex]; return choice; } const counts = {}; for(let i = 0; i < 10000; i++) { let p = getRandomChoice(); counts[p] = (counts[p] || 0) + 1; } console.log(counts);
通過將Math.random
的結果乘以數組的長度(3),我們可以得到一個介於[0,3)之間的值(不包括3)。 然后,我們調用Math.floor
來“截斷”所有小數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.