Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ const rules = {
}
```

## betting strategies

Several betting strategies are included:

* `minPassLineOnly` – always keep the table minimum on the pass line
* `minPassLineMidOdds` – take about half of the allowed odds when a point is set
* `minPassLineMaxOdds` – always take the maximum odds allowed

## what? why?

I like to play craps sometimes. I have a handful of strategies I like to play. It is time consuming to play in an app. I'd like to play 5, 50, 500 hands very fast using various strategies. Which strategies are best is well understood, the variability comes in with how aggressive your strategies are and the level of risk you assume at any given moment. And of course the dice outcomes and their deviation from long term probabilities and how they interact with the strategies you employ is the fun part. This simulator lets me scratch my craps itch very quickly.
Expand Down
22 changes: 21 additions & 1 deletion betting.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,27 @@ function minPassLineMaxOdds (opts) {
return bets
}

function minPassLineMidOdds (opts) {
const bets = minPassLineOnly(opts)
const { rules, hand } = opts

if (process.env.DEBUG) console.log(`[decision] make a new pass odds bet?: ${!hand.isComeOut} && ${!bets?.pass?.odds}`)

if (hand.isComeOut === false && !bets?.pass?.odds) {
const maxMultiple = rules.maxOddsMultiple[hand.point]
const oddsMultiple = Math.ceil(maxMultiple / 2)
const oddsAmount = oddsMultiple * bets.pass.line.amount
bets.pass.odds = {
amount: oddsAmount
}
bets.new += oddsAmount
}

return bets
}

module.exports = {
minPassLineOnly,
minPassLineMaxOdds
minPassLineMaxOdds,
minPassLineMidOdds
}
78 changes: 78 additions & 0 deletions betting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,81 @@ tap.test('minPassLineMaxOdds: continue existing bet', (t) => {

t.end()
})

tap.test('minPassLineMidOdds: make new bet upon establishing point', (t) => {
const rules = {
minBet: 5,
maxOddsMultiple: {
4: 3,
5: 4,
6: 5,
8: 5,
9: 4,
10: 3
}
}

const hand = {
isComeOut: false,
result: 'point set',
point: 5
}

const bets = {
pass: {
line: {
amount: 5,
isContract: true
}
}
}

const expected = Math.ceil(rules.maxOddsMultiple['5'] / 2) * rules.minBet
const updatedBets = lib.minPassLineMidOdds({ rules, bets, hand })
t.equal(updatedBets.pass.line.amount, rules.minBet, 'line bet is not changed')
t.equal(updatedBets.pass.odds.amount, expected, 'odds bet made properly')
t.equal(updatedBets.new, updatedBets.pass.odds.amount)

t.end()
})

tap.test('minPassLineMidOdds: continue existing bet', (t) => {
const rules = {
minBet: 5,
maxOddsMultiple: {
4: 3,
5: 4,
6: 5,
8: 5,
9: 4,
10: 3
}
}

const hand = {
isComeOut: false,
result: 'neutral',
point: 5,
diceSum: 8
}

const bets = {
pass: {
line: {
amount: 5,
isContract: true
},
odds: {
amount: Math.ceil(rules.maxOddsMultiple['5'] / 2) * 5,
isContract: false
}
}
}

const updatedBets = lib.minPassLineMidOdds({ rules, bets, hand })
t.equal(updatedBets.pass.line.amount, bets.pass.line.amount, 'line bet is not changed')
t.equal(updatedBets.pass.odds.amount, bets.pass.odds.amount, 'odds bet is not changed')
t.notOk(updatedBets.new, 'no new bets were made')

t.end()
})
43 changes: 43 additions & 0 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,46 @@ tap.test('integration: minPassLineMaxOdds, one hand with everything', (suite) =>

suite.end()
})

tap.test('integration: minPassLineMidOdds, one hand with everything', (suite) => {
let rollCount = -1
const fixedRolls = [
4, 3, // comeout win
5, 6, // comeout win
1, 1, // comeout loss
1, 2, // comeout loss
6, 6, // comeout loss
3, 3, // point set
4, 1, // neutral
2, 4, // point win
4, 4, // point set
3, 4 // seven out
]

function testRoll () {
rollCount++
if (!fixedRolls[rollCount]) {
console.log('falsy return from fixed dice')
process.exit(1)
}
return fixedRolls[rollCount]
}

const rules = {
minBet: 5,
maxOddsMultiple: {
4: 3,
5: 4,
6: 5,
8: 5,
9: 4,
10: 3
}
}

const hand = lib.playHand({ rules, roll: testRoll, bettingStrategy: betting.minPassLineMidOdds })
suite.ok(Array.isArray(hand.history))
suite.ok(typeof hand.balance === 'number')

suite.end()
})