0

Hello I'm trying to code a pattern game, but the problem is I don't know how to keep track of the previous input of the user, so whenever a new game starts, you cannot input the previous letter. Is there a way to code this?

Example would be like :

Round 1 :
User: inputs -> A
(New Game)
User : inputs -> A // again
Invalid.

Round 2 :
User : inputs -> A
(New Game)
User : inputs -> B 
Valid

Round 3 :
User : inputs -> A
(New Game)
User : inputs -> A
Invalid

The code is here :

#include <stdio.h>
#include <string.h>
int main ()
{
int i=0;
int roundCount = 1;
int pos = 0;


int over = 0;
int f = 1;
char G[2];

printf("Game Start!\n");
do
{
  printf("Round %d!\n", roundCount++);
  printf("Input selection upon prompt.\n");
  printf("Player 1: ");
  scanf(" %c", &G[0] );
  printf("Player 2: ");
  scanf(" %c", &G[1]);

 
if((G[0] == 'L' && G[1] == 'V') || (G[0] == 'V' && G[1] == 'S') || (G[0] == 'S' && G[1] == 'P') || (G[0] == 'P' && G[1] == 'R') || (G[0] == 'R' && G[1] == 'L') || (G[0] == 'R' && G[1] == 'S') || (G[0] == 'P' && G[1] == 'V') || (G[0] == 'S' && G[1] == 'L') || (G[0] == 'V' && G[1] == 'R') || (G[0] == 'L' && G[1] == 'P') )
  {
    f++;
    pos--;
    printf("Uno Wins!   Pos[%d]\n\n", pos);
  }
else if ((G[0] == 'R' && G[1] == 'P' ) || (G[0] == 'L' && G[1] == 'R') || (G[0] == 'R'&& G[1] == 'V') || (G[0] == 'P'&& G[1] =='S')|| (G[0] == 'P'&& G[1] == 'L') || (G[0] == 'S' && G[1] == 'R') || (G[0] == 'S' && G[1] == 'V') || (G[0] == 'L' && G[1] == 'S' )|| (G[0] == 'V'&& G[1] == 'P') || (G[0] == 'V'&& G[1] == 'L'))
  {
    f++;
    pos++;
    printf("Dos Wins    Pos[%d]!\n\n", pos);
  }
 else if ((G[0] == 'R' && G[1] == 'R' ) || (G[0] == 'P' && G[1] == 'P') || (G[0] == 'S' && G[1] == 'S') || (G[0] == 'L' && G[1] == 'L') || (G[0] == 'V' && G[1] == 'V'))
  {
    f++;
    pos = pos;
  }
 if (pos == -3 || pos == 3){
    printf("Game over\n");
    break;
  }
 if(f == 5 && pos != -3 && pos != 3)
  {
     if((G[0] == 'L' && G[1] == 'V') || (G[0] == 'V' && G[1] == 'S') || (G[0] == 'S' && G[1] == 'P') || (G[0] == 'P' && G[1] == 'R') || (G[0] == 'R' && G[1] == 'L') || (G[0] == 'R' && G[1] == 'S') || (G[0] == 'P' && G[1] == 'V') || (G[0] == 'S' && G[1] == 'L') || (G[0] == 'V' && G[1] == 'R') || (G[0] == 'L' && G[1] == 'P') )
  {
 printf("Uno Wins!\n");
    break;
  }
 else if((G[0] == 'R' && G[1] == 'P' ) || (G[0] == 'L' && G[1] == 'R') || (G[0] == 'R'&& G[1] == 'V') || (G[0] == 'P'&& G[1] =='S')|| (G[0] == 'P'&& G[1] == 'L') || (G[0] == 'S' && G[1] == 'R') || (G[0] == 'S' && G[1] == 'V') || (G[0] == 'L' && G[1] == 'S' )|| (G[0] == 'V'&& G[1] == 'P') || (G[0] == 'V'&& G[1] == 'L'))
  {
    printf("Dos Win!\n");
    break;
  }
}


} while (f < 5);

return 0;
}

See code above, It resets at G[0] and G[1] again, i cannot keep track of the previous input because it resets. Is there a way to improve this code? I would gladly appreciate the help.

  • What variables do you want to preserve across invocations? You can write them to a file. At program start you can read them from the file if it exists. When the game is complete, you can unlink the file – Craig Estey Sep 11 '21 at 17:54
  • I edited the question with more samples @TomM – user14997606 Sep 11 '21 at 18:17

