如何多次替换数组元素?

时间:2018-11-18 20:18:32

标签: javascript node.js npm inquirer

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);

    }
});

我使用构造函数构建了一个hang子手游戏。我已经设置好了,所以当选择一个随机单词时,每个字母都将显示为下划线。
我使用了询价包来要求一封信。当正确猜出第一个字母时,它将成功地用liveWord数组中的字母替换下划线。问题是,它只适用于一个字母。我需要使它起作用,直到猜出整个单词为止。仅供参考,文件1和2仅供参考,我的问题仅在文件3中。无需查看前2个。有什么提示吗?

2 个答案:

答案 0 :(得分:1)

我不会在代码中为您提供帮助,调试,重写某人的代码(尤其是很长的代码)很烦人。

但是我给你一个例子:

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 :(得分:1)

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

  1. letterTest方法中,如果猜测与字母不同,则将letter属性设置为下划线。这是错误的,因为那样您将永远不会再知道正确的字母是什么。删除它。拥有guess属性的正确值就足够了

  2. stringRep方法中,您在循环中引用变量eachLetter,该变量与此无关。相反,您应该使用this.splitWord[i]

  3. 没有循环允许用户进行第二次猜测,因此这是正常现象,它只能运行一次。需要有一个循环来减小变量remainingGuesses的值,您到目前为止还没有使用过。

  4. 您不应显示splitWord。这与第1点有关。相反,您应该显示stringRep(),其中要考虑到是否已经基于guessed属性猜到了字母。这正是您需要输出的内容。

  5. 缺少检测到是否完全找到该单词的逻辑。在这种情况下,一条消息将是适当的,并且应该中断猜测周期(未实现)。

为便于循环,我建议使用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>