0

I'm new to C, and is trying to make a number baseball game. The functions I wish to include are, when I press x, the game ends, and when I press m, a series of instructions are printed. Finally, I've added a re-game function, so that when I press the number 1 after the game ends, one could play it again. The number baseball game itself works fine, but whenever I press x or m, the program goes into an infinite loop. I can't figure out what's wrong. Also, when I use the re-game function, my program works, but it doesn't generate a new set of numbers, and just uses the set it used before. Could you please help??

#include <stdio.h>
#include <time.h>
#include <windows.h>

int main (void) {
    
    int computerBall[4];
    int X = 0;
    int i, j = 1;
    int userBall[4];
    int x, m;
    int o, q;
    int flag = 1;
    q = 1;
    x = 2;
    m = 3;
    srand (time (NULL));

    computerBall[0] = rand () % 31;

    while (computerBall[0] == 0)
        computerBall[0] = rand () % 31;

    for (i = 1; i < 4; i++) {
        computerBall[i] = rand () % 31;

        while (q == 1) {
            flag = 0;
            for (j = 0; j < i; j++) {
                if (computerBall[j] == computerBall[i]) {
                    computerBall[i] = rand () % 31;
                    flag = 1;
                    break;
                }
            }
            if (flag == 0)
                break;
        }
    }                           // Code to Generate Random Numbers
    while (q == 1) {
        printf ("Choose 4 numbers between 1 and 30\n");
        printf ("Press x to exit, and press m for help\n");
        while (q == 1) {
            printf ("Input numbers:");
            scanf_s ("%d %d %d %d\n", &userBall[0], &userBall[1],
                     &userBall[2], &userBall[3]);
            //To prevent numbers outside of range
            if (userBall[0] < 1 || userBall[0] > 30 || userBall[1] < 1 || 
                userBall[1] > 30 || userBall[2] < 1 || userBall[2] > 30 || 
                userBall[3] < 1 || userBall[3] > 30) {
                printf ("You cannot input numbers outside the range.\n");
                continue;
            } //To prevent repeating numbers
            else if (userBall[0] == userBall[1] || userBall[0] == userBall[2] ||
                     userBall[0] == userBall[3] || userBall[1] == userBall[2] ||
                     userBall[1] == userBall[3] || userBall[2] == userBall[3]) {
                printf ("You cannot input same numbers at once.\n");
                continue;
            }
            else if (userBall[0] == m) {        //Doesn't work
                printf ("Help\n\n");
                continue;
            }
            else if (userBall[0] == x) {        //Doesn't work
                printf ("\n Game Over\n");
                printf ("Answer : ");
                printf ("%d ", X);
                printf ("Press 1 to restart");
                scanf_s ("%d", &o);
                if (o == 1)
                    continue;
                else
                    q = 0;
            }
            break;
        }
    }
    return 0;
}
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
Dagun
  • 41
  • 5
  • 1
    The short answer is all your `scanf_s()` function calls read integers. If you press `'x'` or `'m'` a *matching failure* occurs -- character extraction from `stdin` ceases -- leaving the offending character ***unread*** in `stdin` and you try to read an integer again -- you spin off into an infinite loop because `'x'` or `'m'` is still there and your next attempt to read an integer input fails for the same reason.... – David C. Rankin Jun 27 '20 at 06:57
  • Also note `"%d %d %d %d\n"` many not do what you think it does, see [Format Specification Fields: scanf](https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-fields-scanf-and-wscanf-functions?view=vs-2019) – David C. Rankin Jun 27 '20 at 06:59
  • I thought declaring x and m as integers would solve the problem... Is there a way to 'read' characters using scanf_s() calling integers? Or should I add a separate scanf_s() function to read the characters? Thanks – Dagun Jun 27 '20 at 07:01
  • Oh No No No.... If you want al literal `'m'`, then you must enclose it in single quotes. You will then get the [ASCII value for m](http://www.asciitable.com/) (e.g. `109`) Answer me this.. What is the value held in variable `m` when you do `else if (userBall[0] == m)`? (hint: it is uninitialized -- invoking *Undefined Behavior*) – David C. Rankin Jun 27 '20 at 07:07
  • You may benefit from [Long Answer Describing correct use of `scanf`](https://stackoverflow.com/a/60472657/3422102). It should give you more than a short introduction to using `scanf` (and the [C-Standard Annex K](http://port70.net/~nsz/c/c11/n1570.html#K) `_s` functions that Microsoft implements) – David C. Rankin Jun 27 '20 at 07:16
  • Thanks for your help. I'll try reading it. – Dagun Jun 27 '20 at 07:22

1 Answers1

0

Try using return 1 in the particular line of your code when you want to exit to close the program if that's your problem