ContentDescription.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. class ContentDescription {
  2. public name : string;
  3. public group : ContentUnit | ContentGroup;
  4. public description : Say | ((description : ContentDescription, group : ContentUnit | ContentGroup) => Say);
  5. private saidCount = 0;
  6. public constructor (name : string, group : ContentUnit | ContentGroup) {
  7. this.name = name;
  8. this.group = group;
  9. }
  10. public addMarker (marker : any) {
  11. if (this.group instanceof ContentGroup) {
  12. let markerUnit = new ContentUnit();
  13. markerUnit.addCategory(new ContentDifferential(marker))
  14. this.group.addUnit(markerUnit);
  15. } else if (this.group instanceof ContentUnit) {
  16. this.group.addCategory(marker);
  17. }
  18. }
  19. public getScore () {
  20. return (this.group).getScore();
  21. }
  22. public getDescription (group : ContentUnit | ContentGroup) : Say {
  23. this.saidCount++;
  24. if (typeof this.description == "function") {
  25. return this.description(this, group);
  26. }
  27. return this.description;
  28. }
  29. public setDescription (description : Say | string | ((description : ContentDescription, group : ContentUnit | ContentGroup) => Say) ) {
  30. if (!(description instanceof Say)) {
  31. this.description = new Say(description);
  32. } else {
  33. this.description = description;
  34. }
  35. return this;
  36. }
  37. public static pickDescriptions (cda : Array<ContentDescription>, target : ContentGroup | ContentUnit) : Array<Say> {
  38. let a = cda.slice();
  39. let groups = [];
  40. for (let i = 0; i < a.length; i++) {
  41. let randomIndex = Math.floor(Math.random() * (a.length - i)) + i;
  42. let temp = a[i];
  43. a[i] = a[randomIndex];
  44. a[randomIndex] = temp;
  45. }
  46. // After shuffling the list, descriptions with the highest scores go at the top, and between those the ones with the lowest saidCounts go first
  47. // If multiple descriptions have the same score/saidCount, they are picked randomly due to the previous shuffling.
  48. a.sort((a : ContentDescription, b : ContentDescription) => {
  49. // Division by saidCount for now, to increase rotativity of descriptions
  50. // Reduce precision on final number to decrease the likelihood of printing the same descriptions always in the same order
  51. let precision = 5;
  52. let scoreA = Math.floor(precision * a.getScore() / (a.saidCount + 1)) / precision;
  53. let scoreB = Math.floor(precision * b.getScore() / (b.saidCount + 1)) / precision;
  54. if (scoreA != scoreB) return scoreB - scoreA;
  55. return 0;
  56. });
  57. a.forEach(description => {
  58. groups.push(description.group);
  59. });
  60. let matches = (<any> target).matchAgainst(<any> groups);
  61. if (matches != undefined) {
  62. let result = [];
  63. matches.forEach(i => {
  64. result.push(a[i].getDescription(target));
  65. result.push(new Say(" "));
  66. });
  67. return result;
  68. } else {
  69. console.warn("No description available for", target);
  70. return [new Say("Warning: No description available for the current situation. Please report so it can be corrected.")];
  71. }
  72. }
  73. }