feat: add TTR simulator and calculation engine, enhance member model with TTR adjustment constant
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 59s

This commit is contained in:
Torsten Schulz (local)
2026-10-05 15:18:10 +02:00
parent 6fa54163f6
commit 6d982add75
21 changed files with 466 additions and 27 deletions

View File

@@ -0,0 +1,44 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
calculateExpectedWinProbability,
calculateTtrChange,
calculateTtrEvent,
roundTtr,
} from '../src/services/ttrCalculator.mjs';
test('equal ratings have a 50 percent expected win probability', () => {
assert.equal(calculateExpectedWinProbability(1500, 1500), 0.5);
assert.equal(calculateTtrChange(1500, 1500, 'win', 16).displayChange, 8);
assert.equal(calculateTtrChange(1500, 1500, 'loss', 16).displayChange, -8);
});
test('a win against a stronger player gains more than a win against a weaker player', () => {
const strong = calculateTtrChange(1318, 1429, 'win', 16);
const weak = calculateTtrChange(1318, 1180, 'win', 16);
assert.ok(strong.rawChange > weak.rawChange);
assert.ok(calculateTtrChange(1318, 1429, 'loss', 16).rawChange > calculateTtrChange(1318, 1180, 'loss', 16).rawChange);
});
test('an event uses one immutable snapshot and rounds only the total', () => {
const event = calculateTtrEvent({
ownTtr: 1318,
adjustmentConstant: 16,
matches: [
{ opponentTtr: 1382, result: 'win' },
{ opponentTtr: 1429, result: 'win' },
],
});
assert.equal(event.calculations[0].ownTtrSnapshot, 1318);
assert.equal(event.ownTtrSnapshot, 1318);
assert.equal(event.displayChange, 25);
assert.equal(event.projectedTtr, 1343);
assert.equal(event.displayChange, roundTtr(event.calculations[0].rawChange + event.calculations[1].rawChange));
assert.equal(event.projectedTtr, 1318 + event.displayChange);
});
test('the adjustment constant is player-specific input', () => {
const with16 = calculateTtrChange(1500, 1500, 'win', 16).rawChange;
const with8 = calculateTtrChange(1500, 1500, 'win', 8).rawChange;
assert.equal(with16, with8 * 2);
});