feat: add relationship classification helpers with tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { classify, getPartnerCap, getFriendCap } from '../relationshipHelpers.js';
|
||||
|
||||
describe('relationshipHelpers', () => {
|
||||
describe('classify', () => {
|
||||
it('returns Partner for value >= 80', () => {
|
||||
expect(classify(80)).toBe('Partner');
|
||||
expect(classify(100)).toBe('Partner');
|
||||
});
|
||||
|
||||
it('returns Close Friend for value 50-79', () => {
|
||||
expect(classify(50)).toBe('Close Friend');
|
||||
expect(classify(79)).toBe('Close Friend');
|
||||
});
|
||||
|
||||
it('returns Friend for value 20-49', () => {
|
||||
expect(classify(20)).toBe('Friend');
|
||||
expect(classify(49)).toBe('Friend');
|
||||
});
|
||||
|
||||
it('returns Acquaintance for value 5-19', () => {
|
||||
expect(classify(5)).toBe('Acquaintance');
|
||||
expect(classify(19)).toBe('Acquaintance');
|
||||
});
|
||||
|
||||
it('returns Stranger for value -4 to 4', () => {
|
||||
expect(classify(0)).toBe('Stranger');
|
||||
expect(classify(4)).toBe('Stranger');
|
||||
expect(classify(-4)).toBe('Stranger');
|
||||
});
|
||||
|
||||
it('returns Wary for value -19 to -5', () => {
|
||||
expect(classify(-5)).toBe('Wary');
|
||||
expect(classify(-19)).toBe('Wary');
|
||||
});
|
||||
|
||||
it('returns Rival for value -49 to -20', () => {
|
||||
expect(classify(-20)).toBe('Rival');
|
||||
expect(classify(-49)).toBe('Rival');
|
||||
});
|
||||
|
||||
it('returns Enemy for value -79 to -50', () => {
|
||||
expect(classify(-50)).toBe('Enemy');
|
||||
expect(classify(-79)).toBe('Enemy');
|
||||
});
|
||||
|
||||
it('returns Nemesis for value <= -80', () => {
|
||||
expect(classify(-80)).toBe('Nemesis');
|
||||
expect(classify(-100)).toBe('Nemesis');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPartnerCap', () => {
|
||||
it('returns 1 for average stats', () => {
|
||||
expect(getPartnerCap(10, 10)).toBe(1);
|
||||
});
|
||||
|
||||
it('returns 2 for high sociability and empathy', () => {
|
||||
expect(getPartnerCap(15, 14)).toBe(2);
|
||||
});
|
||||
|
||||
it('returns 1 if only sociability is high', () => {
|
||||
expect(getPartnerCap(15, 10)).toBe(1);
|
||||
});
|
||||
|
||||
it('returns 1 if only empathy is high', () => {
|
||||
expect(getPartnerCap(10, 14)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFriendCap', () => {
|
||||
it('returns baseCap for sociability 10', () => {
|
||||
expect(getFriendCap(10)).toBe(5);
|
||||
});
|
||||
|
||||
it('increases with high sociability', () => {
|
||||
expect(getFriendCap(16)).toBe(8);
|
||||
});
|
||||
|
||||
it('decreases with low sociability', () => {
|
||||
expect(getFriendCap(6)).toBe(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
import { relationshipConfig } from '../config/relationshipConfig.js';
|
||||
|
||||
export function classify(value: number): string {
|
||||
for (const tier of relationshipConfig.tiers) {
|
||||
if (value >= tier.min) return tier.label;
|
||||
}
|
||||
return 'Nemesis';
|
||||
}
|
||||
|
||||
export function getPartnerCap(sociability: number, empathy: number): number {
|
||||
if (
|
||||
sociability >= relationshipConfig.polySociabilityThreshold &&
|
||||
empathy >= relationshipConfig.polyEmpathyThreshold
|
||||
) {
|
||||
return relationshipConfig.polyPartnerCap;
|
||||
}
|
||||
return relationshipConfig.defaultPartnerCap;
|
||||
}
|
||||
|
||||
export function getFriendCap(sociability: number): number {
|
||||
return relationshipConfig.baseFriendCap +
|
||||
Math.floor((sociability - 10) * relationshipConfig.friendCapPerSociability);
|
||||
}
|
||||
|
||||
export function getEffectiveClassification(
|
||||
entityId: number,
|
||||
value: number,
|
||||
allRelationships: Map<number, { value: number }>,
|
||||
sociability: number,
|
||||
empathy: number,
|
||||
): string {
|
||||
const raw = classify(value);
|
||||
|
||||
if (raw === 'Partner') {
|
||||
const cap = getPartnerCap(sociability, empathy);
|
||||
let partnerCount = 0;
|
||||
for (const [otherId, rel] of allRelationships) {
|
||||
if (otherId !== entityId && rel.value >= 80 && rel.value > value) {
|
||||
partnerCount++;
|
||||
}
|
||||
}
|
||||
if (partnerCount >= cap) return 'Close Friend';
|
||||
}
|
||||
|
||||
if (raw === 'Friend') {
|
||||
const cap = getFriendCap(sociability);
|
||||
let friendCount = 0;
|
||||
for (const [otherId, rel] of allRelationships) {
|
||||
if (otherId !== entityId && rel.value >= 20 && rel.value < 80 && rel.value > value) {
|
||||
friendCount++;
|
||||
}
|
||||
}
|
||||
if (friendCount >= cap) return 'Acquaintance';
|
||||
}
|
||||
|
||||
return raw;
|
||||
}
|
||||
Reference in New Issue
Block a user