Если / Else / Switch возвращает неправильные результаты

Я делаю Rock-Paper-Scissors-Lizard-Spock (Теория Большого Взрыва, телешоу) с использованием ReactJS, и я сталкиваюсь с какой-то абстрактной проблемой.

switch (this.state.playerOnePick === 'Rock') {
    case((this.state.playerTwoPick === 'Scissors') || (this.state.playerTwoPick === 'Lizard')):
    return (
        <div>
            <h1>Player One wins !</h1>
            <h2>P1: {this.state.playerOnePick} P2: {this.state.playerTwoPick}</h2>
        </div>
    );
        break;
    case((this.state.playerTwoPick === 'Paper') || (this.state.playerTwoPick === 'Spock')):
        return (
            <div>
                <h1>Player Two wins !</h1>
                <h2>P1: {this.state.playerOnePick}
                    P2: {this.state.playerTwoPick}</h2>
            </div>
        );
        break;

}

switch (this.state.playerOnePick === 'Lizard') {
    case((this.state.playerTwoPick === 'Spock') || (this.state.playerTwoPick === 'Paper')):
        return (
            <div>
                <h1>Player One wins !</h1>
                <h2>P1: {this.state.playerOnePick} P2: {this.state.playerTwoPick}</h2>
            </div>

        );
        break;
    case((this.state.playerTwoPick === 'Scissors') || (this.state.playerTwoPick === 'Rock')):
        return (
            <div>
                <h1>Player Two wins !</h1>
                <h2>P1: {this.state.playerOnePick} P2: {this.state.playerTwoPick}</h2>
            </div>
        );
        break;

}

Рок против бумаги возвращает правильные результаты, независимо от того, кто их выбирает, когда P1: Рок, P2: Ящерица, P1 выигрывает, как и ожидалось, но когда P1: Ящерица P2: Рок, он возвращает, что P1 выигрывает..

Что он мне возвращает, когда P1: Lizard P2: Rock

Там нигде, где ящерица должна победить рок...

(playerOnePick и playerTwoPick корректно обновляются, когда игрок выбирает оружие)

3 ответа

Правильное использование switch заявления будут

switch (this.state.playerOnePick) {
    case 'Rock':
        switch (this.state.playerTwoPick) {
            case 'Scissors'):
            case 'Lizard':
                return "Player One wins!";
                break; // unnecessary after `return` but well
            case 'Paper':
            case 'Spock':
                return "Player Two wins!";
                break; // as above
        }
        break;
    case 'Lizard':
        switch (this.state.playerTwoPick) {
            case 'Spock':
            case 'Paper':
                return "Player One wins!"
            case 'Scissors':
            case 'Rock':
                return "Player Two wins!";
        }
        break;
}

То, что вы показали, это макет для if/elseс большим количеством логических условий:

if (this.state.playerOnePick === 'Rock') {
    if ((this.state.playerTwoPick === 'Scissors') || (this.state.playerTwoPick === 'Lizard')) {
        return "Player One wins!";
    } else if ((this.state.playerTwoPick === 'Paper') || (this.state.playerTwoPick === 'Spock')) {
        return "Player Two wins!";
    }
} else if (this.state.playerOnePick === 'Lizard') {
    if ((this.state.playerTwoPick === 'Spock') || (this.state.playerTwoPick === 'Paper')) {
        return "Player One wins!";
    } else if ((this.state.playerTwoPick === 'Scissors') || (this.state.playerTwoPick === 'Rock')) {
        return "Player Two wins!";
    }
}

Однако реальная проблема с реализацией Rock-Paper-Scissors-Lizard-Spock - все это дублирование (которое оставляет много места для ошибок). Фактическая задача программирования - выяснить, как уменьшить это.
Совет: назначьте каждому возможному выбору целое число и поиграйте с некоторыми математическими задачами.
Написать отдельную функцию winner(pick1, pick2) это возвращает -1 когда первый игрок выигрывает, 0 за галстук и 1 когда второй игрок выигрывает. Затем просто вызовите это из кода ReactJS, который связан с пользовательским интерфейсом.

Дело переключения не работает так. Если вы хотите использовать переключатель, вы должны сделать что-то вроде:

switch(playerOnePick) {
 case 'Rock':
   switch(playerTwoPick) {
    case 'Scissors':
    case 'Lizard':
      // Player 1 wins
      break;
    case 'Paper':
    case 'Spock':
    // Player 2 wins
    break;
   }
   break;
 case 'Lizard':
   switch(playerTwoPick) {
    case 'Spock':
    case 'Paper': 
      // Player 1 wins
     break;
    case 'Scissors':
    case 'Rock': 
    // Player 2 wins
    break;
 }
}

и т.п.

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

Это потому, что вы так настроили. посмотри наконец<h1>,

Скажем, вы могли бы написать лучше switch/case заявление для оценки состояния. Вы сильно повторяете себя, что против СУХОГО (не повторяйте себя) принципала.

Вы можете тянуть <h2>P1: {this.state.playerOnePick} P2: {this.state.playerTwoPick}</h2> полностью из switch заблокировать и разместить сразу после включения выключателя }, Или лучше указать только одно значение для каждого случая, а не объединять пару из них в один случай. Это усложняет соблюдение кода. Это мой выбор для этого конкретного случая переключения:

switch (this.state.playerOnePick === 'Rock') {
    case(this.state.playerTwoPick === 'Scissors'):
         return ( <div> <h1>Player One wins !</h1> </div>);
         break;
    case(this.state.playerTwoPick === 'Lizard')):
         return ( <div> <h1>Player One wins !</h1> </div>);
         break;
    case(this.state.playerTwoPick === 'Paper'):
         return ( <div> <h1>Player Two wins !</h1> </div>);          
         break;
    case(this.state.playerTwoPick === 'Spock'):
         return ( <div> <h1>Player Twi wins !</h1> </div>);        
         break;
    }
// The same goes for second switch
<div><h2>P1: {this.state.playerOnePick} P2:{this.state.playerTwoPick}</h2><div>
Другие вопросы по тегам