如何多次替换数组元素?

How can i replace an array element multiple times?

console.log("Start file 1 =========================================");
function Letter (letter) {

    this.letter = letter;
    this.guess = false;
    this.answer = function () {
        if (!this.guess) {
            return "_";
        }
        else if (this.guess === true) {
            return this.letter;
        }
    }
    this.letterTest = function (guessed) {
        if (guessed === this.letter) {
            this.guess = true;
            // this.letter = guessed;
        } else {
            this.letter = "_";
        }
    }
};

module.exports = Letter;
console.log("End file 1 =========================================");


console.log("Start file 2 =========================================");
var Letter = require("./letter.js");

function Word (word) { 

    this.splitWord = [];
    for (var i = 0; i < word.length; i++) { 
        var eachLetter = new Letter (word[i]);
        this.splitWord.push(eachLetter);
    }

    this.stringRep = function () {
        var testedWord = [];
        for (var i = 0; i < this.splitWord.length; i++) {
            testedWord.push(eachLetter.answer());
        }

        testedWord = testedWord.join(" ");

        // console.log(testedWord);
        return testedWord;

};

    this.eachGuess = function (input) {
        for (var i = 0; i < this.splitWord.length; i++) {

            this.splitWord[i].letterTest(input);
        }
        }    
}

module.exports = Word;
console.log("End file 2 =========================================");


console.log("Start file 3 =========================================");
var Word = require("./word.js");
var inquirer = require('inquirer');

var remainingGuesses = 10;
var mainGame;
var currentWord;
var liveWord = [];
completeWord = null;
let countryPicker;
let testedWord;

var europe = ["Albania", "Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Denmark", "England", "France", "Greece", "Germany",
"Hungary", "Iceland", "Italy", "Lithuania", "Monaco", "Norway", "Poland", "Portugal", "Romania", "Serbia", "Slovakia", "Spain", "Sweden",
"Switzerland", "Ukraine"];

// Function that picks a random country
function pickCountry () {
    countryPicker = europe[Math.floor((Math.random() * europe.length) + 1)];
    var mainGame2 = new Word (countryPicker);
    mainGame = mainGame2;
    // Display word

    currentWord = mainGame.stringRep();
    currentWord = JSON.stringify(currentWord);
    console.log("Word: " + currentWord);
};

pickCountry();
// Delete this after
console.log("1: " + countryPicker);
console.log("2: " + currentWord);

inquirer.prompt([
    {
        type: "input",
        name: "game",
        message: "Guess a letter!"
    }
]).then(function(inquirerResponse) {
        liveWord = mainGame.splitWord;
        mainGame.eachGuess(inquirerResponse.game);

    for (let i = 0; i < liveWord.length; i++) {

        console.log(mainGame.splitWord[i].letter);

    }
});

我使用构造函数构建了一个刽子手游戏。 I have set it up so when a random word is chosen, each letter will be displayed as an underscore.
我用inquirer包要了一封信。当第一个字母被猜对时,它成功地将下划线替换为 liveWord 数组中的字母。问题是,它只适用于一个字母。我需要让它工作,直到猜出完整的单词。仅供参考,文件 1 和 2 仅供参考,我的问题仅在文件 3 中。无需查看前 2 个。有什么提示吗?

我不会帮你解决你问题中的代码问题,调试、重写别人的代码(尤其是很长的代码)很烦人。

但是我给你举个例子:

const words = [
  'Azerbaijan', 'America', 'blablabla', 'Argentina', 'lambada', 'Australia', 'schmetterling', 'krankenwagen', 'kugelschreiber'
];

let word, result, charIndexes;

const start = () => {
  word = words[parseInt(Math.random()*words.length)];
  charIndexes = {};
  result = new Array(word.length+1).join('_');

  word.split('').forEach((char, i) => {
    char = char.toLowerCase();
    if (!charIndexes[char]) charIndexes[char] = []
    charIndexes[char].push(i);
  });
  
  info.innerHTML = '';
  output.innerHTML = result;
  input.focus();
};

const checkChar = (char) => {
  result = result.split('');
  if (charIndexes[char]) {
    const indexes = charIndexes[char];
    indexes.forEach(i => {
      result[i] = word.charAt(i);
    });
    delete charIndexes[char];
  }
  result = result.join('');
  output.innerHTML = result;
  if (Object.keys(charIndexes).length === 0) {
    info.innerHTML = 'Congratulations!';
  }
};

const input = document.getElementById('letter');
const output = document.getElementById('word');
const info = document.getElementById('info');

input.onkeyup = (e) => {
  const char = e.key.toLowerCase();
  input.value = '';
  checkChar(char);
};

