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

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

  var p = AdventureJS.Parser.prototype;

  /**
   * ",", "and", and ", and" can be used in multiple ways:
   * <ol>
   *  <li>as a conjunction
   *    <ul>
   *      <li>"take glass key and silver key"</li>
   *      <li>"take all but glass key and silver key"</li>
   *      <li>"take glass key, silver key"</li>
   *      <li>"take all but glass key, silver key"</li>
   *    </ul>
   *  </li>
   *  <li>as a sentence boundary (like "then")
   *    <ul>
   *      <li>"take glass key and go north"</li>
   *      <li>"jump and go north"</li>
   *      <li>"jump up and go north"</li>
   *      <li>"go east and go north"</li>
   *      <li>STRETCH: "put a in b and c in d"</li>
   *    </ul>
   *  </li>
   * </ol>
   *
   * When "and" is used as a conjunction in phrases like
   * "take sword and stone", convert "and" to "&" to make
   * plural noun string "sword&stone".
   * <br/><br/>
   * When used as a sentence boundary, we convert "and"
   * to " | ".
   * @memberOf AdventureJS.Parser
   * @method AdventureJS.Parser#tokenizeAnd
   * @param {String} input
   * @returns {String}
   */
  p.tokenizeAnd = function Parser_tokenizeAnd(input) {
    this.game.log(
      "L1702",
      "log",
      "high",
      `[tokenizeAnd.js] tokenizeAnd() receive: ${input}`,
      "Parser"
    );

    // look for:
    // - ", and "
    // - " and "
    // - ", "

    // variations:
    // - "take glass key and go north" : verb noun and verb = |
    // - "jump and go north" : verb and verb = |
    // - "jump up and go north" : verb prep and verb = |
    // - "go east and go north" : verb noun and verb = |
    // - "take and wear eyeglasses"
    // stretch goal:
    // - "put a in b and c in d"

    // We've already set some sentence boundaries though we're
    // not yet ready to split input into sentences. We do want
    // to search per sentence so we're doing a temporarily split.

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

    for (let i = 0; i < sentences.length; i++) {
      const sentence = sentences[i];

      if (sentence.includes(" and ")) {
        console.warn(`SENTENCE INCLUDES " AND "`);
        // is word before "and" a noun?
        // is word after "and" a verb?
        let words = sentence.split(" ").map((item) => item.trim());
        let last_word = "";
        let count = -1;

        words.forEach((word) => {
          let boundary = false;

          last_word = word;
          count++;
        });
      }
    }

    input = sentences.map((item) => item.trim()).join(" | ");

    /* *
     * Convert " and " to "&" for later noun parsing
     * We've already removed instances of " and then "
     * and we're assuming that any other use of "and" is in
     * the form of "verb noun and noun".
     * We also look for ", and" as in "take x, and y"
     * which seems less likely to be input, but not impossible.
     * Another possibility: "look between noun and noun" - may need a lookBetweenAnd verb
     * "put noun between noun and noun" - might need a putBetweenAnd verb
     * @TODO need to handle "take key and go north"
     * where "and" works like "then"
     */
    input = input.replace(/, and /g, "&");
    input = input.replace(/ and /g, "&");

    /* *
     * Also convert ", " to "&", for instances of:
     *  take sword, shield
     *
     * There is an additional comma check in splitByThens,
     * because we assume English speakers will input things like
     *  take sword, then go north
     * But in that case we want to strip the comma.
     */
    input = input.replace(/, /g, "&");

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