Застрял в игре Paper-Scissors-Rock - PullRequest
0 голосов
/ 19 февраля 2020

В то время как l oop повторяется два раза каждый раз, а ЦП получает балл только при выборе «S» для ножниц. Другой вопрос, как мне сделать его более простым и куда добавить эту функцию? Я должен использовать символы 'r', 's' и 'p' вместо 1,2,3, чтобы принять пользовательский ввод. Не уверен, как поступить, чтобы исправить это

#include <stdlib.h> 
#include<time.h> 

int main () {

   char player1;
   int player2;
   int userScore = 0, cpuScore = 0;
   player2 = rand ( ) % 3 + 1;
   srand ((int) time (NULL));

int count = 0;
while(count <= 10) {
  printf("\nEnter p for Paper, r for rock, or S for scissor: ");
  scanf("%c", &player1);
   switch(player1) {
      case 'P' :
       if(player1 == 'P' && player2 == 1) {
         printf("Draw!");
         break;
       } else if(player1 == 'P' && player2 == 2) {
         userScore++;
         printf("User won this one!");
         break;
       } else {
         cpuScore++;
         printf("CPU won this one!");
         break;
       }
      case 'R': 
         if(player1 == 'R' && player2 == 2) {
         printf("Draw!");
         break;
       } else if(player1 == 'R' && player2 == 3) {
         userScore++;
         printf("User won this one!");
         break;
       } else {
         cpuScore++;
         printf("CPU won this one!");
         break;
       }
      case 'S':
        if(player1 == 'S' && player2 == 3) {
         printf("Draw!");
         break;
       } else if(player1 == 'S' && player2 == 1) {
         userScore++;
         break;
         printf("User won this one!");
       } else {
         cpuScore++;
         printf("CPU won this one!");
         break;
       }
      default :
         printf("\nInvalid Input");
         break;
   }
   printf("\nUser Score: %d", userScore);
   printf("\nCPU Score: %d", cpuScore);
   count++;
}
   if(userScore == cpuScore) {
     printf("\nDraw game!");
   } else if(userScore > cpuScore) {
     printf("\nYou win!");
   } else {
     printf("\nCPU wins!");
   }
   return 0;
} ``` 

Ответы [ 3 ]

4 голосов
/ 20 февраля 2020

Я предлагаю вам исправить это, я сделаю это гораздо менее сложным. Победитель Rock-Paper-Scisors может быть определен арифметически.

Проще сравнивать подобное для лайка, а использование целочисленных значений позволяет получить более простое арифметическое решение c. Также арифметически проще использовать 0,1,2, а не 1,2,3. Поэтому сначала преобразуйте пользовательский ввод в 0,1,2:

#define INVALID_SELECTION sizeof(rps)
static const char rps[] = {'r', 'p', 's'} ;
int human = INVALID_SELECTION ;

while( human == INVALID_SELECTION )
{
    printf("\nEnter R for Rock, P for Paper, or S for Scissors: ");

    char ch = 0 ;
    scanf("%c", &ch ) ;
    while( ch != '\n' && getchar() != '\n' ) ;

    for( human = 0; 
         human < INVALID_SELECTION && tolower(ch) != rps[human] ; 
         human++ )
    {
        // do nothing
    }
}

Затем следует определить компьютерную игру:

srand( (int)time(NULL) ) ;
int computer = rand() % 3 ;

, хотя обратите внимание, что вам нужен только вызов srand() один раз, так что если вы поместите игру в oop, чтобы повторить игру, вызов srand() должен появиться до повтор l oop.

Затем вы можете сообщить об игре таким образом:

static const char* play_lookup[] = { "Rock", "Paper", "Scissors" } ;
printf( "Human played %s\n", play_lookup[human] ) ;
printf( "Computer played %s\n", play_lookup[computer] ) ;

Тогда human и computer прямо и арифметически сопоставимы так, что:

int battle = human - computer ;
if( battle < 0 ) battle += 3 ;
switch( battle )
{
    case 0 : printf( "Draw!\n" ) ; break ;
    case 1 : printf( "Human wins!\n" ) ; break ;
    case 2 : printf( "Computer wins!\n" ) ; break ;
}

из (кредит @ HAL9000):

int battle = ((human - computer) + 3) % 3 ;
switch( battle )
...

Собираем все вместе:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

int main()
{
    // Randomize
    srand( (int)time(NULL) ) ;

    // Repeat play indefinitely
    for(;;)
    {
        #define INVALID_SELECTION sizeof(rps)
        static const char rps[] = {'r', 'p', 's'} ;
        int human = INVALID_SELECTION ;

        // While human input is not one of R,P,S,r,p or s...
        while( human == INVALID_SELECTION )
        {
            printf("\nEnter R for Rock, P for Paper, or S for Scissors: ");

            char ch = 0 ;
            scanf("%c", &ch ) ;
            while( ch != '\n' && getchar() != '\n' ) ;

            // Transform input to one of 0,1,2 (for R,P,S respectively)
            for( human = 0; 
                 human < INVALID_SELECTION && tolower(ch) != rps[human] ; 
                 human++ )
            {
                // do nothing
            }
        }

        // Get computer's play    
        int computer = rand() % 3 ;

        // Report human and computer plays in full text
        static const char* play_lookup[] = { "Rock", "Paper", "Scissors" } ;
        printf( "Human played %s\n", play_lookup[human] ) ;
        printf( "Computer played %s\n", play_lookup[computer] ) ;

        // Calculate and report result
        int battle = ((human - computer) + 3) % 3 ;
        switch( battle )
        {
            case 0 : printf( "Draw!\n" ) ; break ;
            case 1 : printf( "Human wins!\n" ) ; break ;
            case 2 : printf( "Computer wins!\n" ) ; break ;
        }
    }

    return 0;
}

Пример вывода:

Enter R for Rock, P for Paper, or S for Scissors: r
Human played Rock
Computer played Rock
Draw!

Enter R for Rock, P for Paper, or S for Scissors: r
Human played Rock
Computer played Scissors
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: r
Human played Rock
Computer played Rock
Draw!

Enter R for Rock, P for Paper, or S for Scissors: r
Human played Rock
Computer played Scissors
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: r
Human played Rock
Computer played Paper
Computer wins!

Enter R for Rock, P for Paper, or S for Scissors: p
Human played Paper
Computer played Paper
Draw!

Enter R for Rock, P for Paper, or S for Scissors: p
Human played Paper
Computer played Scissors
Computer wins!

Enter R for Rock, P for Paper, or S for Scissors: p
Human played Paper
Computer played Rock
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: s
Human played Scissors
Computer played Scissors
Draw!

Enter R for Rock, P for Paper, or S for Scissors: s
Human played Scissors
Computer played Paper
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: s
Human played Scissors
Computer played Paper
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: s
Human played Scissors
Computer played Scissors
Draw!

Enter R for Rock, P for Paper, or S for Scissors: s
Human played Scissors
Computer played Rock
Computer wins!

Enter R for Rock, P for Paper, or S for Scissors: R
Human played Rock
Computer played Scissors
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: P
Human played Paper
Computer played Paper
Draw!

Enter R for Rock, P for Paper, or S for Scissors: S
Human played Scissors
Computer played Paper
Human wins!

Enter R for Rock, P for Paper, or S for Scissors: xx

Enter R for Rock, P for Paper, or S for Scissors: yy

Enter R for Rock, P for Paper, or S for Scissors: zz

Enter R for Rock, P for Paper, or S for Scissors: 

1 голос
/ 20 февраля 2020

Попробуйте:

#include <stdio.h>
#include <stdlib.h> 
int main () {
   char player1;
   int player2;
   int userScore = 0, cpuScore = 0;
   srand ((int) time (NULL));
   int count = 0;
   while(count != 10) {
       printf("Enter p for Paper, r for rock, or S for scissor:\n");
       fgets(&player1, 80, stdin);
       player2 = rand ( ) % 4;
       if(player1 == 'P' && player2 == 1) {
         printf("Draw!\n");
       }if(player1 == 'P' && player2 == 2) {
        userScore++;
        printf("User won this one!\n");
       }if(player1 == 'P' && player2 == 3){
         cpuScore++;
         printf("CPU won this one!\n");
       }
       if(player1 == 'R' && player2 == 2) {
         printf("Draw!\n");
       }if(player1 == 'R' && player2 == 3) {
         userScore++;
         printf("User won this one!\n");
       }if(player1 == 'R' && player2 == 1){
         cpuScore++;
         printf("CPU won this one!\n");
       }
       if(player1 == 'S' && player2 == 3) {
         printf("Draw!\n");
       }if(player1 == 'S' && player2 == 1) {
         userScore++;
         printf("User won this one!\n");
       }if(player1 == 'S' && player2 == 2){
         cpuScore++;
         printf("CPU won this one!\n");
       }
       if(player1!='S' || player1!='R' || player1!='P'){
         printf("Invalid Input\n");
       }
    printf("User Score: %d\n", userScore);
    printf("CPU Score: %d\n", cpuScore);
    count++;
}
   if(userScore == cpuScore) {
     printf("Draw game!\n");
   } else if(userScore > cpuScore) {
     printf("You win!\n");
   } else {
     printf("CPU wins!\n");
   }
   return 0;
}

Я также должен добавить, что эта программа чувствительна. Например, ввод 'r' не будет работать, а 'R' будет. Измените это на ваше усмотрение.

0 голосов
/ 20 февраля 2020

Проблема в том, что вы устанавливаете player2 вне l oop, а не обновляете его; это будет постоянно то же самое. Вместо преобразования его в промежуточное значение с помощью toupper, это, вероятно, типичный случай, когда было бы целесообразно преобразовать его непосредственно в enum. Вместо switch с if это сокращает ваше проблемное пространство до 3 значений, которые легко помещаются в таблицу поиска.

#include <stdlib.h>
#include <stdio.h> /* `printf` requires this. */
#include <time.h>

/* https://en.wikipedia.org/wiki/X_Macro just because I don't want to type. */
#define CHOICE(X)  X(ROCK), X(PAPER), X(SCISSORS)
#define OUTCOME(X) X(LOSS), X(TIE), X(WIN)
#define NAME(A) A
#define STR(A) #A
enum Choice { CHOICE(NAME) };
static const char *const choice_names[] = { CHOICE(STR) };
enum Outcome { OUTCOME(NAME) };
static const char *const outcome_names[] = { OUTCOME(STR) };
static enum Outcome choice_outcomes[][3] = {
    { TIE, LOSS,  WIN },
    { WIN,  TIE, LOSS },
    { LOSS, WIN,  TIE }
};

int main(void) { /* <- `void` should be used to prototype. */
    char input;
    enum Choice player1, player2;
    int score[] = { 0, 0, 0 }; /* <- Replace `cpuScore` and `userScore`. */
    int count = 0;

    srand ((int) time (NULL)); /* <- `srand` should precede `rand`. */

    while(count <= 10) {
        printf("\nEnter p for Paper, r for rock, or S for scissor: ");
        /* Ignores whitespace, (_viz_ enter); breaks on error, (_eg_ EOF.) */
        if(scanf(" %c", &input) != 1) break;
        /* Convert it to `player1` immediately. */
        switch(input) {
        case 'r': case 'R':
            player1 = ROCK; break;
        case 'p': case 'P':
            player1 = PAPER; break;
        case 's': case 'S':
            player1 = SCISSORS; break;
        default:
            printf("Unexpected input, '%c'.\n", input); continue;
        }
        player2 = rand() % 3;
        printf("User choses %s _vs_ Cpu choses %s: %s.\n",
            choice_names[player1], choice_names[player2],
            outcome_names[choice_outcomes[player1][player2]]);
        score[choice_outcomes[player1][player2]]++;
        printf("User Score: %d\n", score[WIN]);
        printf("CPU Score: %d\n", score[LOSS]);
        printf("Ties: %d\n", score[TIE]);
        count++;
    }
    /* One of the places was the `scanf` break, so check, (unlikely.) */
    if(ferror(stdin)) { perror("stdin"); return 1; }

    /* Print the winner. */
    if(score[WIN] == score[LOSS]) {
        printf("Draw game!\n");
    } else if(score[WIN] > score[LOSS]) {
        printf("You win!\n");
    } else {
        printf("CPU wins!\n");
    }
    return 0;
}

Я также помещаю userScore и cpuScore в Массив проиндексирован enum Outcome.

...