shufflecom-calculations 2.2.32 → 2.3.1

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.
@@ -0,0 +1,18 @@
1
+ import BigNumber from 'bignumber.js';
2
+ import { GameCalculation } from './gameCalculation';
3
+ export declare enum ChickenDifficulty {
4
+ EASY = "EASY",
5
+ MEDIUM = "MEDIUM",
6
+ HARD = "HARD",
7
+ EXPERT = "EXPERT"
8
+ }
9
+ export declare class Chicken extends GameCalculation {
10
+ static readonly TOTAL_LANES = 20;
11
+ static readonly DIFFICULTY_TO_VALID_LANE_COUNT: Record<ChickenDifficulty, number>;
12
+ static readonly DIFFICULTY_TO_HEX_ROUNDS: Record<ChickenDifficulty, number>;
13
+ static getResults(hexStr: string[], difficulty: ChickenDifficulty): number[];
14
+ static calculateWinChanceBN(difficulty: ChickenDifficulty, selectedLane: number): BigNumber;
15
+ static calculateMultiplierBN(difficulty: ChickenDifficulty, selectedLane: number, edgeBps: number): BigNumber;
16
+ static firstDeathLane(results: number[]): number;
17
+ static isLoss(results: number[], selected: number): boolean;
18
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Chicken = exports.ChickenDifficulty = void 0;
4
+ const edge_1 = require("../utils/edge");
5
+ const ncr_1 = require("../utils/ncr");
6
+ const gameCalculation_1 = require("./gameCalculation");
7
+ var ChickenDifficulty;
8
+ (function (ChickenDifficulty) {
9
+ ChickenDifficulty["EASY"] = "EASY";
10
+ ChickenDifficulty["MEDIUM"] = "MEDIUM";
11
+ ChickenDifficulty["HARD"] = "HARD";
12
+ ChickenDifficulty["EXPERT"] = "EXPERT";
13
+ })(ChickenDifficulty || (exports.ChickenDifficulty = ChickenDifficulty = {}));
14
+ class Chicken extends gameCalculation_1.GameCalculation {
15
+ static getResults(hexStr, difficulty) {
16
+ const losingLaneCount = this.TOTAL_LANES - this.DIFFICULTY_TO_VALID_LANE_COUNT[difficulty];
17
+ return this.pickUniqueNumbers(hexStr, losingLaneCount, this.TOTAL_LANES);
18
+ }
19
+ static calculateWinChanceBN(difficulty, selectedLane) {
20
+ const validLanes = this.DIFFICULTY_TO_VALID_LANE_COUNT[difficulty];
21
+ const selectedLaneCount = selectedLane + 1;
22
+ return (0, ncr_1.nCr)(validLanes, selectedLaneCount).dividedBy((0, ncr_1.nCr)(this.TOTAL_LANES, selectedLaneCount));
23
+ }
24
+ static calculateMultiplierBN(difficulty, selectedLane, edgeBps) {
25
+ const winChance = this.calculateWinChanceBN(difficulty, selectedLane);
26
+ return (0, edge_1.calculateEdgeMultiplier)(edgeBps).div(winChance);
27
+ }
28
+ static firstDeathLane(results) {
29
+ if (results.length === 0) {
30
+ throw new Error('Results array is empty, cannot determine first death lane.');
31
+ }
32
+ return Math.min(...results);
33
+ }
34
+ static isLoss(results, selected) {
35
+ return selected >= this.firstDeathLane(results);
36
+ }
37
+ }
38
+ exports.Chicken = Chicken;
39
+ Chicken.TOTAL_LANES = 20;
40
+ Chicken.DIFFICULTY_TO_VALID_LANE_COUNT = {
41
+ [ChickenDifficulty.EASY]: 19,
42
+ [ChickenDifficulty.MEDIUM]: 17,
43
+ [ChickenDifficulty.HARD]: 15,
44
+ [ChickenDifficulty.EXPERT]: 10,
45
+ };
46
+ Chicken.DIFFICULTY_TO_HEX_ROUNDS = {
47
+ [ChickenDifficulty.EASY]: 1,
48
+ [ChickenDifficulty.MEDIUM]: 1,
49
+ [ChickenDifficulty.HARD]: 1,
50
+ [ChickenDifficulty.EXPERT]: 2,
51
+ };
52
+ //# sourceMappingURL=chicken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chicken.js","sourceRoot":"","sources":["../../src/games/chicken.ts"],"names":[],"mappings":";;;AACA,wCAAwD;AACxD,sCAAmC;AACnC,uDAAoD;AAEpD,IAAY,iBAKX;AALD,WAAY,iBAAiB;IAC3B,kCAAa,CAAA;IACb,sCAAiB,CAAA;IACjB,kCAAa,CAAA;IACb,sCAAiB,CAAA;AACnB,CAAC,EALW,iBAAiB,iCAAjB,iBAAiB,QAK5B;AAED,MAAa,OAAQ,SAAQ,iCAAe;IAiB1C,MAAM,CAAC,UAAU,CAAC,MAAgB,EAAE,UAA6B;QAC/D,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;QAE3F,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,UAA6B,EAAE,YAAoB;QAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;QACnE,MAAM,iBAAiB,GAAG,YAAY,GAAG,CAAC,CAAC;QAE3C,OAAO,IAAA,SAAG,EAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,SAAS,CAAC,IAAA,SAAG,EAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,CAAC,qBAAqB,CAAC,UAA6B,EAAE,YAAoB,EAAE,OAAe;QAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAEtE,OAAO,IAAA,8BAAuB,EAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,OAAiB;QACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,OAAiB,EAAE,QAAgB;QAC/C,OAAO,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;;AA7CH,0BA8CC;AA7CiB,mBAAW,GAAG,EAAE,CAAC;AAEjB,sCAA8B,GAAsC;IAClF,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE;IAC5B,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE;IAC9B,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE;IAC5B,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE;CAC/B,CAAC;AAEc,gCAAwB,GAAsC;IAC5E,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7B,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;CAC9B,CAAC"}
@@ -0,0 +1,16 @@
1
+ export declare abstract class GameCalculation {
2
+ private static readonly BYTE_TOTAL;
3
+ private static readonly BYTES_PER_HEX_STRING;
4
+ private static readonly BYTES_PER_RANDOM_NUMBER;
5
+ private static readonly NUMBERS_PER_HEX_STRING;
6
+ private static bytesToProbability;
7
+ private static getRandomInt;
8
+ static pickUniqueNumbers(hexStrings: string[], count: number, poolSize: number): number[];
9
+ static generateIndependentNumbers(hexStrings: string[], count: number, maxValue: number): number[];
10
+ static generateDigestHex({ serverSeed, clientSeed, nonce, rounds, }: {
11
+ serverSeed: string;
12
+ clientSeed: string;
13
+ nonce: string;
14
+ rounds: number;
15
+ }): string[];
16
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GameCalculation = void 0;
7
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
8
+ const hex_to_bytes_1 = require("../utils/hex-to-bytes");
9
+ const crypto_1 = require("crypto");
10
+ class GameCalculation {
11
+ static bytesToProbability(byteArray, startIndex) {
12
+ let probability = new bignumber_js_1.default(0);
13
+ for (let i = 0; i < this.BYTES_PER_RANDOM_NUMBER; i++) {
14
+ const byteValue = byteArray[startIndex + i];
15
+ probability = probability.plus(new bignumber_js_1.default(byteValue).dividedBy(this.BYTE_TOTAL.pow(i + 1)));
16
+ }
17
+ return probability;
18
+ }
19
+ static getRandomInt(byteArray, startIndex, maxValue) {
20
+ const probability = this.bytesToProbability(byteArray, startIndex);
21
+ return probability.multipliedBy(maxValue).integerValue(bignumber_js_1.default.ROUND_DOWN).toNumber();
22
+ }
23
+ static pickUniqueNumbers(hexStrings, count, poolSize) {
24
+ const bytesAvailable = hexStrings.length * this.BYTES_PER_HEX_STRING;
25
+ const bytesNeeded = count * this.BYTES_PER_RANDOM_NUMBER;
26
+ if (bytesAvailable < bytesNeeded) {
27
+ throw new Error(`Not enough randomness: need ${bytesNeeded} bytes for ${count} numbers, only have ${bytesAvailable} bytes`);
28
+ }
29
+ const results = [];
30
+ const pool = Array.from({ length: poolSize }, (_, i) => i);
31
+ const byteArrays = hexStrings.map(hex_to_bytes_1.hexToBytes);
32
+ for (let hexIndex = 0; hexIndex < byteArrays.length; hexIndex++) {
33
+ const byteArray = byteArrays[hexIndex];
34
+ for (let numberIndex = 0; numberIndex < this.NUMBERS_PER_HEX_STRING; numberIndex++) {
35
+ if (results.length >= count) {
36
+ return results;
37
+ }
38
+ const byteOffset = numberIndex * this.BYTES_PER_RANDOM_NUMBER;
39
+ const remainingPoolSize = pool.length;
40
+ const randomPosition = this.getRandomInt(byteArray, byteOffset, remainingPoolSize);
41
+ const pickedNumber = pool.splice(randomPosition, 1)[0];
42
+ results.push(pickedNumber);
43
+ }
44
+ }
45
+ return results;
46
+ }
47
+ static generateIndependentNumbers(hexStrings, count, maxValue) {
48
+ const bytesAvailable = hexStrings.length * this.BYTES_PER_HEX_STRING;
49
+ const bytesNeeded = count * this.BYTES_PER_RANDOM_NUMBER;
50
+ if (bytesAvailable < bytesNeeded) {
51
+ throw new Error(`Not enough randomness: need ${bytesNeeded} bytes for ${count} numbers, only have ${bytesAvailable} bytes`);
52
+ }
53
+ const results = [];
54
+ const byteArrays = hexStrings.map(hex_to_bytes_1.hexToBytes);
55
+ for (let hexIndex = 0; hexIndex < byteArrays.length; hexIndex++) {
56
+ const byteArray = byteArrays[hexIndex];
57
+ for (let numberIndex = 0; numberIndex < this.NUMBERS_PER_HEX_STRING; numberIndex++) {
58
+ if (results.length >= count) {
59
+ return results;
60
+ }
61
+ const byteOffset = numberIndex * this.BYTES_PER_RANDOM_NUMBER;
62
+ const randomNumber = this.getRandomInt(byteArray, byteOffset, maxValue);
63
+ results.push(randomNumber);
64
+ }
65
+ }
66
+ return results;
67
+ }
68
+ static generateDigestHex({ serverSeed, clientSeed, nonce, rounds, }) {
69
+ const results = Array.from(Array(rounds).keys()).map(round => {
70
+ const hmac = (0, crypto_1.createHmac)('sha256', serverSeed);
71
+ hmac.update(`${clientSeed}:${nonce}:${round}`);
72
+ return hmac.digest('hex');
73
+ });
74
+ return results;
75
+ }
76
+ }
77
+ exports.GameCalculation = GameCalculation;
78
+ GameCalculation.BYTE_TOTAL = new bignumber_js_1.default(256);
79
+ GameCalculation.BYTES_PER_HEX_STRING = 32;
80
+ GameCalculation.BYTES_PER_RANDOM_NUMBER = 4;
81
+ GameCalculation.NUMBERS_PER_HEX_STRING = 8;
82
+ //# sourceMappingURL=gameCalculation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gameCalculation.js","sourceRoot":"","sources":["../../src/games/gameCalculation.ts"],"names":[],"mappings":"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"}