play-again.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import type { TargetWord } from '@wordle/shared';
  2. /**
  3. * Select a target word weighted by proximity to the player's skill level.
  4. *
  5. * Algorithm:
  6. * 1. Compute a weight for each target based on how close its difficulty
  7. * is to the player's skill (Gaussian-like: 1 / (1 + (diff - skill)^2))
  8. * 2. Pick randomly, weighted by those weights.
  9. *
  10. * If all difficulties are equal (default 3.0), this degenerates to uniform random.
  11. */
  12. export function selectPlayAgainWord(
  13. targets: TargetWord[],
  14. skillMetric: number
  15. ): TargetWord {
  16. if (targets.length === 0) {
  17. throw new Error('No target words available');
  18. }
  19. // Compute weights: closer difficulty = higher weight
  20. const weights = targets.map((t) => {
  21. const delta = t.difficulty - skillMetric;
  22. return 1 / (1 + delta * delta);
  23. });
  24. // Weighted random selection
  25. const totalWeight = weights.reduce((sum, w) => sum + w, 0);
  26. let r = Math.random() * totalWeight;
  27. for (let i = 0; i < targets.length; i++) {
  28. r -= weights[i];
  29. if (r <= 0) {
  30. return targets[i];
  31. }
  32. }
  33. // Fallback (floating point edge case)
  34. return targets[targets.length - 1];
  35. }