Функция ведет себя странно после первого клика - PullRequest
0 голосов
/ 12 июня 2018

У меня есть следующий HTML:

<input type = "text" id = "pick"> <input type = "submit" value = "Submit" onclick = "guessWord()">

, который запускает мою функцию js, которая отлично работает (с несвязанными сбоями) при первом вызове.Но если я изменю свой текст и отправлю его снова без перезагрузки, мой первоначальный оператор if / else будет работать неправильно.В частности, if / else должен проверять, находится ли введенное пользователем слово в массиве.Он работает правильно при первом вызове, но после этого он переходит к блоку else, даже если не должен.

Вот js (заранее извиняюсь за включение всей функции, меня просто обычно просят включить больше кода, чем я делаю изначально):

function guessWord() {

  var comWords, match, compWord =  "";
  var possWords = dictFive;
  var firstFive = ["vibex", "fjord", "nymph", "waltz", "gucks"]; // note: right now choosing any of these words results in unexpected behavior -- either it doesn't accept them or it freezes.
  var inputWord = document.getElementById("pick").value.toLowerCase().replace(/\s+/g, '');

  if (possWords.includes(inputWord)) { // checks to see if the user inputted word is in our dictionary.i f not, requests a different word.

    // start game loop:

    // in order to try and get as much information as possible in the first few turns I start by guessing the five words in firstFive[]: vibex, fjord, nymph, waltz, gucks. together, these words give us information about 25 letters.

    for (let d = 0; d < inputWord.length; d++) { // this loop will run for the length of the inputted word, making it scaleable so in the future the program could accept shorter or longer words. within the current scope it will always be 5.

      compWord = firstFive[d]; // the computers word will loop through each word in firstFive[].

      if (inputWord === compWord) { // if the word matches the user inputted word:

        document.getElementById("otpt").innerHTML = "Your word was: " + firstFive[d] + ". I guessed it in " + (d + 1) + " turns.";
        return;

      } else { // if the word is not the user inputted word, then:

        comWords = (inputWord + compWord).split('').sort().join(''); // we combine the users word with the comps word and sort them by character.
        match = comWords.length - comWords.replace(/(\w)\1+/g, '$1').length; // match produces a numerical value for how many letters matched between both words.

        for (let e = 0; e < possWords.length; e++) { // loop to cycle through our dictionary.

          for (let f = 0; f < inputWord.length; f++) { // loop to cycle through all the different match options.

            if (match === 0) { // if there are no matches we can:

              if (possWords[e].includes(firstFive[f])) { // go through the dict and get rid of every word that has letters in common with the word.

                possWords.splice(e, 1);

              }

            } else if (match === f) { // if there's at least one letter in common:

              comWords = (possWords[e] + compWord).split('').sort().join(''); // as we cycle through the dict, pick each available word, combine and sort with the chosen word,
              var matchFive = comWords.length - comWords.replace(/(\w)\1+/g, '$1').length; // and then find how many letters match.

              if (matchFive != match) { // any words in dict that have a different match value can be deleted.

                possWords.splice(e, 1);
              }
            }
          }
        }
      }
    }

    // once we've worked through the words in firstFive[] we start guessing randomly.

    for (let a = 0; a < possWords.length; a++) { // the loop max is set to the length of the array because that's the maximum amount of time the guessing can take.

      compWord = possWords[Math.floor(Math.random() * possWords.length)]; // choose a random word.

      if (compWord === inputWord) { // check if the random word is the inputted word. if it is:

        document.getElementById("otpt").innerHTML = "Your word was: " + compWord + ". I guessed it in " + (a + 5) +  " turns. I had " + possWords.length + " remaining words that were possible matches.";
        return;

      } else { // while the word still isn't correct:

        comWords = (compWord + inputWord).split('').sort().join(''); // again, we join and sort it.
        match = comWords.length - comWords.replace(/(\w)\1+/g, '$1'); // find its match value.

        for (let c = 0; c < inputWord.length; c++) { // loop through inputted word's length to check all letters.

          if (match === 0) { // again, no matches we can safely delete all words with those letters.

            if (possWords.includes(compWord[c])) {
              possWords.splice(c, 1);

            }

          } else if (match === c) { // if match is higher than 0:

            for (let g = 0; g < possWords.length; g++) {

              comWords = (possWords[g]+ compWord).split('').sort().join('');
              matchAll = comWords.length - comWords.replace(/(\w)\1+/g, '$1');

              if (match != matchAll) {

                possWords.splice(g, 1);

              }
            }
          }
        }
      }
    }

      } else { // If the user inputted word was not in our dictionary, requests a different word:

    document.getElementById("otpt").innerHTML = "Please choose a different word.";

      }
    }

(Для контекста dictFiveявляется массивом, расположенным в отдельном файле.) Код пытается угадать введенное пользователем слово, проверяя, сколько букв совпадают, а затем выделяя слова из основного массива, если они не могут совпадать, поэтому массив possWords начинается примерно с 2500слова и сужается до нескольких сотен к концу функции.Насколько я могу судить, функция должна правильно перезагружать переменные каждый раз, когда она вызывается, но я предполагаю, что это не по какой-то причине?

1 Ответ

0 голосов
/ 12 июня 2018

Ваш массив dictFive используется splice d каждый раз, когда вызывается функция.

Когда вы устанавливаете possWords = dictFive, а затем соединяете possWords позже, вы также соединяете dictFiveпотому что обе переменные ссылаются на один и тот же массив.Затем, во второй раз, когда функция запускается, dictFive все еще находится в своем соединенном состоянии.Вместо установки possWords = dictFive, попробуйте сделать копию массива.Таким образом, вы склеите копию, не затрагивая оригинал, dictFive.Вы можете клонировать массив с помощью possWords = dictFive.slice().

var dictFive = [0,1,2,3,4]; // Just an example of whatever dictFive might be
var possWords = dictFive; // This makes possWords refer to the same thing as dictFive
possWords.splice(0, 1); // Splicing the array at whatever point
possWords // [1,2,3,4] because the 0th element was spliced out
dictFive // also [1,2,3,4] because both dictFive and possWords are the same array

и сравните его с

var dictFive = [0,1,2,3,4];
var possWords = dictFive.slice(); // This makes a copy of the array instead of referencing the original dictFive
possWords.splice(0, 1);
possWords // [1,2,3,4];
dictFive // Now, this array is still [0,1,2,3,4] because only the possWords array was spliced. dictFive wasn't affected.
...