2015-08-17 3 views
1

(У переполнения стека нет тега для подсказки, поэтому я использовал предупреждение, поскольку я предполагаю, что он достаточно похож, чтобы привлечь правильных ответчиков.)Заполнение приглашения элементами массива и их номером

Hello, В настоящее время я делаю JavaScript-игру для обучения в университете. Обычно я хорошо разбираюсь в решении проблем, но в этом вопросе эта проблема не увенчалась успехом.

Чтобы объяснить, у меня есть массив, который называет возможные доспехи, которые игрок может выбрать. В любом порядке они могут быть выбраны, и каждый раз выбор переходит к второму массиву, который обрабатывает то, что уже было выбрано (и в каком порядке), и этот элемент получает сплайсинг из исходного массива. Существует цикл while, который проходит до тех пор, пока все 3 не будут выбраны.

var armourSlotToPick = ["Head", "Chest", "Legs"],  
    armourSlotPicked = [], 
    armourLoop = 1, 
    indexArmour = 0; 

function numInArray() { 
    indexArmour++; 
    return (indexArmour + ". " + armourSlotToPick[indexArmour - 1] + "\n"); 
} 


function armour() { 
    while (armourLoop < 4) { 
     var armourPick = prompt("Pick an armour slot to generate an item for:\n" + armourSlotToPick.forEach(numInArray)); 
     if (armourPick == 1) { 
      armourSlotPicked.push(armourSlotToPick[0]); 
      armourSlotToPick.splice(0,1); 
     } else if (armourPick == 2) { 
      armourSlotPicked.push(armourSlotToPick[1]); 
      armourSlotToPick.splice(1,1); 
     } else if (armourPick == 3) { 
      armourSlotPicked.push(armourSlotToPick[2]); 
      armourSlotToPick.splice(2,1); 
     } else { 
      alert("Invalid choice, you suck"); 
      break; 
     } 
     armourLoop++; 
    } 
} 

Я знаю, что это, вероятно, не было бы возможно сделать все возвращение в numInArray() в командной строке, но он показывает некоторую работу.

Теперь проблема: я получил ее, чтобы каждый элемент массива был пронумерован (var armourSlotToPick = ["1. Head", "2. Chest", "3. Legs"],), но, как вы могли если игрок выбрал 2, то в следующий раз он покажет «1. Голова (новая линия) 3. Ноги», и когда игрок выберет 3, возникнет проблема, поскольку они действительно должны были выбрать 2. Как возможно ли число элементов в массиве, в подсказке?

Я, возможно, подумал об этом, но я страдал уже несколько часов.

Я заранее благодарю Вас за любой проницательности вы можете иметь,

Даниила.


EDIT: Solved.

Ниже приводится конечный результат, небольшое отклонение от отредактированного ответа Джонатана Брукса.

var armourSlotToPick = [null, "Head", "Chest", "Legs"] 
var armourSlotPicked = [null]; 
var armourLoop = 1; 

function armour() { 
    while (armourLoop < 4) { 
     var message = "Pick an armour slot to generate an item for:\n"; 
     for (var i = 0; i < armourSlotToPick.length; i++) { 
      if (armourSlotToPick[i] !== null) { 
       message += "" + i + ". " + armourSlotToPick[i] + "\n"; 
      }    
     } 
     var armourPick = prompt(message); 
     if (armourPick > armourSlotToPick.length-1 || armourPick < 1) { 
      alert("Invalid choice, you suck"); 
     } else { 
      var insert = armourSlotToPick.splice(armourPick, 1); 
      armourSlotPicked.push(insert); 
     } 
     armourLoop++; 
    } 
    armourSlotPicked.splice(0,1); 
} 

armour(); 
alert(armourSlotPicked.join("\n")); 

Я благодарю всех, что внесли свой вклад в эту дискуссию и конечный результат, и я надеюсь, что это является хорошим примером для будущих проблем, которые люди могут иметь похожее на это.

ответ

1

Проверьте мой fiddle, я думаю, у меня есть рабочее решение.

То, что вы действительно хотите использовать, это Object Literals с вашим собственным индексированием (начиная с 1) - если бы это был я, я бы создал свой собственный путь для повторения этой пользовательской индексации путем добавления метода к прототипу объекта, но я отвлекся.

Вы усложнять свой код, используя while петли, и что большая масса if утверждений не является необходимой: вместо этого, все, что вам нужно, это некоторые основные проверок на входе, а затем вы можете просто доверять любой вход передает эту проверку. Это показано здесь:

if (armourPick > armourSlotToPick.length || armourPick < 1) { 
    alert("Invalid choice, you suck"); 
} 
else { 
    armourSlotPicked.push(armourSlotToPick[armourPick-1]) 
    alert (armourSlotPicked[armourSlotPicked.length-1].value); 
} 

Внимательно прочитайте мой код, и вы должны лучше понять, как справляться с определенными проблемами.

EDIT:

По вашему желанию, я думаю, что у меня есть решение, которое соответствует вашим потребностям. В основном все, что вам нужно сделать, чтобы иметь массивы «начать» с индексом 1, чтобы заполнить нулевой элемент со значением null, например, так:

var armourSlotToPick = [null, "Head", "Chest", "Legs"] 
var armourSlotPicked = [null]; 

Вы просто должны помнить, чтобы принять этот null объект в в вашем коде, например:

if (armourSlotToPick[i] !== null) { 
    message += "" + i + "\n"; 
} 

