Last active
June 17, 2017 11:43
-
-
Save Restuta/4c4ddb525898a6534db7d913e535460b to your computer and use it in GitHub Desktop.
Gamblers Fallacy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Models flip-a-coin game with variative chance of "heads" and "tails". Chance depends on betWinPayoutRatio. | |
For 2 it's 50% like you wold expect and for 10 it's 1/10th | |
Once you copy paste this code to Chrome's console, run | |
main({ | |
gamesToPlay: 100, | |
timesToPlayEachGame: 1000000, | |
chainLenghtToWaitFor: 5, | |
betWinPayoutRatio: 10, | |
}) | |
and tweak self-explanatory parametrs | |
The most interesting one is "chainLenghtToWaitFor" which represents how long a player should wait for a give number of tails in a row | |
before placing a bet to heads. For 5 a player would wait for 5 tails in a row and only then place a bet on heads. | |
starting money for each player is 1000 | |
each bet is equal to 1 | |
I CHALLANGE YOU to find parameters where avgMoneyLeft doubles =) | |
*/ | |
function main({ | |
gamesToPlay = 10, | |
timesToPlayEachGame = 10, | |
chainLenghtToWaitFor = 5, | |
betWinPayoutRatio = 2 | |
}) { | |
console.clear() | |
const log = console.log | |
log(...arguments) | |
function rnd(min, max) { | |
min = Math.ceil(min); | |
max = Math.floor(max); | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
// const flipCoin = () => (Math.random() >= 0.5 ? 'heads' : 'tails') | |
const flipCoin = () => (rnd(1, betWinPayoutRatio) === 1 ? 'tails' : 'heads') | |
const winningBet = coinSide => (coinSide === 'tails') | |
class Player { | |
constructor({startingMoney, winGoal}) { | |
this.money = startingMoney | |
this.betsPlaced = 0 | |
this.betPlaced = false | |
this.betAmount = 0 | |
this.winGoalAchived = false | |
} | |
placeBet(betAmount) { | |
const remainingMoney = this.money - betAmount | |
this.betPlaced = true | |
this.betsPlaced++ | |
this.betAmount = betAmount | |
this.money -= betAmount | |
} | |
collectWinnings({payoutRatio}) { | |
this.money += (this.betAmount * payoutRatio) | |
this.betPlaced = false | |
this.betAmount = 0 | |
if (this.money >= this.winGoal) { | |
this.winGoalAchieved = true | |
log(`Win goal achieved, player's balance: ${this.money}`) | |
} | |
} | |
feelDisappointed() { | |
this.betPlaced = false | |
this.betAmount = 0 | |
} | |
} | |
function playAGame({sameSideChainLength = 5, timesToPlay = 1000}) { | |
let headsInARow = 0 | |
let previousFlipWasHeads = false | |
const player = new Player({startingMoney: 1000, winGoal: 2000}) | |
for(let i = 0; i < timesToPlay; i++) { | |
let coinSide = flipCoin() | |
if (player.betPlaced) { | |
if (winningBet(coinSide)) { | |
player.collectWinnings({payoutRatio: betWinPayoutRatio}) | |
// log('collected winnings') | |
} else { | |
player.feelDisappointed() | |
} | |
} | |
if (coinSide === 'heads') { | |
if (previousFlipWasHeads) { | |
headsInARow++ | |
} else { | |
headsInARow = 1 | |
} | |
previousFlipWasHeads = true | |
} else { | |
previousFlipWasHeads = false | |
headsInARow = 0 | |
} | |
if (headsInARow === sameSideChainLength) { | |
player.placeBet(1) | |
} | |
} | |
// log(player.money) | |
// log(`Bets placed: ${player.betsPlaced}`) | |
return { | |
moneyLeft: player.money, | |
betsPlaced: player.betsPlaced | |
} | |
} | |
const game = () => playAGame({sameSideChainLength: chainLenghtToWaitFor, timesToPlay: timesToPlayEachGame}) | |
const playGameNTimes = (game, times) => { | |
let results = [] | |
for (let i = 0; i < times; i++) { | |
results.push(game()) | |
} | |
return results | |
} | |
const gamesResults = playGameNTimes(game, gamesToPlay) | |
const stats = gamesResults | |
.reduce((a, b) => { | |
a.moneyLeft += b.moneyLeft | |
a.betsPlaced += b.betsPlaced | |
return a | |
}, {moneyLeft: 0, betsPlaced: 0}) | |
log('--- last N games results ---') | |
gamesResults.slice(gamesToPlay - 10).map(x => { | |
log(x) | |
return x | |
}) | |
log('Total bankrupt players: ') | |
log(gamesResults.filter(x => x.moneyLeft < 0).length) | |
console.info({ | |
avgMoneyLeft: stats.moneyLeft / gamesToPlay, | |
avgBetsPlaced: stats.betsPlaced / gamesToPlay | |
}) | |
//1234 | |
} | |
main({ | |
gamesToPlay: 100, | |
timesToPlayEachGame: 1000000, | |
chainLenghtToWaitFor: 5, | |
betWinPayoutRatio: 10, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment