Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
// tokeAnd.js

(function () {
  /* global AdventureJS A */

  var p = AdventureJS.Parser.prototype;

  /**
   * Convert any of these FROM
   *   "verb1 noun1, then verb2 noun2"
   *   "verb1 noun1 then verb2 noun2"
   *   "verb1 noun1 and then verb2 noun2"
   * TO
   *   "verb1 noun1. verb2 noun2."
   * Try to convert FROM
   *   "verb1 then verb2 noun1"
   * TO
   *   "verb1 noun1. verb2 noun2."
   *
   * Each clause separated by 'then' is a distinct input.
   * We treat clauses as unrelated without dependencies
   * and stack each into a queue.
   * <br><br>
   * Example: "take sword then go north"
   * @memberOf AdventureJS.Parser
   * @method AdventureJS.Parser#tokeAnd
   * @param {String} input
   * @returns {String}
   * @TODO what about "take sword then shield" ?
   */
  p.tokeAnd = function Parser_tokeAnd(input) {
    this.game.log(
      "L1597",
      "log",
      "high",
      `[tokeAnd.js] tokeAnd() receive: ${input}`,
      "Parser"
    );

    const sentences = input
      .split("|")
      .map((sentence) => sentence.trim())
      .filter((sentence) => sentence.length);

    console.warn(`tokeAnd sentences`, sentences);

    // --------------------------------------------------
    // for each sentence
    // --------------------------------------------------
    for (let i = 0; i < sentences.length; i++) {
      // normalize variations of and for easier split
      // look for:
      // - ", and "
      // - " and "
      // - ", "
      let sentence = sentences[i].replace(
        /(?:,\s*and\s*|,\s*|\s+and\s+|\s+)\s+/i,
        (match, offset, string, groups) => {
          console.warn(`tokeAnd`, { match, offset, string, groups });
          return " [AND] ";
        }
      );

      const words = sentence.split(/\s+/);

      for (let w = 0; w < words.length; w++) {
        if (words[w] !== "and") continue;

        const prev = words[w - 1];
        const next = words[w + 1];

        // determine whether this particular "and"
        // is a conjunction or a sentence boundary
      }

      for (let w = 0; w < words.length; w++) {
        if (words[w] !== "and") continue;

        const before = words.slice(0, w);
        const after = words.slice(w + 1);

        // inspect before and after
      }

      // const last_sentence = sentences[i - 1];
      // const next_sentence = sentences[i + 1];
      // if (last_sentence && last_sentence.split(" ").length === 1) {
      //   // we got a split where the language preceding the then
      //   // is only one word. Is that word a verb?
      //   const potential_verb = this.parseVerb(last_sentence);
      //   if (potential_verb) {
      //     // we found a verb - can that verb be intransitive?
      //     // this isn't conclusive but it's the best we got
      //     const dictionary_verb = this.game.getVerb(potential_verb);
      //     if (dictionary_verb && !dictionary_verb.accepts_structures.verb) {
      //       // get first word from sentence
      //       const next_potential_verb = this.parseVerb(sentence.split(" ")[0]);
      //       const next_dictionary_verb = this.game.getVerb(next_potential_verb);
      //       if (next_dictionary_verb) {
      //         // yes, it appears that player input
      //         // "verb1 then verb2 something"
      //         // we can't make anything of verb1 alone
      //         // so copy second clause to first clause
      //         // then restore verb1 to first clause
      //         // we should wind up with
      //         // [ "verb1 something", "verb2 something" ]
      //         sentences[i - 1] = sentences[i].replace(
      //           next_potential_verb,
      //           potential_verb
      //         );
      //       }
      //     }
      //   }
      // }
    }

    console.warn(`tokeAnd sentences`, sentences);

    // @TODO east then look - intransitive verb handling

    // ensure every phrase but the last ends with a boundary
    if (sentences.length > 1) {
      for (let i = 0; i < sentences.length - 1; i++) {
        sentences[i] = sentences[i].trim();

        // does it end with a period because it ends with an abbreviation?
        // ie: give glass key to mrs. go east
        if (sentences[i].endsWith(".")) {
          let words = sentences[i].split(" ");
          let lastword = words[words.length - 1].toLowerCase();
          if (
            "undefined" !== typeof this.game.world_lookup[lastword] ||
            this.game.dictionary.getAbbreviation(lastword)
          ) {
            // add a sentence boundary which will be used
            // to split input into sentences later
            sentences[i] += " |";
          }
        }

        if (!sentences[i].endsWith(".")) sentences[i] += " |";
      }
    }

    // reduce array back to string
    let ninput = sentences.map((item) => item.trim()).join(" ");
    console.warn(`tokeAnd ninput`, ninput);

    this.game.log(
      "L1598",
      "log",
      "high",
      `[tokeAnd.js] tokeAnd() return: ${input}`,
      "Parser"
    );
    return input;
  };
})();