Индексы будут обновляться автоматически. См. Это updated fiddle для более подробной информации.

+0

Спасибо за это, да, я понимаю, как справиться с этими проблемами сейчас, есть только 1 проблема, с которой я сталкиваюсь, «ключ» по-прежнему жестко привязан к «значению», как в случае, когда я делаю это три раза, один раз за каждый раз, когда игрок выбирает следующий слот брони, 2 всегда будет сундуком, а 3 всегда будут ногами. Я хочу, чтобы это динамически менялось, поэтому после первого выбора оставшиеся 2 теперь являются клавишами 1 и 2, а не, скажем, клавишей 2 и клавишей 3 (для сундуков и ног). Я предполагаю, что это возможно. –

+0

@ DanielJochem Проверьте мои изменения –

+0

Спасибо @JonathanBrooks, я закончил использовать отредактированный ответ, так как я действительно хотел сохранить подсказку, которую Хенрик рекомендовал мне не делать. Благодарим вас за терпение. –

1

использовать структуры/объекты как содержимое в массиве, а не просто значения.

основная концепция:

armourSlotPicked.push({ "key": 1, "value":armourSlotToPick[1]}) 
alert("value: " + armourSlotPicked[0].value) 
alert("key: " + armourSlotPicked[0].key) 

редактировать: отвечать на комментарии может занять некоторое пространство.

IMHO - это совершенно неправильный инструмент для этого, так как большинство браузеров спрашивают у пользователя разрешение на предотвращение множественных всплывающих окон, а так как promt может только вернуть 1 часть информации, вы можете запросить только 1 штуку за всплывающее окно , Вместо этого вы должны использовать элемент div, с флажками для каждой информации.

Это, как говорится, можно легко использовать в промте. Запрос - это просто встроенная функция, которая принимает строку в качестве аргумента (которая отображается как текст во всплывающем окне) и возвращает строку с вводом пользователей.

Что для вас на самом деле волшебство: array.foreach(): Метод forEach() выполняет предоставленную функцию один раз для элемента массива.

В вашем случае это означает, что он вызывает функцию, которая возвращает строку для каждого элемента в массиве и объединяет строки.

в старые времена, вы написали бы это:

var messageText= "Pick an armour slot to generate an item for:\n" 
for(var i = 1; i < armourSlotToPick.length; i++){ 
    messageText += i + ". " + armourSlotToPick[i- 1] + "\n"; 
} 
var armourPick = prompt(messageText); 

, но в наше время, вы определяете функцию печати, и использовать его для создания цикла:

function numInArray() { 
    indexArmour++; 
    return (indexArmour + ". " + armourSlotToPick[indexArmour - 1] + "\n"); 
} 

//more code before we get to where the function is used.... 

indexArmour = 0; 
var messageText = "Pick an armour slot to generate an item for:\n" + armourSlotToPick.forEach(numInArray); 
var armourPick = prompt(messageText); 

или в одна строка, как в вашем коде: indexArmour = 0; // вы забыли это - иначе список будет только один раз? var armourPick = prompt («Выберите слот брони, чтобы сгенерировать элемент для: \ n" + armourSlotToPick.forEach (numInArray));

Он производит тот же результат, потому что он делает то же самое, его просто написано совсем по-другому!

Если массив содержит «литералов объектов» вместо просто значений, как я предлагаю, старомодный код будет выглядеть примерно так:

function contains(a, value) { 
    try{ 
     for (var i = 0; i < a.length; i++) { 
      if (a[i].value == value) { 
       return true; 
      } 
     } 
    } 
    catch(err) { 
     // do nothing 
    }; 
    return false; 
} 

и позже ..

for(var j = 0; j < 4; j++){ 
    for(var i = 0; i < Math.min(armourSlotToPick.length); i++){ 
     if(contains(armourSlotPicked, armourSlotToPick[i- 1])) 

продолжить ; var messageText = "Создать элемент для брони в слоте:" + i + "\ n" messageText + = armourSlotToPick [i-1] + "\ n"; }

var armourPick = prompt(messageText); 
    if (armourPick > 0 && armourPick < armourSlotToPick.length) { 
     armourSlotPicked.push({"key":j, "value":armourSlotToPick[armourPick]); 
    } 
    ... 
} 
//now we have an array that holds information about when what was picked.. 

или что-то вдоль этих линий .. это bt.w совершенно непроверенные, это просто для иллюстрации

+0

Точно. Объектные литералы гораздо лучше подходят для этой проблемы –

+0

Так что это можно легко использовать в подсказке? Как это произойдет? –

+0

@ Хенрик, я так благодарен вам за ваши усилия в этом ответе, вы указали некоторые из моих слабых подходов к ситуации, и я возьму на себя то, что вы указали, чтобы помочь мне улучшить свой курс в университете. Как я сказал Джонатану, я действительно хотел сохранить подсказку, мне нужно только каждый раз возвращать 1 часть информации, она также показывает моему преподавателю в университете, что я могу выделить элементы и прокрутить их до тех пор, пока все не будут учтены , Ваши ответы будут полезны для будущих проблем, которые могут иметь люди, и я признаю, что это лучший подход. –

0

Вы хотите использовать индекс массива пронумеровать ваши вопросы. Поскольку ваши номера однонаправлены, а индекс основан на нуле, вам нужно будет преобразовать их между двумя при выводе и интерпретации ответа.

Этот подход также позволит вам устранить все, кроме двух случаев, в вашем заявлении if-else.

Смежные вопросы