poker-bitvaljs 1.1.0 → 1.1.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.
Files changed (2) hide show
  1. package/bitval-worker.js +152 -0
  2. package/package.json +3 -2
@@ -0,0 +1,152 @@
1
+ // Web Worker for parallel matchup evaluation
2
+ // Loads bitval.js to access BitVal class and dependencies
3
+ importScripts('bitval.js');
4
+
5
+ /**
6
+ * Deserializes setup data from main thread (converts string BigInts back to BigInt)
7
+ */
8
+ function deserializeSetup(setupData) {
9
+ const setup = {
10
+ ...setupData,
11
+ boardMask: BigInt(setupData.boardMask),
12
+ deadCardsMask: BigInt(setupData.deadCardsMask),
13
+ comboArray: setupData.comboArray ? setupData.comboArray.map(s => BigInt(s)) : null,
14
+ // Keep other properties as-is
15
+ boardCards: setupData.boardCards,
16
+ numberOfBoardCards: setupData.numberOfBoardCards,
17
+ iterations: setupData.iterations,
18
+ isExhaustive: setupData.isExhaustive,
19
+ numberOfCardsToDeal: setupData.numberOfCardsToDeal
20
+ };
21
+ return setup;
22
+ }
23
+
24
+ /**
25
+ * Deserializes matchup data (converts string BigInt masks back to BigInt)
26
+ */
27
+ function deserializeMatchup(matchupData) {
28
+ return {
29
+ ...matchupData,
30
+ heroMask: BigInt(matchupData.heroMask),
31
+ villainMask: BigInt(matchupData.villainMask)
32
+ };
33
+ }
34
+
35
+ /**
36
+ * Evaluates a single matchup in the worker context
37
+ * Similar to _evaluateMatchup but without progress callbacks
38
+ */
39
+ async function evaluateMatchupInWorker(heroMask, villainMask, setup, evalCache, cacheInfo, bitval) {
40
+ let win = 0, tie = 0, lose = 0;
41
+ const deadMask = heroMask | villainMask | setup.deadCardsMask;
42
+
43
+ // Initialize random number generator for Monte Carlo (not needed for exhaustive)
44
+ if (!setup.isExhaustive) {
45
+ bitval.xorShift = new XorShift32();
46
+ }
47
+
48
+ // Prepare for exhaustive enumeration if applicable
49
+ let comboArray = null;
50
+ let iterations = setup.iterations;
51
+ if (setup.isExhaustive) {
52
+ // Use comboArray from setup if available, otherwise compute it
53
+ if (setup.comboArray && setup.comboArray.length > 0) {
54
+ comboArray = setup.comboArray;
55
+ iterations = comboArray.length;
56
+ } else {
57
+ // Compute comboArray if not provided
58
+ const availableMasks = bitval._getAvailableCardMasksByLookUp(deadMask);
59
+ comboArray = bitval._getCombinations(availableMasks, setup.numberOfCardsToDeal);
60
+ iterations = comboArray.length;
61
+ }
62
+ }
63
+
64
+ // Main evaluation loop
65
+ for (let i = 0; i < iterations; i++) {
66
+ // Generate board: use pre-computed combo for exhaustive, or deal randomly
67
+ const board = setup.isExhaustive
68
+ ? setup.boardMask | comboArray[i]
69
+ : bitval.deal(setup.boardMask, deadMask, setup.numberOfCardsToDeal) | setup.boardMask;
70
+
71
+ // Evaluate both hands
72
+ let hEval, hKick, vEval, vKick;
73
+ if (cacheInfo && evalCache) {
74
+ [hEval, hKick] = bitval._getCachedEvaluation(cacheInfo.heroKey, cacheInfo.heroHand, board, evalCache);
75
+ [vEval, vKick] = bitval._getCachedEvaluation(cacheInfo.villainKey, cacheInfo.villainHand, board, evalCache);
76
+ } else {
77
+ [hEval, hKick] = bitval.evaluate(heroMask | board);
78
+ [vEval, vKick] = bitval.evaluate(villainMask | board);
79
+ }
80
+
81
+ // Compare and accumulate results
82
+ if (hEval > vEval || (hEval === vEval && hKick > vKick)) {
83
+ win++;
84
+ } else if (vEval > hEval || (vEval === hEval && vKick > hKick)) {
85
+ lose++;
86
+ } else {
87
+ tie++;
88
+ }
89
+ }
90
+
91
+ return { matchupWin: win, matchupTie: tie, matchupLose: lose };
92
+ }
93
+
94
+ // Worker message handler
95
+ self.onmessage = async function(e) {
96
+ try {
97
+ const { matchups, setupData, workerId } = e.data;
98
+
99
+ // Deserialize setup
100
+ const setup = deserializeSetup(setupData);
101
+
102
+ // Create BitVal instance and cache for this worker (reused for all matchups)
103
+ const bitval = new BitVal();
104
+ const evalCache = new FastestAutoClearingCache(16000000);
105
+
106
+ const results = [];
107
+
108
+ // Evaluate each matchup in the batch
109
+ for (const matchupData of matchups) {
110
+ const matchup = deserializeMatchup(matchupData);
111
+
112
+ // Prepare cache info if available
113
+ const cacheInfo = matchup.heroKey ? {
114
+ heroKey: matchup.heroKey,
115
+ heroHand: matchup.heroHand,
116
+ villainKey: matchup.villainKey,
117
+ villainHand: matchup.villainHand
118
+ } : null;
119
+
120
+ // Evaluate matchup
121
+ const result = await evaluateMatchupInWorker(
122
+ matchup.heroMask,
123
+ matchup.villainMask,
124
+ setup,
125
+ evalCache,
126
+ cacheInfo,
127
+ bitval
128
+ );
129
+
130
+ results.push({
131
+ key: matchup.key,
132
+ validCount: matchup.validCount,
133
+ ...result
134
+ });
135
+ }
136
+
137
+ // Send results back to main thread
138
+ self.postMessage({
139
+ workerId,
140
+ results,
141
+ success: true
142
+ });
143
+ } catch (error) {
144
+ // Send error back to main thread
145
+ self.postMessage({
146
+ workerId: e.data.workerId,
147
+ error: error.message,
148
+ success: false
149
+ });
150
+ }
151
+ };
152
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poker-bitvaljs",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "High-performance poker hand evaluator optimized for browser environments, using bitwise operations for rapid poker hand analysis and equity calculations.",
5
5
  "main": "bitval.js",
6
6
  "scripts": {
@@ -19,10 +19,11 @@
19
19
  "license": "MIT",
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "https://github.com/DarraghGeo/poker-bitvaljs.git"
22
+ "url": "git+https://github.com/DarraghGeo/poker-bitvaljs.git"
23
23
  },
24
24
  "files": [
25
25
  "bitval.js",
26
+ "bitval-worker.js",
26
27
  "README.md"
27
28
  ]
28
29
  }