shufflecom-calculations 2.2.25 → 2.2.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/games/blackjack.d.ts +6 -0
- package/lib/games/blackjack.js +16 -4
- package/lib/games/blackjack.js.map +1 -1
- package/lib/games/keno.d.ts +1 -0
- package/lib/games/keno.js +10 -6
- package/lib/games/keno.js.map +1 -1
- package/lib/games/plinko.d.ts +1 -0
- package/lib/games/plinko.js +14 -21
- package/lib/games/plinko.js.map +1 -1
- package/lib/games/roulette.d.ts +2 -1
- package/lib/games/roulette.js +15 -11
- package/lib/games/roulette.js.map +1 -1
- package/lib/games/wheel.d.ts +1 -0
- package/lib/games/wheel.js +19 -9
- package/lib/games/wheel.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/sports-name.js +20 -10
- package/lib/utils/sports-name.js.map +1 -1
- package/package.json +2 -2
- package/src/games/blackjack.ts +51 -8
- package/src/games/keno.ts +12 -6
- package/src/games/plinko.ts +18 -24
- package/src/games/roulette.ts +36 -13
- package/src/games/wheel.ts +20 -9
- package/src/utils/sports-name.spec.ts +27 -1
- package/src/utils/sports-name.ts +26 -16
package/lib/utils/sports-name.js
CHANGED
|
@@ -10,6 +10,9 @@ const sports_types_1 = require("./sports.types");
|
|
|
10
10
|
exports.HOME_PLACEHOLDERS = ['Home Team', 'Home', 'Competitor A'];
|
|
11
11
|
exports.AWAY_PLACEHOLDERS = ['Away Team', 'Away', 'Competitor B'];
|
|
12
12
|
const SCORE_NAME_REGEX = /^\b(\d+)[:-](\d+)\b$/;
|
|
13
|
+
const LINE_VALUE_WITH_BRACKET_REGEX = (lineValue) => new RegExp(`\\([+-]?${lineValue.replace(/[-+]/g, '')}(\\.0+)?\\)$`, 'g');
|
|
14
|
+
const LINE_VALUE_WITHOUT_BRACKET_REGEX = (lineValue) => new RegExp(`(\\b|[+-])${lineValue.replace(/[-+]/g, '')}(\\.0+)?$`, 'g');
|
|
15
|
+
const ZERO_LINE_VALUE_WITH_BRACKET_REGEX = LINE_VALUE_WITH_BRACKET_REGEX('0');
|
|
13
16
|
function formatOddinDoubleChanceName({ displayName, englishName, homeDisplayName, awayDisplayName, provider, }) {
|
|
14
17
|
if (provider === sports_types_1.SportsMarketProvider.ODDIN) {
|
|
15
18
|
const mappings = {
|
|
@@ -79,20 +82,27 @@ function formatGeniusCompetitorPlaceholderName({ displayName, homeDisplayName, a
|
|
|
79
82
|
}
|
|
80
83
|
function formatLineValueName({ displayName, lineValue, isHome, marketDisplayType, provider, }) {
|
|
81
84
|
let formattedName = displayName;
|
|
82
|
-
if (lineValue !== null
|
|
85
|
+
if (lineValue !== null) {
|
|
83
86
|
const number = (0, bignumber_js_1.default)(lineValue);
|
|
84
87
|
if (!number.isNaN()) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
if (provider === sports_types_1.SportsMarketProvider.BETRADAR) {
|
|
89
|
+
if (number.isZero()) {
|
|
90
|
+
formattedName = formattedName.replace(ZERO_LINE_VALUE_WITH_BRACKET_REGEX, '(0.0)');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
formattedName = formattedName.replace(LINE_VALUE_WITH_BRACKET_REGEX(lineValue), '');
|
|
95
|
+
formattedName = formattedName.replace(LINE_VALUE_WITHOUT_BRACKET_REGEX(lineValue), '');
|
|
96
|
+
formattedName = formattedName.trim();
|
|
97
|
+
if (marketDisplayType !== sports_types_1.SportsMarketDisplayType.MAP_NTH_KILLS) {
|
|
98
|
+
formattedName += ' ';
|
|
99
|
+
if (marketDisplayType === sports_types_1.SportsMarketDisplayType.HANDICAP_VALUE) {
|
|
100
|
+
if (!number.isZero()) {
|
|
101
|
+
formattedName += isHome !== number.isPositive() ? '+' : '-';
|
|
102
|
+
}
|
|
93
103
|
}
|
|
104
|
+
formattedName += number.abs().toFixed(number.dp() || 1);
|
|
94
105
|
}
|
|
95
|
-
formattedName += number.abs().toFixed(number.dp() || 1);
|
|
96
106
|
}
|
|
97
107
|
}
|
|
98
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sports-name.js","sourceRoot":"","sources":["../../src/utils/sports-name.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAqC;AACrC,mCAAoC;AACpC,iDAA+E;AAElE,QAAA,iBAAiB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAC1D,QAAA,iBAAiB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAEvE,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"sports-name.js","sourceRoot":"","sources":["../../src/utils/sports-name.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shufflecom-calculations",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.27",
|
|
4
4
|
"description": "",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
},
|
|
15
15
|
"author": "",
|
|
16
16
|
"license": "ISC",
|
|
17
|
-
"gitHead": "
|
|
17
|
+
"gitHead": "079de9596de541a9ae3fb20362f72fbd508ec245"
|
|
18
18
|
}
|
package/src/games/blackjack.ts
CHANGED
|
@@ -156,7 +156,11 @@ export class Blackjack {
|
|
|
156
156
|
return true;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
static getHandOutcome(
|
|
159
|
+
static getHandOutcome(
|
|
160
|
+
dealerCards: readonly number[],
|
|
161
|
+
playerCards: readonly number[],
|
|
162
|
+
hasSplit: boolean,
|
|
163
|
+
): { multiplier: BigNumber; outcome: HandOutcome } {
|
|
160
164
|
const dealerBlackjack = this.isBlackjack(dealerCards);
|
|
161
165
|
const playerBlackjack = this.isBlackjack(playerCards);
|
|
162
166
|
|
|
@@ -194,7 +198,10 @@ export class Blackjack {
|
|
|
194
198
|
}
|
|
195
199
|
}
|
|
196
200
|
|
|
197
|
-
static calcSideBetWins(
|
|
201
|
+
static calcSideBetWins(
|
|
202
|
+
dealerUpCard: number,
|
|
203
|
+
playerCards: readonly number[],
|
|
204
|
+
): { perfectPair?: PerfectPairType; twentyOnePlusThree?: TwentyOnePlusThreeType } {
|
|
198
205
|
const results: { perfectPair?: PerfectPairType; twentyOnePlusThree?: TwentyOnePlusThreeType } = {};
|
|
199
206
|
const dealerCardDetails = CardGames.getCardDetails(dealerUpCard);
|
|
200
207
|
const playerCard0 = CardGames.getCardDetails(playerCards[0]);
|
|
@@ -230,7 +237,9 @@ export class Blackjack {
|
|
|
230
237
|
A: [14, 1],
|
|
231
238
|
};
|
|
232
239
|
|
|
233
|
-
const cardValues = [...cardValueMap[playerCard0.value], ...cardValueMap[playerCard1.value], ...cardValueMap[dealerCardDetails.value]].sort(
|
|
240
|
+
const cardValues = [...cardValueMap[playerCard0.value], ...cardValueMap[playerCard1.value], ...cardValueMap[dealerCardDetails.value]].sort(
|
|
241
|
+
(a, b) => a - b,
|
|
242
|
+
);
|
|
234
243
|
|
|
235
244
|
const isFlush = dealerCardDetails.suit === playerCard0.suit && playerCard0.suit === playerCard1.suit;
|
|
236
245
|
const firstThreeCards = cardValues.slice(0, 3) as [number, number, number];
|
|
@@ -275,7 +284,7 @@ export class Blackjack {
|
|
|
275
284
|
K: 10,
|
|
276
285
|
};
|
|
277
286
|
|
|
278
|
-
let aceCount = CardGames.getCardDetailsArr(cards).filter(
|
|
287
|
+
let aceCount = CardGames.getCardDetailsArr(cards).filter(card => card.value === 'A').length;
|
|
279
288
|
let cardSum = CardGames.getCardDetailsArr(cards).reduce((acc, cur) => acc + cardValueMap[cur.value], 0);
|
|
280
289
|
|
|
281
290
|
if (aceCount === 0) {
|
|
@@ -340,12 +349,36 @@ export class Blackjack {
|
|
|
340
349
|
return newDealerHand;
|
|
341
350
|
}
|
|
342
351
|
|
|
352
|
+
static getMaxPotentialPayout({
|
|
353
|
+
mainBetAmount,
|
|
354
|
+
twentyOnePlusThreeAmount,
|
|
355
|
+
perfectPairAmount,
|
|
356
|
+
}: {
|
|
357
|
+
mainBetAmount: BigNumber;
|
|
358
|
+
twentyOnePlusThreeAmount: BigNumber;
|
|
359
|
+
perfectPairAmount: BigNumber;
|
|
360
|
+
mainHandDoubleDown?: boolean;
|
|
361
|
+
}) {
|
|
362
|
+
const mainHandPayout = mainBetAmount.times(2.5);
|
|
363
|
+
|
|
364
|
+
const twentyOnePlusThreeMaxPayout = BigNumber.max(...Object.values(twentyOnePlusThreePayout)).times(twentyOnePlusThreeAmount);
|
|
365
|
+
|
|
366
|
+
const perfectPairMaxPayout = BigNumber.max(...Object.values(perfectPairPayout)).times(perfectPairAmount);
|
|
367
|
+
|
|
368
|
+
return mainHandPayout.plus(twentyOnePlusThreeMaxPayout).plus(perfectPairMaxPayout);
|
|
369
|
+
}
|
|
370
|
+
|
|
343
371
|
/**
|
|
344
372
|
*
|
|
345
373
|
* Called after bet ends. Players can still win insurance or sidebets even if they lose the main bet
|
|
346
374
|
* @returns total payout amount
|
|
347
375
|
*/
|
|
348
|
-
static getGameOutcome(data: SettleBetVars): {
|
|
376
|
+
static getGameOutcome(data: SettleBetVars): {
|
|
377
|
+
payout: BigNumber;
|
|
378
|
+
multiplier: BigNumber;
|
|
379
|
+
mainHandOutcome: HandOutcome;
|
|
380
|
+
splitHandOutcome: HandOutcome;
|
|
381
|
+
} {
|
|
349
382
|
if (data.dealerHand.length < 2) {
|
|
350
383
|
throw new Error('Dealer hole card is missing');
|
|
351
384
|
}
|
|
@@ -360,9 +393,15 @@ export class Blackjack {
|
|
|
360
393
|
let perfectPairPayoutAmt = new BigNumber(0);
|
|
361
394
|
let twentyOnePlusThreePayoutAmt = new BigNumber(0);
|
|
362
395
|
|
|
363
|
-
const {
|
|
396
|
+
const {
|
|
397
|
+
mainHandOutcome,
|
|
398
|
+
payout: mainBetPayout,
|
|
399
|
+
splitHandOutcome,
|
|
400
|
+
} = Blackjack.getMainBetPayout({ ...data, mainHandBetAmount, splitHandBetAmount });
|
|
364
401
|
|
|
365
|
-
const playerHand: [number, number] = data.hasSplit
|
|
402
|
+
const playerHand: [number, number] = data.hasSplit
|
|
403
|
+
? [data.mainPlayerHand[0], data.splitPlayerHand[0]]
|
|
404
|
+
: [data.mainPlayerHand[0], data.mainPlayerHand[1]];
|
|
366
405
|
|
|
367
406
|
const { perfectPair, twentyOnePlusThree } = Blackjack.calcSideBetWins(data.dealerHand[0], playerHand);
|
|
368
407
|
|
|
@@ -376,7 +415,11 @@ export class Blackjack {
|
|
|
376
415
|
|
|
377
416
|
const payout = mainBetPayout.plus(perfectPairPayoutAmt).plus(twentyOnePlusThreePayoutAmt);
|
|
378
417
|
const insuranceCost = data.boughtInsurance ? data.mainBetAmount.dividedBy(2) : new BigNumber(0); // insurance costs half of the main bet
|
|
379
|
-
const totalBetAmount = mainHandBetAmount
|
|
418
|
+
const totalBetAmount = mainHandBetAmount
|
|
419
|
+
.plus(splitHandBetAmount)
|
|
420
|
+
.plus(data.perfectPairAmount)
|
|
421
|
+
.plus(data.twentyOnePlusThreeAmount)
|
|
422
|
+
.plus(insuranceCost);
|
|
380
423
|
|
|
381
424
|
let multiplier = payout.dividedBy(totalBetAmount);
|
|
382
425
|
|
package/src/games/keno.ts
CHANGED
|
@@ -127,6 +127,16 @@ export class Keno {
|
|
|
127
127
|
return new BigNumber(config.payout[risk][matchedTiles.length] ?? 0);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
static getMaxMultiplier(risk: KenoRiskLevel, selectedTiles: number[]) {
|
|
131
|
+
const config = this.configs().find(config => config.tiles === selectedTiles.length);
|
|
132
|
+
|
|
133
|
+
if (!config) {
|
|
134
|
+
throw new Error(`No configuration found for ${selectedTiles.length} tiles`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return new BigNumber(config.payout[risk][selectedTiles.length] ?? 0);
|
|
138
|
+
}
|
|
139
|
+
|
|
130
140
|
static getResults(hexStr: string[], rows: number): number[] {
|
|
131
141
|
const results: number[] = [];
|
|
132
142
|
const grids = Array.from(Array(TOTAL_TILES.toNumber()).keys());
|
|
@@ -143,9 +153,7 @@ export class Keno {
|
|
|
143
153
|
position = position.plus(new BigNumber(value).dividedBy(BYTE_TOTAL.pow(j + 1)));
|
|
144
154
|
}
|
|
145
155
|
|
|
146
|
-
position = position
|
|
147
|
-
.multipliedBy(TOTAL_TILES.minus(new BigNumber(8 * counter + i)))
|
|
148
|
-
.integerValue(BigNumber.ROUND_DOWN);
|
|
156
|
+
position = position.multipliedBy(TOTAL_TILES.minus(new BigNumber(8 * counter + i))).integerValue(BigNumber.ROUND_DOWN);
|
|
149
157
|
|
|
150
158
|
results.push(grids.splice(position.toNumber(), 1)[0] + 1); // (0 to 39) + 1 = 1 + 40
|
|
151
159
|
}
|
|
@@ -155,8 +163,6 @@ export class Keno {
|
|
|
155
163
|
}
|
|
156
164
|
|
|
157
165
|
static getChance({ correctPicks, picked }: { correctPicks: number; picked: number }) {
|
|
158
|
-
return new BigNumber(nCr(10, correctPicks))
|
|
159
|
-
.multipliedBy(nCr(30, picked - correctPicks))
|
|
160
|
-
.dividedBy(new BigNumber(nCr(40, picked)));
|
|
166
|
+
return new BigNumber(nCr(10, correctPicks)).multipliedBy(nCr(30, picked - correctPicks)).dividedBy(new BigNumber(nCr(40, picked)));
|
|
161
167
|
}
|
|
162
168
|
}
|
package/src/games/plinko.ts
CHANGED
|
@@ -67,39 +67,25 @@ const plinkoConfigs: PlinkConfig[] = [
|
|
|
67
67
|
{
|
|
68
68
|
rows: 14,
|
|
69
69
|
payout: {
|
|
70
|
-
[PlinkoRiskLevel.LOW_RISK]: [
|
|
71
|
-
7.1, 4, 1.9, 1.4, 1.3, 1.1, 1, 0.5, 1, 1.1, 1.3, 1.4, 1.9, 4, 7.1,
|
|
72
|
-
],
|
|
70
|
+
[PlinkoRiskLevel.LOW_RISK]: [7.1, 4, 1.9, 1.4, 1.3, 1.1, 1, 0.5, 1, 1.1, 1.3, 1.4, 1.9, 4, 7.1],
|
|
73
71
|
[PlinkoRiskLevel.MEDIUM_RISK]: [58, 15, 7, 4, 1.9, 1, 0.5, 0.2, 0.5, 1, 1.9, 4, 7, 15, 58],
|
|
74
|
-
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
75
|
-
420, 56, 18, 5, 1.9, 0.3, 0.2, 0.2, 0.2, 0.3, 1.9, 5, 18, 56, 420,
|
|
76
|
-
],
|
|
72
|
+
[PlinkoRiskLevel.HIGH_RISK]: [420, 56, 18, 5, 1.9, 0.3, 0.2, 0.2, 0.2, 0.3, 1.9, 5, 18, 56, 420],
|
|
77
73
|
},
|
|
78
74
|
},
|
|
79
75
|
{
|
|
80
76
|
rows: 15,
|
|
81
77
|
payout: {
|
|
82
78
|
[PlinkoRiskLevel.LOW_RISK]: [15, 8, 3, 2, 1.5, 1.1, 1, 0.7, 0.7, 1, 1.1, 1.5, 2, 3, 8, 15],
|
|
83
|
-
[PlinkoRiskLevel.MEDIUM_RISK]: [
|
|
84
|
-
|
|
85
|
-
],
|
|
86
|
-
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
87
|
-
620, 83, 27, 8, 3, 0.5, 0.2, 0.2, 0.2, 0.2, 0.5, 3, 8, 27, 83, 620,
|
|
88
|
-
],
|
|
79
|
+
[PlinkoRiskLevel.MEDIUM_RISK]: [88, 18, 11, 5, 3, 1.3, 0.5, 0.3, 0.3, 0.5, 1.3, 3, 5, 11, 18, 88],
|
|
80
|
+
[PlinkoRiskLevel.HIGH_RISK]: [620, 83, 27, 8, 3, 0.5, 0.2, 0.2, 0.2, 0.2, 0.5, 3, 8, 27, 83, 620],
|
|
89
81
|
},
|
|
90
82
|
},
|
|
91
83
|
{
|
|
92
84
|
rows: 16,
|
|
93
85
|
payout: {
|
|
94
|
-
[PlinkoRiskLevel.LOW_RISK]: [
|
|
95
|
-
|
|
96
|
-
],
|
|
97
|
-
[PlinkoRiskLevel.MEDIUM_RISK]: [
|
|
98
|
-
110, 41, 10, 5, 3, 1.5, 1, 0.5, 0.3, 0.5, 1, 1.5, 3, 5, 10, 41, 110,
|
|
99
|
-
],
|
|
100
|
-
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
101
|
-
1000, 130, 26, 9, 4, 2, 0.2, 0.2, 0.2, 0.2, 0.2, 2, 4, 9, 26, 130, 1000,
|
|
102
|
-
],
|
|
86
|
+
[PlinkoRiskLevel.LOW_RISK]: [16, 9, 2, 1.4, 1.4, 1.2, 1.1, 1, 0.5, 1, 1.1, 1.2, 1.4, 1.4, 2, 9, 16],
|
|
87
|
+
[PlinkoRiskLevel.MEDIUM_RISK]: [110, 41, 10, 5, 3, 1.5, 1, 0.5, 0.3, 0.5, 1, 1.5, 3, 5, 10, 41, 110],
|
|
88
|
+
[PlinkoRiskLevel.HIGH_RISK]: [1000, 130, 26, 9, 4, 2, 0.2, 0.2, 0.2, 0.2, 0.2, 2, 4, 9, 26, 130, 1000],
|
|
103
89
|
},
|
|
104
90
|
},
|
|
105
91
|
];
|
|
@@ -117,9 +103,7 @@ export class Plinko {
|
|
|
117
103
|
}
|
|
118
104
|
|
|
119
105
|
static calculateChances(rows: number): BigNumber[] {
|
|
120
|
-
return Object.keys(Array(rows + 1)).map(position =>
|
|
121
|
-
this.calculateChance(rows, parseInt(position)),
|
|
122
|
-
);
|
|
106
|
+
return Object.keys(Array(rows + 1)).map(position => this.calculateChance(rows, parseInt(position)));
|
|
123
107
|
}
|
|
124
108
|
|
|
125
109
|
static calculateMultiplier(risk: PlinkoRiskLevel, rows: number, results: number[]) {
|
|
@@ -133,6 +117,16 @@ export class Plinko {
|
|
|
133
117
|
return new BigNumber(config.payout[risk][position]);
|
|
134
118
|
}
|
|
135
119
|
|
|
120
|
+
static getMaxMultiplier(risk: PlinkoRiskLevel, rows: number) {
|
|
121
|
+
const config = this.configs().find(config => config.rows === rows);
|
|
122
|
+
|
|
123
|
+
if (!config) {
|
|
124
|
+
throw new Error(`No configuration found for ${rows} rows`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return new BigNumber(Math.max(...config.payout[risk]));
|
|
128
|
+
}
|
|
129
|
+
|
|
136
130
|
static getResults(hexStr: string[], rows: number): number[] {
|
|
137
131
|
const results: number[] = [];
|
|
138
132
|
hexStr.map(hexToBytes).every(gameResultBytes => {
|
package/src/games/roulette.ts
CHANGED
|
@@ -144,7 +144,9 @@ const isValidStraight = (num: number): boolean => {
|
|
|
144
144
|
export const isValidStreet = (street: streetValue): boolean => {
|
|
145
145
|
const sortedStreet = (street as unknown as number[]).sort((a, b) => a - b);
|
|
146
146
|
|
|
147
|
-
return
|
|
147
|
+
return (
|
|
148
|
+
sortedStreet.length === 3 && STREET_VALUES.some(val => val[0] === sortedStreet[0] && val[1] === sortedStreet[1] && val[2] === sortedStreet[2])
|
|
149
|
+
);
|
|
148
150
|
};
|
|
149
151
|
|
|
150
152
|
// for corners (up, down, left, right, and diagonally adjacent)
|
|
@@ -174,7 +176,7 @@ export const cornerNumbers = (num: straightValue): straightValue[] => {
|
|
|
174
176
|
possibleCornerNumbers = [num - 4, num - 3, num - 1, num + 2, num + 3];
|
|
175
177
|
}
|
|
176
178
|
|
|
177
|
-
return possibleCornerNumbers.filter(
|
|
179
|
+
return possibleCornerNumbers.filter(num => isValidStraight(num)) as straightValue[];
|
|
178
180
|
};
|
|
179
181
|
|
|
180
182
|
// up, down, left, right
|
|
@@ -193,7 +195,7 @@ export const isValidSplit = (firstNumber: straightValue, secondNumber: straightV
|
|
|
193
195
|
possibleSplitNumbers = [firstNumber - 3, firstNumber - 1, firstNumber + 3];
|
|
194
196
|
}
|
|
195
197
|
|
|
196
|
-
const filteredPossibleSplitNumbers = possibleSplitNumbers.filter(
|
|
198
|
+
const filteredPossibleSplitNumbers = possibleSplitNumbers.filter(num => isValidStraight(num)) as straightValue[];
|
|
197
199
|
|
|
198
200
|
if (firstNumber !== 0 && secondNumber !== 0) {
|
|
199
201
|
return filteredPossibleSplitNumbers.includes(secondNumber);
|
|
@@ -206,7 +208,12 @@ export const isValidSplit = (firstNumber: straightValue, secondNumber: straightV
|
|
|
206
208
|
return false; // should never reach here
|
|
207
209
|
};
|
|
208
210
|
|
|
209
|
-
export const isValidCorner = (
|
|
211
|
+
export const isValidCorner = (
|
|
212
|
+
firstNumber: straightValue,
|
|
213
|
+
secondNumber: straightValue,
|
|
214
|
+
thirdNumber: straightValue,
|
|
215
|
+
fourthNumber: straightValue,
|
|
216
|
+
): boolean => {
|
|
210
217
|
// all 4 numbers MUST be adjacent to every other number
|
|
211
218
|
const numbersAdjacentToFirstNumber = cornerNumbers(firstNumber);
|
|
212
219
|
const numbersAdjacentToSecondNumber = cornerNumbers(secondNumber);
|
|
@@ -416,8 +423,8 @@ export class Roulette {
|
|
|
416
423
|
return resultNum;
|
|
417
424
|
}
|
|
418
425
|
|
|
419
|
-
static getPayout(inputs: RouletteInput, result: straightValue): BigNumber {
|
|
420
|
-
if (!this.validateInputs(inputs)) {
|
|
426
|
+
static getPayout(inputs: RouletteInput, result: straightValue, skipValidation?: boolean): BigNumber {
|
|
427
|
+
if (!skipValidation && !this.validateInputs(inputs)) {
|
|
421
428
|
throw new Error('Invalid inputs');
|
|
422
429
|
}
|
|
423
430
|
|
|
@@ -491,9 +498,25 @@ export class Roulette {
|
|
|
491
498
|
return totalPayout;
|
|
492
499
|
}
|
|
493
500
|
|
|
501
|
+
static getMaxMultiplier(inputs: RouletteInput, betAmount: BigNumber): BigNumber {
|
|
502
|
+
const maxPotentialPayout = BigNumber.max(...STRAIGHT_VALUES.map(possibleResult => this.getPayout(inputs, possibleResult, true)));
|
|
503
|
+
|
|
504
|
+
return maxPotentialPayout.dividedBy(betAmount).decimalPlaces(4);
|
|
505
|
+
}
|
|
506
|
+
|
|
494
507
|
static validateInputs(inputs: RouletteInput): boolean {
|
|
495
|
-
const {
|
|
496
|
-
|
|
508
|
+
const {
|
|
509
|
+
straightValues,
|
|
510
|
+
splitValues,
|
|
511
|
+
streetValues,
|
|
512
|
+
cornerValues,
|
|
513
|
+
doubleStreetValues,
|
|
514
|
+
parityValues,
|
|
515
|
+
colorValues,
|
|
516
|
+
columnValues,
|
|
517
|
+
dozenValues,
|
|
518
|
+
halfValues,
|
|
519
|
+
} = inputs;
|
|
497
520
|
// user must bet on at least one thing
|
|
498
521
|
if (
|
|
499
522
|
straightValues.length === 0 &&
|
|
@@ -510,11 +533,11 @@ export class Roulette {
|
|
|
510
533
|
return false;
|
|
511
534
|
}
|
|
512
535
|
|
|
513
|
-
const straightsValid = straightValues.every(
|
|
514
|
-
const splitsValid = splitValues.every(
|
|
515
|
-
const streetsValid = streetValues.every(
|
|
516
|
-
const cornersValid = cornerValues.every(
|
|
517
|
-
const doubleStreetsValid = doubleStreetValues.every(
|
|
536
|
+
const straightsValid = straightValues.every(input => isValidStraight(input.straightNumber));
|
|
537
|
+
const splitsValid = splitValues.every(input => isValidSplit(input.firstNumber, input.secondNumber));
|
|
538
|
+
const streetsValid = streetValues.every(input => isValidStreet(input.street));
|
|
539
|
+
const cornersValid = cornerValues.every(input => isValidCorner(input.firstNumber, input.secondNumber, input.thirdNumber, input.fourthNumber));
|
|
540
|
+
const doubleStreetsValid = doubleStreetValues.every(input => isValidDoubleStreet(input.firstStreet, input.secondStreet));
|
|
518
541
|
|
|
519
542
|
return straightsValid && splitsValid && streetsValid && cornersValid && doubleStreetsValid;
|
|
520
543
|
}
|
package/src/games/wheel.ts
CHANGED
|
@@ -38,25 +38,28 @@ export const WHEEL_MULTIPLIERS: Record<WheelSegments, Record<WheelRiskLevel, num
|
|
|
38
38
|
},
|
|
39
39
|
[WheelSegments.FORTY]: {
|
|
40
40
|
[WheelRiskLevel.LOW]: [
|
|
41
|
-
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5,
|
|
42
|
-
1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
|
|
41
|
+
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5,
|
|
42
|
+
1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
|
|
43
43
|
],
|
|
44
44
|
[WheelRiskLevel.MEDIUM]: [
|
|
45
45
|
2, 0, 1.5, 0, 3, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 2, 0, 1.5, 0, 1.6, 0, 1.5, 0, 3, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 2, 0, 1.5, 0,
|
|
46
46
|
],
|
|
47
|
-
[WheelRiskLevel.HIGH]: [
|
|
47
|
+
[WheelRiskLevel.HIGH]: [
|
|
48
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39.6,
|
|
49
|
+
],
|
|
48
50
|
},
|
|
49
51
|
[WheelSegments.FIFTY]: {
|
|
50
52
|
[WheelRiskLevel.LOW]: [
|
|
51
|
-
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5,
|
|
52
|
-
1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
|
|
53
|
+
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5,
|
|
54
|
+
1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0, 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
|
|
53
55
|
],
|
|
54
56
|
[WheelRiskLevel.MEDIUM]: [
|
|
55
|
-
1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5,
|
|
56
|
-
1.5, 0, 2, 0, 1.5, 0,
|
|
57
|
+
1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0, 1.5,
|
|
58
|
+
0, 5, 0, 1.5, 0, 2, 0, 1.5, 0,
|
|
57
59
|
],
|
|
58
60
|
[WheelRiskLevel.HIGH]: [
|
|
59
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
61
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
62
|
+
0, 49.5,
|
|
60
63
|
],
|
|
61
64
|
},
|
|
62
65
|
};
|
|
@@ -71,7 +74,10 @@ export const WHEEL_SEGMENTS_TO_NUMBER: Record<WheelSegments, number> = {
|
|
|
71
74
|
|
|
72
75
|
export class Wheel {
|
|
73
76
|
static getResult(hexStr: string, segments: WheelSegments, risk: WheelRiskLevel): { resultSegment: number; multiplier: BigNumber } {
|
|
74
|
-
const resultSegment = this.getRandomNumberFromHexStr(hexStr)
|
|
77
|
+
const resultSegment = this.getRandomNumberFromHexStr(hexStr)
|
|
78
|
+
.multipliedBy(WHEEL_SEGMENTS_TO_NUMBER[segments])
|
|
79
|
+
.integerValue(BigNumber.ROUND_DOWN)
|
|
80
|
+
.toNumber();
|
|
75
81
|
const multiplier = BigNumber(WHEEL_MULTIPLIERS[segments][risk][resultSegment]);
|
|
76
82
|
return { resultSegment, multiplier };
|
|
77
83
|
}
|
|
@@ -91,4 +97,9 @@ export class Wheel {
|
|
|
91
97
|
|
|
92
98
|
return result;
|
|
93
99
|
}
|
|
100
|
+
|
|
101
|
+
static getMaxMultiplier(segments: WheelSegments, risk: WheelRiskLevel): BigNumber {
|
|
102
|
+
const maxMultiplier = BigNumber.max(...WHEEL_MULTIPLIERS[segments][risk]);
|
|
103
|
+
return maxMultiplier;
|
|
104
|
+
}
|
|
94
105
|
}
|
|
@@ -221,7 +221,7 @@ describe('sports-name', () => {
|
|
|
221
221
|
).toBe('Draw 1-1');
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
-
it('should not format 1:1 when it is not score
|
|
224
|
+
it('should not format 1:1 when it is not score market display type', () => {
|
|
225
225
|
expect(
|
|
226
226
|
formatSelectionName({
|
|
227
227
|
name: '1:1',
|
|
@@ -388,6 +388,32 @@ describe('sports-name', () => {
|
|
|
388
388
|
}),
|
|
389
389
|
).toBe('Team B 2.75');
|
|
390
390
|
});
|
|
391
|
+
|
|
392
|
+
it('should format liveValue zero to no sign for betradar', () => {
|
|
393
|
+
expect(
|
|
394
|
+
formatSelectionName({
|
|
395
|
+
name: 'Team A (+0)',
|
|
396
|
+
homeDisplayName: 'Team A',
|
|
397
|
+
awayDisplayName: 'Team B',
|
|
398
|
+
lineValue: '0',
|
|
399
|
+
isHome: true,
|
|
400
|
+
marketDisplayType: SportsMarketDisplayType.OVER_AND_UNDER,
|
|
401
|
+
provider: SportsMarketProvider.BETRADAR,
|
|
402
|
+
}),
|
|
403
|
+
).toBe('Team A (0.0)');
|
|
404
|
+
|
|
405
|
+
expect(
|
|
406
|
+
formatSelectionName({
|
|
407
|
+
name: 'Team B (-0)',
|
|
408
|
+
homeDisplayName: 'Team A',
|
|
409
|
+
awayDisplayName: 'Team B',
|
|
410
|
+
lineValue: '0',
|
|
411
|
+
isHome: false,
|
|
412
|
+
marketDisplayType: SportsMarketDisplayType.OVER_AND_UNDER,
|
|
413
|
+
provider: SportsMarketProvider.BETRADAR,
|
|
414
|
+
}),
|
|
415
|
+
).toBe('Team B (0.0)');
|
|
416
|
+
});
|
|
391
417
|
});
|
|
392
418
|
|
|
393
419
|
it('should format liveValue with leading zero', () => {
|
package/src/utils/sports-name.ts
CHANGED
|
@@ -6,6 +6,9 @@ export const HOME_PLACEHOLDERS = ['Home Team', 'Home', 'Competitor A'];
|
|
|
6
6
|
export const AWAY_PLACEHOLDERS = ['Away Team', 'Away', 'Competitor B'];
|
|
7
7
|
|
|
8
8
|
const SCORE_NAME_REGEX = /^\b(\d+)[:-](\d+)\b$/;
|
|
9
|
+
const LINE_VALUE_WITH_BRACKET_REGEX = (lineValue: string) => new RegExp(`\\([+-]?${lineValue.replace(/[-+]/g, '')}(\\.0+)?\\)$`, 'g');
|
|
10
|
+
const LINE_VALUE_WITHOUT_BRACKET_REGEX = (lineValue: string) => new RegExp(`(\\b|[+-])${lineValue.replace(/[-+]/g, '')}(\\.0+)?$`, 'g');
|
|
11
|
+
const ZERO_LINE_VALUE_WITH_BRACKET_REGEX = LINE_VALUE_WITH_BRACKET_REGEX('0');
|
|
9
12
|
|
|
10
13
|
function formatOddinDoubleChanceName({
|
|
11
14
|
displayName,
|
|
@@ -112,27 +115,34 @@ function formatLineValueName({
|
|
|
112
115
|
}: { displayName: string; lineValue: string | null; isHome: boolean; marketDisplayType: SportsMarketDisplayType; provider: SportsMarketProvider }) {
|
|
113
116
|
let formattedName = displayName;
|
|
114
117
|
|
|
115
|
-
|
|
116
|
-
if (lineValue !== null && provider !== SportsMarketProvider.BETRADAR) {
|
|
118
|
+
if (lineValue !== null) {
|
|
117
119
|
const number = BigNumber(lineValue);
|
|
118
120
|
|
|
119
121
|
if (!number.isNaN()) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// skip lineValue in map nth kills market
|
|
125
|
-
if (marketDisplayType !== SportsMarketDisplayType.MAP_NTH_KILLS) {
|
|
126
|
-
formattedName += ' ';
|
|
127
|
-
|
|
128
|
-
// only add sign in handicap market
|
|
129
|
-
if (marketDisplayType === SportsMarketDisplayType.HANDICAP_VALUE) {
|
|
130
|
-
if (!number.isZero()) {
|
|
131
|
-
formattedName += isHome !== number.isPositive() ? '+' : '-'; // flip opposite if isHome
|
|
132
|
-
}
|
|
122
|
+
if (provider === SportsMarketProvider.BETRADAR) {
|
|
123
|
+
if (number.isZero()) {
|
|
124
|
+
formattedName = formattedName.replace(ZERO_LINE_VALUE_WITH_BRACKET_REGEX, '(0.0)');
|
|
133
125
|
}
|
|
126
|
+
} else {
|
|
127
|
+
// Since betradar uses template already to format name, we don't need to format it here again
|
|
128
|
+
|
|
129
|
+
formattedName = formattedName.replace(LINE_VALUE_WITH_BRACKET_REGEX(lineValue), '');
|
|
130
|
+
formattedName = formattedName.replace(LINE_VALUE_WITHOUT_BRACKET_REGEX(lineValue), '');
|
|
131
|
+
formattedName = formattedName.trim();
|
|
132
|
+
|
|
133
|
+
// skip lineValue in map nth kills market
|
|
134
|
+
if (marketDisplayType !== SportsMarketDisplayType.MAP_NTH_KILLS) {
|
|
135
|
+
formattedName += ' ';
|
|
134
136
|
|
|
135
|
-
|
|
137
|
+
// only add sign in handicap market
|
|
138
|
+
if (marketDisplayType === SportsMarketDisplayType.HANDICAP_VALUE) {
|
|
139
|
+
if (!number.isZero()) {
|
|
140
|
+
formattedName += isHome !== number.isPositive() ? '+' : '-'; // flip opposite if isHome
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
formattedName += number.abs().toFixed(number.dp() || 1); // min 1 dp
|
|
145
|
+
}
|
|
136
146
|
}
|
|
137
147
|
}
|
|
138
148
|
}
|