start();
<input type="text" id="letter" value=""> 
<button onclick="start()">reset</button>
<br/><br/>
<div id="word"></div>
<div id="info"></div>

您的代码中存在几个问题:

  1. letterTest 方法中,当猜测与字母不同时,您将 letter 属性 设置为下划线。这是错误的,因为那样你就再也不知道正确的字母是什么了。删除这个。 guess 属性

  2. 的正确值就足够了
  3. stringRep 方法中,您在循环中引用变量 eachLetter,这与此处无关。相反,您应该使用 this.splitWord[i].

  4. 没有让用户进行二次猜测的循环,因此只能正常工作一次。需要有一个循环来减少您的变量 remainingGuesses 的值,您目前还没有使用它。

  5. 你不应该显示 splitWord。这与第 1 点有关。相反,您应该显示 stringRep(),它考虑到字母是否已根据 guessed 属性 猜出。这正是您需要输出的内容。

  6. 缺少检测单词是否被完整找到的逻辑。在那种情况下,一条消息是合适的,猜测循环(未实现)应该被中断。

为了便于循环,我建议使用 async/await 语法来处理 inquirer 返回的承诺。

这是您的代码,上面列出的点已更正。为了使其在此代码段小部件中可运行,我没有像您那样将其拆分为模块,也没有包含 inquirer (我将其简化为内联替换)。

我也没有尝试做很多其他的改进,所以你仍然可以认可你自己的作品。所有更改均已评论:

function Letter (letter) {
    this.letter = letter;
    this.guess = false;
    this.answer = function () {
        if (!this.guess) {
            return "_";
        }
        else { // No need to check whether this.guess is true here. It is the logical consequence...
            return this.letter;
        }
    }
    this.letterTest = function (guessed) {
        if (guessed === this.letter) {
            this.guess = true;
        }
        // Don't change this.letter, as you will forever forget what the correct letter is!
        // (code was deleted from here)
    }
}

function Word (word) { 
    this.splitWord = [];
    for (var i = 0; i < word.length; i++) { 
        var eachLetter = new Letter (word[i]);
        this.splitWord.push(eachLetter);
    }
    this.stringRep = function () {
        var testedWord = [];
        for (var i = 0; i < this.splitWord.length; i++) {
            // Don't push eachLetter, but use the i-variable as index! 
            testedWord.push(this.splitWord[i].answer());
        }
        testedWord = testedWord.join(" ");
        return testedWord;
    }

    this.eachGuess = function (input) {
        for (var i = 0; i < this.splitWord.length; i++) {
            this.splitWord[i].letterTest(input);
        }
    }    
}

// Simplified implementation of inquirer for this snippet only:
var inquirer = {
    prompt([{type, name, message}]) {
        return new Promise((resolve) => {
            const input = document.querySelector(`[name=${name}]`);
            input.value = "";
            input.placeholder = message;
            input.onchange = e => resolve({ [name]: input.value });
        });
    }
}

var remainingGuesses = 10;
var mainGame;
var currentWord;
var liveWord = [];
completeWord = null;
let countryPicker;
let testedWord;

var europe = ["Albania", "Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Denmark", "England", "France", "Greece", "Germany",
"Hungary", "Iceland", "Italy", "Lithuania", "Monaco", "Norway", "Poland", "Portugal", "Romania", "Serbia", "Slovakia", "Spain", "Sweden",
"Switzerland", "Ukraine"];

function pickCountry () {
    countryPicker = europe[Math.floor((Math.random() * europe.length) + 1)];
    var mainGame2 = new Word (countryPicker);
    mainGame = mainGame2;
    currentWord = mainGame.stringRep();
    currentWord = JSON.stringify(currentWord);
    console.log("Word: " + currentWord);
}

pickCountry();
// Delete this after
console.log("1: " + countryPicker);
console.log("2: " + currentWord);

(async function () { // Use an async function to allow the use of AWAIT
    while (remainingGuesses--) { // You need a loop to repeat guess/response cycle
        // Use AWAIT -- simpler to use than THEN
        const inquirerResponse = await inquirer.prompt([{
            type: "input",
            name: "game",
            message: "Guess a letter!"
        }]);
        const liveWord = mainGame.splitWord;
        mainGame.eachGuess(inquirerResponse.game);
        // Don't display splitWord here, but stringRep:
        const output = mainGame.stringRep();
        console.log(output);
        // Detect that the word has been found, and exit if so
        if (!output.includes("_")) {
            console.log("You found it!");
            return;
        }
    }
    // The maximum number of guesses was not enough to find the word
    console.log('What a pity. You ran out of guesses.');
})();
Letter: 
<input name="game">
<button>Guess</button>