Skip to main content
Glama
probability.test.ts3.02 kB
import { describe, it, expect } from 'vitest'; import { ProbabilityEngine } from '../../src/math/probability'; describe('ProbabilityEngine', () => { const engine = new ProbabilityEngine(); it('should calculate simple probability', () => { // 1d20 >= 11 is 50% expect(engine.calculateProbability('1d20', 11)).toBeCloseTo(0.5); // 1d20 >= 20 is 5% expect(engine.calculateProbability('1d20', 20)).toBeCloseTo(0.05); }); it('should handle modifiers', () => { // 1d20+5 >= 15 is same as 1d20 >= 10 (55%) expect(engine.calculateProbability('1d20+5', 15)).toBeCloseTo(0.55); }); it('should handle multiple dice', () => { // 2d6 distribution: // 2: 1/36 // 7: 6/36 = 1/6 // 12: 1/36 const dist = engine.getDistribution('2d6'); expect(dist.get(2)).toBeCloseTo(1 / 36); expect(dist.get(7)).toBeCloseTo(6 / 36); expect(dist.get(12)).toBeCloseTo(1 / 36); }); it('should calculate expected value', () => { expect(engine.expectedValue('1d20')).toBe(10.5); expect(engine.expectedValue('2d6')).toBe(7); expect(engine.expectedValue('1d20+5')).toBe(15.5); }); it('should handle advantage', () => { // 1d20 advantage // EV should be 13.825 const ev = engine.expectedValue({ count: 1, sides: 20, modifier: 0, advantage: true }); expect(ev).toBeCloseTo(13.825); }); it('should handle disadvantage', () => { // 1d20 disadvantage // EV should be 7.175 const ev = engine.expectedValue({ count: 1, sides: 20, modifier: 0, disadvantage: true }); expect(ev).toBeCloseTo(7.175); }); it('should compare expressions', () => { // P(1d20 > 1d20) should be slightly less than 0.5 (ties are possible) // P(A > B) + P(B > A) + P(A = B) = 1 // P(A > B) = P(B > A) // P(A = B) = sum(p^2) = 20 * (1/400) = 1/20 = 0.05 // 2 * P(A > B) = 0.95 => P(A > B) = 0.475 expect(engine.compare('1d20', '1d20')).toBeCloseTo(0.475); // P(1d20+5 > 1d20) // Should be high expect(engine.compare('1d20+5', '1d20')).toBeGreaterThan(0.6); }); it('should handle exploding dice', () => { // 1d4! // EV for d4! is 4.2 (approx) // Formula: E = sides/2 + 0.5 + E/sides => E(1 - 1/sides) = (sides+1)/2 => E = (sides+1)/2 * (sides/(sides-1)) // For d4: 2.5 * (4/3) = 10/3 = 3.333... // Wait, standard explosion adds the new roll. // E = \sum p_i x_i // E = (1/s)(1 + ... + s-1) + (1/s)(s + E) // E = (1/s)(s(s-1)/2) + 1 + E/s // E(1 - 1/s) = (s-1)/2 + 1 = (s+1)/2 // E((s-1)/s) = (s+1)/2 // E = s(s+1) / 2(s-1) // For d4: 4*5 / 2*3 = 20/6 = 3.333 // For d6: 6*7 / 2*5 = 42/10 = 4.2 expect(engine.expectedValue('1d4!')).toBeCloseTo(3.333, 2); expect(engine.expectedValue('1d6!')).toBeCloseTo(4.2, 2); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server