2015-09-01 2 views
0

Я изучаю JS самостоятельно, используя codecademy.com, и одной задачей было сделать игру JS rock, paper, scissors. В конце он попросил некоторые улучшения, например, если бы это была связь, как бы вы сделали это там, где вы могли бы выбрать снова, и если у пользователя была неверная запись, как бы вы справились с этой проблемой.Функция функции функции обновления с функцией

Следующая игра JS, довольно маленькая. Мне просто нужна помощь в том, как заставить первую операцию if в моей функции правильно работать, правильно проверив первый параметр и, если она недействительна, появится приглашение, которое обновляет параметр без ущерба для второго. а затем повторно запустите функцию. Мои операторы «ИЛИ», похоже, тоже не работают.

Также я хотел бы знать, есть ли более чистый/лучший способ написать мой второй оператор if. Он отлично работает, мне просто интересно, есть ли лучший способ.

Благодарим за помощь!

var userChoice = prompt("Do you choose rock, paper or scissors?"); 
var computerChoice = Math.random(); 
if (computerChoice < 0.34) { 
    computerChoice = "rock"; 
} else if(computerChoice <= 0.67) { 
    computerChoice = "paper"; 
} else { 
    computerChoice = "scissors"; 
} console.log("Computer: " + computerChoice); 

var compare = function (choice1, choice2){ 

    if (choice1 !== "rock" || "scissors" || "paper"){ 
     choice1 = prompt("Invalid entry, please reenter")} 

    if (choice1 === choice2){ 
     var userChoice = prompt("Tie! Choose Again!"); 
     var computerChoice = Math.random(); 
     if (computerChoice < 0.34) { 
       computerChoice = "rock"; 
      } else if(computerChoice <= 0.67) { 
       computerChoice = "paper"; 
      } else { 
       computerChoice = "scissors"; 
      } console.log("Computer: " + computerChoice); 
    compare(userChoice, computerChoice); 


    } else if (choice1 === "rock"){ 

     if(choice2 === "scissors"){ 
     return "rock wins"; 
     }else{ 
      return "Paper wins"}; 
    } else if (choice1 === "paper"){ 
     if (choice2 === "rock"){ 
      return "paper wins"; 
     }else { 
      return "scissors win"} 
    } else if (choice1 === "scissors"){ 
     if (choice2 === "rock"){ 
      return "rock wins" 
     }else { 
      return "scissors wins"} 
    }; 
}; 
compare(userChoice, computerChoice); 

ответ

1

У вас неправильная логика того, что вы пытаетесь сделать.

Вы должны изменить первую строку, если заявление на:

if (choice1 !== "rock" || choice1 !== "scissors" || choice1 !== "paper"){ 

В качестве альтернативы:

var options = ["rock", "scissors", "paper"]; 
if (options.indexOf(choice1)==-1){ 
+0

Спасибо, что упрется мой или оператора. Теперь, как мне нужно, чтобы функция обновляла первый параметр и повторно запускала функцию без изменения второго. –

1

Я сделал немного fiddle для вас. Взгляните на этот код:

var validChoices = ['rock', 'paper', 'scissors']; 
if (validChoices.indexOf(choice1) == -1){ 
    hoice1 = prompt("Invalid entry, please reenter") 
    compare(choice1, choice2); 
} 

Сначала вы говорите, какие варианты действительны. Если пользователь не дал ни одного из них, попросите его снова сделать выбор, и снова вызовите вашу функцию с новым, выбранным пользователем choice1.

О Ты, если условие: то, что вы сделали это следующее, либо:

  • Choice1 является рок

  • "ножницы" истинно

  • "бумага" верно

Поскольку javascript слабо типизирован, строка истинна. Чтобы сравнить это правильно с тем, как вы хотели, взгляните на ответ Curts.

+0

Я понимаю все, что происходит в отрывках, которые вы, ребята, дали, кроме одной части. После .indexOf(), что делает «> = 0» и «== - 1». –

+1

'Array.indexOf (value)' дает вам позицию, в которой значение 'value' найдено в массиве. Он возвращает -1, если 'значение' не найдено. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf –

+1

Большое спасибо очень информативно. Я обязательно буду принимать это знание со мной, когда буду идти вперед с моей работой. –

1

Поскольку второе приглашение должно было бы снова проверить, рекомендуется объединить проверки в цикле или внешней функции. например .:

var options = ['rock', 'paper', 'scissors']; 

function getUserInput(){ 
    var txt= "Do you choose rock, paper or scissors?"; 
    while(true){ //loop until valid input or cancelled 
     var res = prompt(txt); 
     if(res==null)return null; //user cancelled 
     var ind = options.indexOf(res.toLowerCase()); //alter input (in this case only tolowercase, but you could add trimming and such) 
     if(ind >=0) return options[ind]; //if valid, return the stored value to be able to have the same value for comparison. You could choose to work with the indices too 
     txt = "Invalid entry, please reenter"; 
    } 
} 

Это также выполняет toLowerCase на входе, поэтому вход как «Rock» или «ROCK» будет действительным тоже.

Для дальнейшего избежать синтаксических расхождений, можно повторно использовать массив опций для ввода в компьютер с чем-то вроде

var computerChoice = options[ Math.floor(Math.random() * 3)]; 

это будет использовать строки в опционных массивов. Math.floor(Math.random() * 3) будет генерировать целое число 0,1 или 2 с той же вероятностью, что и < 0,34 и т. Д.сравнения.


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

var options = ['rock', 'scissors', 'paper']; //ordered such that each value beats the next value (where the last value beats the first) 

function getUserInput(txt){ 
    while(true){ //loop until valid input or cancelled 
     var res = prompt(txt || "Do you choose rock, paper or scissors?"); //prompt with a pre defined text or the default text (|| makes sure undefined is replaced with the right hand value) 
     if(res==null)return null; //user cancelled 
     var ind = options.indexOf(res.toLowerCase()); //alter input (in this case only tolowercase, but you could add trimming and such) 
     if(ind >=0) return ind; //if valid, return the index 
     txt = "Invalid entry, please reenter"; 
    } 
} 


function runGame(promptText){ 
    var userChoice = getUserInput(promptText); 
    if(userChoice===null)return; //user cancelled 
    var computerChoice = Math.floor(Math.random() * 3); //generates a random number of 0,1 or 2 
    console.log("Computer: " + options[computerChoice]); 

    if(userChoice === computerChoice) 
     return runGame("Tie! Choose Again!"); //in case of Tie, start over with the prompText of Tie 

    if(userChoice === (computerChoice + 1) % 3) //the next value: +1 the % 3 (modulo 3) returns the remainder if the '+1' value is divided by 3 and thus turns 3 into 0 
     return options[computerChoice] + ' beats ' + options[userChoice] + ' (Computer wins)';   
    return options[userChoice] + ' beats ' + options[computerChoice] + ' (User wins)';   

} 

var res = runGame(); 
if(res) 
    alert(res); 

Fiddle

+0

Очень хороший ответ, хотя я почти рак глаз из-за всех однострочных-ifs ;-) –

+1

Спасибо. ха-ха, что я могу сказать, я люблю один лайнер. Но особенно для случая вариант с как можно меньшим количеством ifs: http://jsfiddle.net/75f3hovc/4/ –

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