2 Answers2

2

Caveat: This isn't a full solution, but a bug fix and some cleanup:

Your scanf sequence produces a bad value for G[1]. Better to use fgets to get a full line cleanly.

Your if statements are unwieldy. They can be greatly simplified with a switch/case and some macro trickery.

Here's some cleaned up code:

#include <stdio.h>
#include <string.h>

#define SWITCH(_g0,_g1) \
    (_g0 << 8) | (_g1 << 0)
#define CASE(_g0,_g1) \
    case SWITCH(_g0,_g1)

int
getval(const char *prompt)
{
    char *cp;
    char buf[100];
    int val;

    while (1) {
        printf("%s: ",prompt);
        fflush(stdout);

        cp = fgets(buf,sizeof(buf),stdin);

        // handle end of file
        if (cp == NULL) {
            val = -1;
            break;
        }

        // get the first char on the line
        val = buf[0];
        if (val != '\n')
            break;
    }

    return val;
}

int
main()
{
    int i = 0;
    int roundCount = 1;
    int pos = 0;

    int over = 0;
    int f = 1;
    int G[2];

    printf("Game Start!\n");

    do {
        printf("Round %d!\n", roundCount++);
        printf("Input selection upon prompt.\n");

        G[0] = getval("Player 1");
        if (G[0] < 0)
            break;
        G[1] = getval("Player 2");
        if (G[1] < 0)
            break;

        printf("DEBUG: %2.2X %2.2X\n",G[0],G[1]);

        switch (SWITCH(G[0],G[1])) {
        CASE('L','V'):
        CASE('V','S'):
        CASE('S','P'):
        CASE('P','R'):
        CASE('R','L'):
        CASE('R','S'):
        CASE('P','V'):
        CASE('S','L'):
        CASE('V','R'):
        CASE('L','P'):
            f++;
            pos--;
            printf("Uno Wins!   Pos[%d]\n\n", pos);
            break;

        CASE('R','P'):
        CASE('L','R'):
        CASE('R','V'):
        CASE('P','S'):
        CASE('P','L'):
        CASE('S','R'):
        CASE('S','V'):
        CASE('L','S'):
        CASE('V','P'):
        CASE('V','L'):
            f++;
            pos++;
            printf("Dos Wins    Pos[%d]!\n\n", pos);
            break;

        CASE('R','R'):
        CASE('P','P'):
        CASE('S','S'):
        CASE('L','L'):
        CASE('V','V'):
            f++;
            pos = pos;
            break;
        }

        if (pos == -3 || pos == 3) {
            printf("Game over\n");
            break;
        }

        if (f == 5 && pos != -3 && pos != 3) {
            switch (SWITCH(G[0],G[1])) {
            CASE('L','V'):
            CASE('V','S'):
            CASE('S','P'):
            CASE('P','R'):
            CASE('R','L'):
            CASE('R','S'):
            CASE('P','V'):
            CASE('S','L'):
            CASE('V','R'):
            CASE('L','P'):
                printf("Uno:Wins!\n");
                break;

            CASE('R','P'):
            CASE('L','R'):
            CASE('R','V'):
            CASE('P','S'):
            CASE('P','L'):
            CASE('S','R'):
            CASE('S','V'):
            CASE('L','S'):
            CASE('V','P'):
            CASE('V','L'):
                printf("Dos Win!\n");
                break;
            }
        }
    } while (f < 5);

    return 0;
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
0

Looking at your code, it looks like you have a persistence problem!

You can solve this a couple ways, but it looks like you only want the data to be around for each 'set' of games. In this case, you need to define the array that holds the user input outside of the loop that the games take place in, otherwise you reinitialize the array each gameplay. That would need to be another array, separate from G[2] that is the maximum size you expect the data to be. From your code it looks like you play 5 games, so 5x2=10, maybe a buffer called Q[10]?

When you finish a loop, set the next 2 members of Q to the user input, and that should work.

Another way to keep the data between runs would be to use a file to maintain the data. That's a little more complicated, but is laid out pretty well in this question:

Write to .txt file?

I hope that helps! Let me know if anything is unclear :)

TomM
  • 175
  • 9
  • i edited the question with more samples please check – user14997606 Sep 11 '21 at 18:42
  • @user14997606, check out Craig's answer above - they really did a great job laying it out! I think their improvement to your structure, and using the buffer variable to hold between matches should get you there! – TomM Sep 13 '21 at 22:05