diff --git a/src/lib/balatro.test.ts b/src/lib/balatro.test.ts index 8df5254..576d176 100644 --- a/src/lib/balatro.test.ts +++ b/src/lib/balatro.test.ts @@ -31,6 +31,7 @@ import case025 from './test-files/025.js' import case026 from './test-files/026.js' import case027 from './test-files/027.js' import case028 from './test-files/028.js' +import case029 from './test-files/029.js' export type TestCase = { message: string @@ -70,6 +71,7 @@ describe('calculateScore', () => { case026('Pair, The Pillar'), case027('Lucky Pair'), case028('Lucky Flush, Bloodstone'), + case029('Lucky Flush, Bloodstone, 4x Oops! All 6s'), ])('$message', ({ initialState, expected }) => { const score = calculateScore(getState(initialState)) diff --git a/src/lib/balatro.ts b/src/lib/balatro.ts index 3dabcf7..8a8abca 100644 --- a/src/lib/balatro.ts +++ b/src/lib/balatro.ts @@ -92,8 +92,18 @@ function getScore (state: State, luck: Luck): Score { break } case 'lucky': { - const hasOops = state.jokerSet.has('Oops! All 6s') - score.multiplier += luck === 'all' ? 20 : luck === 'none' ? 0 : (hasOops ? 8 : 4) + const denominator = 5 + const oopses = state.jokers.filter(({ name }) => name === 'Oops! All 6s') + const minimumNumerator = Math.max(0, Math.min(oopses.length + 1, denominator)) + + let numerator = minimumNumerator + if (luck === 'all') { + numerator = denominator + } else if (luck === 'none' && minimumNumerator < denominator) { + numerator = 0 + } + + score.multiplier += 20 * numerator/denominator log(score, '(+Mult from lucky enhancement)') break } diff --git a/src/lib/data.ts b/src/lib/data.ts index 8b31fe4..649b56f 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -715,8 +715,18 @@ export const JOKER_DEFINITIONS: Record = { rarity: 'uncommon', playedCardEffect ({ score, card, state, luck }) { if (isSuit(card, 'Hearts')) { - const hasOops = state.jokerSet.has('Oops! All 6s') - score.multiplier *= luck === 'all' ? 2 : luck === 'none' ? 1 : 1 + (hasOops ? 2 : 1)/3 + const denominator = 3 + const oopses = state.jokers.filter(({ name }) => name === 'Oops! All 6s') + const minimumNumerator = Math.max(1, Math.min(oopses.length + 1, denominator)) + + let numerator = minimumNumerator + if (luck === 'all') { + numerator = denominator + } else if (luck === 'none' && minimumNumerator < denominator) { + numerator = 0 + } + + score.multiplier *= 1 + numerator/denominator } }, }, diff --git a/src/lib/test-files/029.ts b/src/lib/test-files/029.ts new file mode 100644 index 0000000..9c5e6b1 --- /dev/null +++ b/src/lib/test-files/029.ts @@ -0,0 +1,43 @@ +import type { TestCase } from '#lib/balatro.test.js' + +export default (message: string): TestCase => { + return { + message, + initialState: { + hands: 1, + playedCards: [ + { rank: 'King', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'King', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'Jack', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'Ace', suit: 'Hearts', enhancement: 'lucky' }, + { rank: '6', suit: 'Hearts', enhancement: 'lucky' }, + ], + jokers: [ + { name: 'Sock and Buskin' }, + { name: 'Dusk' }, + { name: 'Lusty Joker' }, + { name: 'Blueprint' }, + { name: 'Bloodstone' }, + { name: 'Oops! All 6s' }, + { name: 'Oops! All 6s' }, + { name: 'Oops! All 6s' }, + { name: 'Oops! All 6s' }, + ], + }, + expected: { + hand: 'Flush', + scoringCards: [ + { rank: 'King', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'King', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'Jack', suit: 'Hearts', enhancement: 'lucky' }, + { rank: 'Ace', suit: 'Hearts', enhancement: 'lucky' }, + { rank: '6', suit: 'Hearts', enhancement: 'lucky' }, + ], + scores: [ + { score: 384131132448, formattedScore: '384,131,132,448', luck: 'none' }, + { score: 384131132448, formattedScore: '384,131,132,448', luck: 'average' }, + { score: 384131132448, formattedScore: '384,131,132,448', luck: 'all' }, + ], + }, + } +}