Написание «Счастливых семерок», что не так? - PullRequest
0 голосов
/ 13 января 2020

Я пишу Lucky Sevens и получаю в основном ожидаемые результаты, основанные на том, как игры в кости работают на IRL. Но время от времени я получаю безумный результат.

В частности, я получаю ситуацию, в которой у меня будет go до 100+ долларов, с сотнями общих бросков, но он говорит мне, что броски на моем moneyMax равны 2 или что-то такое невозможное.

Это малая вероятность генераторов случайных чисел или у меня что-то не так?

Вот Js:

    function rollDice() {
      return Math.floor(Math.random() * 6) + 1;
    }

    function playGame() {
      var startingBet = document.forms["luckySevens"]["startingBet"].value;
      var gameMoney = startingBet;
      var die1;
      var die2;
      var diceSum;
      var rollsNumber = 0;
      var moneyMax = 0;
      var rollsAtMax = 0;

      if (startingBet <= 0) {
      alert("Starting bet must be greater than zero!");
      return false;
      } //end of alert if loop

      while (gameMoney > 0) {
       die1 = rollDice();
       die2 = rollDice();
       diceSum = die1 + die2;
       rollsNumber++;
       if (diceSum != 7) {
        gameMoney = gameMoney - 1;
       } else {
        if (diceSum == 7) {
         gameMoney = gameMoney + 4;
         if (gameMoney > moneyMax) {
           moneyMax = gameMoney;
          rollsAtMax = rollsNumber;
          }
         }
        }
       }
       document.getElementById("results").style.display = "block";
       document.getElementById("playButton").innerText = "Play Again!";
       document.getElementById("betStart").innerText = startingBet;
       document.getElementById("rollsNumber").innerText = rollsNumber;
       document.getElementById("moneyMax").innerText = moneyMax;
       document.getElementById("rollsAtMax").innerText = rollsAtMax;
       return false;
       }//end of playGame()

1 Ответ

0 голосов
/ 13 января 2020

Если вы сомневаетесь в случайности Math.random()?
Альтернатива для Math.random была задана ранее на SO. Например, здесь

Но вы также можете просто удвоить рандомизацию, чтобы сделать ее еще более случайной.

Например:

function rollDice() {
    return (Math.floor(Math.pow(10,14)*Math.random()*Math.random())%6)+1;
}

function rollDices(rolls){
  	let roll = 0;
  	let eyes = 0;
  	let dice = 0;
  	let interval = 0;
  	eyesCount = {1:0, 2:0, 3: 0, 4:0, 5:0, 6:0}	
  	while (roll < rolls){
  		roll++;
  		eyes = rollDice();
  		eyesCount[eyes]++;
  	}
  	return {rolls: roll, eyesCount : eyesCount}
  }
  
console.log(rollDices(1000000));

И посмотрите на результаты этого фрагмента.
Он рассчитывает самый длинный интервал, в течение которого одни и те же глаза бросаются за 2 кубика.

function rollDice() {
    return (Math.floor(Math.pow(10,14)*Math.random()*Math.random())%6)+1;
}

function rollOdds(rolls){
  	let roll = 0;
  	let eyes = 0;
  	let dice1 = 0;
  	let dice2 = 0;
  	let interval = 0;
  	eyesCount = {2:0, 3: 0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0}
  	eyesPrevRoll = {2:0, 3: 0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0}
  	eyesMaxInterval = {2:0, 3: 0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0, 11:0, 12:0}
  	
  	while (roll < rolls){
  		roll++;
  		dice1 = rollDice();
  		dice2 = rollDice();
  		eyes = dice1 + dice2;
  		eyesCount[eyes]++;
  		interval = roll - eyesPrevRoll[eyes];
  		if(interval > eyesMaxInterval[eyes]){
  			eyesMaxInterval[eyes] = interval;
  		}
  		eyesPrevRoll[eyes] = roll;
  	}
  	return {rolls: roll, eyesCount : eyesCount, eyesMaxInterval: eyesMaxInterval}
  }
  
console.log(rollOdds(100000))

Это показывает, что может случиться так, что семерка не выпадет в течение 50+ бросков.

Но, тем не менее, максимальная сумма 2 со стартовым счетом 100 будет означать, что семерка не выпала 98 раз.
Так что да, это заставляет задуматься об истинной случайности Math.random() ,

Тестовый фрагмент на основе вашего кода:

function rollDice() {
    return (Math.floor(Math.pow(10,14)*Math.random()*Math.random())%6)+1;
}

function playGame(startingBet) {
      
      let gameMoney = startingBet;
      let die1;
      let die2;
      let diceSum;
      let rollsNumber = 0;
      let moneyMax = 0;
      let rollsAtMax = 0;
      let moneyAt7 = 4;
      let roll = 0;
      let rollLimit = startingBet * 10;

      while (gameMoney > 0 && roll < rollLimit) {
       roll++;
       die1 = rollDice();
       die2 = rollDice();
       diceSum = die1 + die2;
       rollsNumber++;
       if (diceSum !== 7) {
        gameMoney = gameMoney - 1;
       } else {
        if (diceSum === 7) {
        	
         gameMoney = gameMoney + moneyAt7;
         
         if (gameMoney > moneyMax) {
           moneyMax = gameMoney;
          rollsAtMax = rollsNumber;
          }
         }
        }
       }
    return { 
      startingBet : startingBet,
      gameMoney : gameMoney,
      moneyMax : moneyMax,
      rollsNumber : rollsNumber,
      rollsAtMax : rollsAtMax
    }; 
  
}

// TEST 
console.log(playGame(10000));

Замечание: интересно отметить, что при вознаграждении 4 за семь максимальная сумма часто достигается при 100 бросках.

Чтобы быть более справедливым, выигрыш за семь должен как минимум в 5 раз превышать сумму проигрыша.

Что означает, что нужно выйти из этой игры, когда впереди. Потому что может только хуже.

...