Skip to content

Commit d6a0142

Browse files
committed
Remove unnecessary seeded RNG
1 parent df593be commit d6a0142

10 files changed

Lines changed: 12 additions & 279 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ The Probability Lab helps students understand:
2020
- Two events mode: joint heatmap + two-way table with joint/conditional reads
2121
- Bias controls: fair vs biased devices (coin, die, spinner; custom devices are configured via
2222
`config.json`)
23-
- Seeded randomness: reproduce runs with a seed
2423
- Event relationships: independent, dependent
2524
- Custom devices: define up to 50 outcomes + probabilities in `config.json`
2625

@@ -185,10 +184,10 @@ Experiment summary:
185184
Settings modal:
186185

187186
- pl-settings-modal
188-
- pl-settings-section-probabilities, pl-settings-section-event, pl-settings-section-randomness
187+
- pl-settings-section-probabilities, pl-settings-section-event
189188
- pl-single-config, pl-two-config
190189
- pl-bias-options, pl-bias-options-a, pl-bias-options-b
191-
- pl-relationship, pl-seed
190+
- pl-relationship
192191

193192
Controls:
194193

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ A Bespoke Simulation for repeated-trial probability experiments (coin, die, spin
77
- **One event mode**: event builder (select outcomes), live bar chart, convergence chart, frequency table
88
- **Two events mode**: joint heatmap + two-way table; click a cell to see joint and conditional probabilities
99
- **Bias controls**: explore fair vs biased devices
10-
- **Seeded randomness**: optionally reproduce runs with a seed
1110

1211
## Development
1312

@@ -30,4 +29,3 @@ npm run start:prod
3029
- `client/app.js` – simulation engine + rendering
3130
- `client/app.css` – app-specific styling
3231
- `client/help-content.html` – Help modal content
33-

client/app.js

Lines changed: 3 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { loadConfig } from './src/shell/config.js';
66
import { createActivityLogger } from './src/shell/activity-logger.js';
77
import { clamp, safeNumber } from './src/shared/math.js';
88
import { formatProbability } from './src/shared/format.js';
9-
import { createRngFromSeed } from './src/probability-lab/domain/rng.js';
109
import { buildDeviceDefinition } from './src/probability-lab/domain/devices.js';
1110
import simulateSingleTrials from './src/probability-lab/engine/simulate-single.js';
1211
import simulateTwoTrials from './src/probability-lab/engine/simulate-two.js';
@@ -53,8 +52,6 @@ const els = {
5352
runModeToggleManual: $('pl-run-mode-toggle-manual'),
5453
runModeToggleAuto: $('pl-run-mode-toggle-auto'),
5554

56-
seed: $('pl-seed'),
57-
5855
eventOutcomes: $('pl-event-outcomes'),
5956

6057
deviceView: $('pl-device-view'),
@@ -101,18 +98,7 @@ let settingsModal = null;
10198
let historyModal = null;
10299
let historyView = null;
103100

104-
/**
105-
* Generates a random numeric seed string for the RNG
106-
* @returns {string} A random seed value as a string
107-
*/
108-
function generateRandomSeed() {
109-
return Math.floor(Math.random() * 100000000).toString();
110-
}
111-
112101
const store = createStore({
113-
rng: Math.random,
114-
seedText: '',
115-
userSpecifiedSeed: false,
116102

117103
mode: 'single',
118104
speed: 60,
@@ -274,12 +260,6 @@ function resetSimulation({ reason = 'unknown', logSettings = false } = {}) {
274260
runner.stopRunning();
275261
store.setState((draft) => {
276262
draft.running.cancel = false;
277-
// Generate new random seed on reset if user hasn't specified one
278-
if (!draft.userSpecifiedSeed) {
279-
draft.seedText = generateRandomSeed();
280-
}
281-
// Rewind RNG to the start of the seeded sequence on every reset
282-
draft.rng = createRngFromSeed(draft.seedText);
283263
});
284264

285265
const state = store.getState();
@@ -427,7 +407,6 @@ function updateControls() {
427407
const toDisable = [
428408
els.spinnerSectors,
429409
els.stepSize,
430-
els.seed,
431410
els.relationship,
432411
els.openSettings,
433412
];
@@ -770,23 +749,6 @@ function renderEventOptions() {
770749
}
771750
}
772751

773-
function applySeed(seedText) {
774-
const trimmed = (seedText ?? '').trim();
775-
store.setState((draft) => {
776-
if (trimmed === '') {
777-
// User cleared the seed - revert to auto-generation
778-
draft.userSpecifiedSeed = false;
779-
draft.seedText = generateRandomSeed();
780-
} else {
781-
// User specified a seed - mark as user-specified and persist it
782-
draft.userSpecifiedSeed = true;
783-
draft.seedText = trimmed;
784-
}
785-
draft.rng = createRngFromSeed(draft.seedText);
786-
});
787-
resetSimulation({ reason: 'seed_change', logSettings: true });
788-
}
789-
790752
function openSettingsModal(scrollTarget) {
791753
if (!settingsModal) return;
792754

@@ -862,7 +824,6 @@ function initHistoryModal() {
862824
function syncUiFromState() {
863825
const state = store.getState();
864826
els.stepSize.value = String(state.stepSize);
865-
els.seed.value = state.seedText;
866827

867828
els.spinnerSectors.value = String(state.single.spinnerSectors);
868829

@@ -1038,7 +999,7 @@ function initEventListeners() {
1038999
els.step.addEventListener('click', () => {
10391000
const state = store.getState();
10401001
const stateSlice = state.mode === 'two' ? state.two : state.single;
1041-
runner.runTrials(state.stepSize, state.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, state.rng);
1002+
runner.runTrials(state.stepSize, state.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, Math.random);
10421003
});
10431004

10441005
els.reset.addEventListener('click', () => {
@@ -1051,25 +1012,10 @@ function initEventListeners() {
10511012
runner.stopRunning();
10521013
} else {
10531014
const stateSlice = state.mode === 'two' ? state.two : state.single;
1054-
runner.startAuto(state.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, state.rng, state.speed);
1015+
runner.startAuto(state.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, Math.random, state.speed);
10551016
}
10561017
});
10571018

1058-
// Apply seed automatically on change
1059-
let seedTimeout = null;
1060-
els.seed.addEventListener('input', () => {
1061-
// Debounce to avoid resetting simulation too frequently during typing
1062-
clearTimeout(seedTimeout);
1063-
seedTimeout = setTimeout(() => {
1064-
applySeed(els.seed.value);
1065-
}, 500);
1066-
});
1067-
1068-
els.seed.addEventListener('change', () => {
1069-
clearTimeout(seedTimeout);
1070-
applySeed(els.seed.value);
1071-
});
1072-
10731019
els.twoWayTable.addEventListener('click', (event) => {
10741020
const cell = event.target.closest('[data-row][data-col]');
10751021
if (!cell) return;
@@ -1157,12 +1103,6 @@ async function init() {
11571103
if (config.visualElements) {
11581104
draft.visualElements = { ...draft.visualElements, ...config.visualElements };
11591105
}
1160-
// Generate random seed at startup if seedText is empty
1161-
if (!draft.seedText || draft.seedText.trim() === '') {
1162-
draft.seedText = generateRandomSeed();
1163-
draft.userSpecifiedSeed = false;
1164-
}
1165-
draft.rng = createRngFromSeed(draft.seedText);
11661106
});
11671107
syncUiFromState();
11681108

@@ -1191,7 +1131,7 @@ async function init() {
11911131
setTimeout(() => {
11921132
const newState = store.getState();
11931133
const stateSlice = newState.mode === 'two' ? newState.two : newState.single;
1194-
runner.startAuto(newState.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, newState.rng, newState.speed);
1134+
runner.startAuto(newState.mode, simulateSingleTrials, simulateTwoTrials, stateSlice, Math.random, newState.speed);
11951135
}, 0);
11961136
}
11971137
},

client/help-content.html

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,17 @@ <h2>Overview</h2>
2525

2626
<h3>Competencies</h3>
2727
<ul>
28-
<li>Identifies probability as a measure of likelihood</li>
29-
<li>Describes outcomes and sample spaces</li>
30-
<li>Estimates event frequency from real or simulated data</li>
31-
<li>Compares probabilities</li>
32-
<li>Interprets relationships between events using tables or diagrams</li>
28+
<li>Identify probability as a measure of likelihood</li>
29+
<li>Describe outcomes and sample spaces</li>
30+
<li>Estimate event frequency from real or simulated data</li>
31+
<li>Compare probabilities</li>
32+
<li>Interpret relationships between events using tables or diagrams</li>
3333
</ul>
3434
</section>
3535

3636
<section id="getting-started">
3737
<h2>Getting Started</h2>
3838
<ol>
39-
<li><strong>Choose a mode:</strong> <em>One event</em> (single sample space) or <em>Two events</em> (two-way table).</li>
40-
<li><strong>Pick a device</strong> (coin / die / spinner / custom) and optionally adjust its bias.</li>
4139
<li><strong>Define Event E</strong> by selecting outcomes (e.g., “Heads”, or “Even” by selecting 2, 4, 6).</li>
4240
<li><strong>Run trials</strong> using <em>Run</em>, the +1/+10/+100/+1000 buttons, or <em>Start auto</em>.</li>
4341
<li><strong>Interpret the results</strong> using the charts and tables (look at how the estimates stabilize as trials increase).</li>
@@ -57,41 +55,19 @@ <h3>Frequency Table</h3>
5755
<p>Lists theoretical probability, count, relative frequency, and the difference (<strong>Δ</strong>) between experiment and theory for each outcome. Selected outcomes (Event E) are highlighted.</p>
5856

5957
<h3>Two Events: Heatmap + Two-way Table</h3>
60-
<p>Switch to <em>Two events</em> to explore joint outcomes. Click a cell to see:</p>
58+
<p>Click a cell in the heatmap to see:</p>
6159
<ul>
6260
<li><strong>P(A ∩ B)</strong> (joint probability estimate)</li>
6361
<li><strong>P(A | B)</strong> and <strong>P(B | A)</strong> (conditional probability estimate)</li>
6462
<li>An "independence check" comparing <strong>P(A)·P(B)</strong> to <strong>P(A ∩ B)</strong></li>
6563
</ul>
6664

67-
<h3>Seeded Runs</h3>
68-
<p>Use a <strong>seed</strong> to repeat the same random sequence and compare runs.</p>
69-
</section>
70-
71-
<section id="workflow">
72-
<h2>Learning Workflow</h2>
73-
<p>Use these short tasks to build intuition quickly:</p>
74-
<ol>
75-
<li><strong>Sample space:</strong> Choose a device and list its outcomes (e.g., die: 1–6).</li>
76-
<li><strong>Event building:</strong> Define an event (e.g., “Even” on a die) by selecting outcomes.</li>
77-
<li><strong>Convergence:</strong> Run 10, 100, 1,000 trials. Describe how the estimate changes.</li>
78-
<li><strong>Comparing probabilities:</strong> Change the device bias (e.g., increase P(6)) and predict what will happen before running.</li>
79-
<li><strong>Relationships:</strong> In two-event mode, compare <em>Independent</em> vs <em>Dependent</em>. Explain what changes in the two-way table.</li>
80-
</ol>
81-
82-
<h3>Tips & Best Practices</h3>
83-
<ul>
84-
<li>Small samples are noisy on purpose—don’t “fix” the randomness.</li>
85-
<li>If you change the device bias, treat it as a new experiment and reset.</li>
86-
<li>Use the tables to justify claims (don’t rely only on what “feels” likely).</li>
87-
</ul>
8865
</section>
8966

9067
<section id="shortcuts">
9168
<h2>Shortcuts</h2>
9269
<ul>
9370
<li><strong>ESC</strong> - Close help modal</li>
94-
<li><strong>Enter</strong> (in the Seed input) - Apply seed</li>
9571
<li><strong>Click a heatmap/two-way cell</strong> - Show joint + conditional probabilities</li>
9672
</ul>
9773
</section>
@@ -123,9 +99,4 @@ <h2>Troubleshooting / FAQ</h2>
12399
<summary>What should I look for in the two-way table?</summary>
124100
<p>Start with the joint counts. Then click a cell to compare <strong>P(A ∩ B)</strong> to <strong>P(A)·P(B)</strong>. If events are independent, these values should be close (with enough trials).</p>
125101
</details>
126-
127-
<details>
128-
<summary>Is anything saved?</summary>
129-
<p>The lab saves basic settings (mode, device choices, bias sliders, event selection, seed) in your browser so you can continue where you left off. Trial results are not persisted.</p>
130-
</details>
131102
</section>

client/index.html

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,6 @@ <h3 class="heading-xxxsmall">Event B</h3>
229229
</label>
230230
</div>
231231
</section>
232-
233-
<section class="box pl-settings-section" id="pl-settings-section-randomness">
234-
<div class="pl-settings-section-header">
235-
<h3 class="heading-xxxsmall">Random seed</h3>
236-
<p class="pl-muted body-xsmall">Set a seed to reproduce the same results across runs.</p>
237-
</div>
238-
239-
<label class="row">
240-
<input id="pl-seed" class="input" type="number" placeholder="42" />
241-
</label>
242-
</section>
243232
</div>
244233

245234
<div id="pl-single-view" class="pl-content-grid">

client/src/probability-lab/AGENTS.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ Two-event mode (`state.two`):
2323

2424
## Domain
2525

26-
- `domain/rng.js`: deterministic RNG utilities; empty seed returns `Math.random`.
2726
- `domain/cdf.js`: builds CDF and samples indexes.
2827
- `domain/devices.js`: builds device definitions and clamps probabilities.
2928
- Spinner sectors are clamped to 2-12.

client/src/probability-lab/domain/rng.js

Lines changed: 0 additions & 30 deletions
This file was deleted.

client/src/shell/activity-logger.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ function buildSettingsSnapshot(state) {
4949
deviceA: state.two.deviceA ?? null,
5050
deviceB: state.two.deviceB ?? null,
5151
sections,
52-
seed: state.seedText ?? '',
5352
relationship: state.two.relationship ?? null,
5453
spinnerSectorsA: state.two.spinnerSectorsA ?? null,
5554
spinnerSectorsB: state.two.spinnerSectorsB ?? null,
@@ -71,7 +70,6 @@ function buildSettingsSnapshot(state) {
7170
mode: 'single',
7271
device: state.single.device ?? null,
7372
sections,
74-
seed: state.seedText ?? '',
7573
spinnerSectors: state.single.spinnerSectors ?? null,
7674
bias: {
7775
coinProbabilities: cloneArray(state.single.coinProbabilities),

tests/AGENTS.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Scope: Vitest suites under `tests/`.
99
## Structure
1010

1111
- `tests/shared/` exercises `client/src/shared` utilities.
12-
- `tests/probability-lab/domain/` covers RNG, CDF, device definitions.
12+
- `tests/probability-lab/domain/` covers CDF, device definitions.
1313
- `tests/probability-lab/engine/` covers simulation functions.
1414
- Includes coverage for custom devices and dependent-mode behavior.
1515

@@ -18,4 +18,3 @@ Scope: Vitest suites under `tests/`.
1818
- Use `.test.js` or `.spec.js` filenames (see `vitest.config.js`).
1919
- Vitest runs with `environment: \"node\"` (see `vitest.config.js`).
2020
- Import modules from `client/src` to test production logic.
21-
- Keep RNG-based tests deterministic by seeding where needed.

0 commit comments

Comments
 (0)