Willem van den Ende d3cc48c0f7 feat: Character Creation user story — ADTs, properties, and Allium spec
- Level value object (1..10, level-capped health)
- Health value object (non-negative, pure sub/add)
- Status discriminated union (alive | dead)
- Character entity with private constructor and static factory
- 9 fast-check properties covering creation invariants
- Allium spec with entities, rules, and invariants
2026-06-12 20:23:48 +01:00

42 lines
996 B
TypeScript

/**
* Level value object — constrained to 1..10.
*
* "I can't believe it's not Haskell": invalid states are unrepresentable.
*/
export class Level {
#value: number;
private constructor(n: number) {
this.#value = n;
}
static create(n: number): Level {
if (n < 1 || n > 10) {
throw new Error(`Level must be between 1 and 10, got ${n}`);
}
return new Level(n);
}
get value(): number {
return this.#value;
}
/** Difference in levels (target - this). Positive means target is higher. */
diff(other: Level): number {
return other.value - this.value;
}
/** Next level, or throws if already at max. */
next(): Level {
if (this.#value >= 10) {
throw new Error('Cannot level up beyond level 10');
}
return Level.create(this.#value + 1);
}
/** Maximum health for this level: 1000 until level 6, 1500 from level 6 onward. */
static maxHealthForLevel(level: number): number {
return level >= 6 ? 1500 : 1000;
}
}