У меня возникли проблемы с запуском этой программы на javascript

#javascript

#javascript

Вопрос:

Каждый раз, когда я запускаю программу и ввожу номер стопки и круга, я получаю ошибку «TypeError: piles [выбор стопки] не определен». Я несколько раз пытался отладить ее, но все еще не могу заставить ее функционировать должным образом.

 var piles = [
  {name: 'Pile A', circles: 'ooooo'},
  {name: 'Pile B', circles: 'ooooo'},
  {name: 'Pile C', circles: 'ooooo'}
];

function boardPrint(){
  console.log("NIM");
  for(var i = 0; i < piles.length; i  ) {
    console.log(piles[i].name   ": "   piles[i].circles);
  }
}

function getUserInput(){
  return prompt("Enter the letter for the pile (A-C) and the number of stones you want to remove (1-5). Example: A3").toLowerCase();
}

function userMove(){
  var pileIdx = 0;
  var valid = false;
  var numToRemove = 0;

  while(!valid) {
    var gameIns = getUserInput(); // This will now get called multiple times until user enters valid input
    var pileChoice = gameIns[0]; // This makes 'A' turn into 'a', which makes further logic easier.

    // I rebuilt this part of the function to be a bit cleaner and to show you how switch statements could be used
    switch(pileChoice){
      case 'a':
      pileIdx = 0;
      valid = true;
      break;
      case 'b':
      pileIdx = 1;
      valid = true;
      break;
      case 'c':
      pileIdx = 2;
      valid = true;
      break;
      default:
      alert('Error! Invalid input.');
    }
    numToRemove = Math.min(gameIns[1],piles[pileChoice].circles.length); // This way, they can't select a number that is greater than the number remaining in the pile.
  }

  piles[pileIdx].circles = piles[pileIdx].circles.slice(numToRemove);
}

function computerMove(move){
  // Task 1: pick a pile

  var pileIdx = 0;

  if(piles[0].circles.length > 0) { // tests for whether there are circles left in pile A
    piles[0].circles = piles[0].circles.slice(pileIdx);  // do something

  } else if(piles[1].circles.length > 0) {
    piles[1].circles = piles[1].circles.slice(pileIdx);  // do something

  } else if(piles[2].circles.length > 0) {
    piles[2].circles = piles[2].circles.slice(pileIdx);  // do something
  }

  // Task 2: pick a number to remove from the pile

  // Optional: see how many piles are left and base your number to remove on that
  //var pilesCount = 0;

  // [some logic for counting piles]

  // Otherwise, just remove all that are remaining from a pile
  //var numToRemove = 0;

  if (pilesCount > 1){
    // select a number to remove
  }
  else {
    // select another number to remove
  }

  piles[pileIdx].circles = piles[pileIdx].circles.slice(numToRemove);
}

while(true) {
  boardPrint();
  userMove();

  if (boardEmpty() === true) {
    boardPrint();
    console.log("You win!");
    break;
  }

  boardPrint();
  computerMove();

  if (boardEmpty() === true) {
    boardPrint();
    console.log("Computer wins!");
    break;
  }
}

function boardEmpty() {
  // Check if the board is empty
}
  

Комментарии:

1. gameIns[0] просто выдал бы вам первый символ prompt() ответа.

2. prompt() возвращает строку. Когда вы запускаете запись массива в строке, это похоже String.charAt() . Кроме того, в чем смысл numToRemove = Math.min(gameIns[1],piles[pileChoice].circles.length); ? Math.min() Единственным числом будет это число в любом случае.

3. в строке прямо перед piles[pileChoice] add this console.log(pileChoice, piles); Это может помочь вам лучше понять, что происходит не так, и что вам, вероятно, нужно обновить его до piles[pileIdx]

Ответ №1:

В вашей userMove функции в конце цикла while вы пытаетесь установить numToRemove со следующей строкой:

 numToRemove = Math.min(gameIns[1],piles[pileChoice].circles.length); // This way, they can't select a number that is greater than the number remaining in the pile.
  

Но pileschoice — это либо ‘a’, ‘b’, либо ‘c’, верно? Вот почему вы рассчитали pileIdx в своем коммутаторе. Вам нужно использовать ее вместо этого, потому что способ, которым вы определили piles, не может быть проиндексирован с помощью ‘a’, ‘b’ или ‘c’.

Ответ №2:

Я думаю, что проблема здесь:

У вас есть

 var piles = [
  {name: 'Pile A', circles: 'ooooo'},
  {name: 'Pile B', circles: 'ooooo'},
  {name: 'Pile C', circles: 'ooooo'}
];
  

а затем позже

 numToRemove = Math.min(gameIns[1],piles[pileChoice].circles.length);
  

Я думаю, вы имели в виду, что это должно быть piles[pileIdx] ? pileChoice это будет буква, и у вас есть массив объектов, поэтому вам нужно будет получить доступ к правильному с помощью in index.

Ответ №3:

Вы пытаетесь ссылаться на piles[pileChoice] такие ссылки, как piles[‘a’], piles [‘b’] и так далее в gameIns [0], Но массив piles не отформатирован таким образом, потому что piles — это массив объектов.

Вы могли бы попробовать переосмыслить способ моделирования куч или попробовать обходной путь, подобный следующему, для получения кругов.длина:

 // define pileCircleCount
var pileCircleCount;

// go over your piles array
piles.forEach(function(pile) {

 // get the pile name value and retrieve the last char which is A/B/C
 // and convert it to lowercase
 var pileId = pile.name.substr(pile.name.length - 1).toLowerCase();

 // now match it up with the pileChoice, if a match is found get its
 // circle length and set it to the pileCircleCount
 if(pileId === pileChoice) {
   pileCircleCount = pile.circles.length;
 }
});

numToRemove = Math.min(gameIns[1], pileCircleCount);