123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- class ContentDescription {
- public name : string;
- public group : ContentUnit | ContentGroup;
- public description : Say | ((description : ContentDescription, group : ContentUnit | ContentGroup) => Say);
- private saidCount = 0;
- public constructor (name : string, group : ContentUnit | ContentGroup) {
- this.name = name;
- this.group = group;
- }
- public getScore () {
- return (this.group).getScore();
- }
- public getDescription (group : ContentUnit | ContentGroup) : Say {
- this.saidCount++;
- if (typeof this.description == "function") {
- return this.description(this, group);
- }
- return this.description;
- }
- public setDescription (description : Say | string | ((description : ContentDescription, group : ContentUnit | ContentGroup) => Say) ) {
- if (!(description instanceof Say)) {
- this.description = new Say(description);
- } else {
- this.description = description;
- }
- return this;
- }
- public static pickDescriptions (cda : Array<ContentDescription>, target : ContentGroup | ContentUnit) : Array<Say> {
- let a = cda.slice();
- let groups = [];
- for (let i = 0; i < a.length; i++) {
- let randomIndex = Math.floor(Math.random() * (a.length - i)) + i;
- let temp = a[i];
- a[i] = a[randomIndex];
- a[randomIndex] = temp;
- }
- // After shuffling the list, descriptions with the highest scores go at the top, and between those the ones with the lowest saidCounts go first
- // If multiple descriptions have the same score/saidCount, they are picked randomly due to the previous shuffling.
- a.sort((a : ContentDescription, b : ContentDescription) => {
- // Division by saidCount for now, to increase rotativity of descriptions
- // Reduce precision on final number to decrease the likelihood of printing the same descriptions always in the same order
- let precision = 5;
- let scoreA = Math.floor(precision * a.getScore() / (a.saidCount + 1)) / precision;
- let scoreB = Math.floor(precision * b.getScore() / (b.saidCount + 1)) / precision;
- if (scoreA != scoreB) return scoreB - scoreA;
- return 0;
- });
- a.forEach(description => {
- groups.push(description.group);
- });
- let matches = (<any> target).matchAgainst(<any> groups);
- if (matches != undefined) {
- let result = [];
- matches.forEach(i => {
- result.push(a[i].getDescription(target));
- result.push(new Say(" "));
- });
- return result;
- } else {
- console.warn("No description available for", target);
- return [new Say("Warning: No description available for the current situation. Please report so it can be corrected.")];
- }
- }
- }
|