简体   繁体   中英

Selectively ignoring parts of a randomly generated sequence of numbers (in C)

I have a question that may be hard to understand -- but I will try my best to explain.

I'm programming the Simon Game in C. This implementation specifically read/writes to a hardware DAQ module that has a 4 LED display, and 4 corresponding toggle switches.

As per the rules of the Game, I've seeded and generated a random sequence of numbers between 0 and 3 (sequence length is arbitrarily 5). In the Game, if the player presses the wrong switch (ie blue is shown but you press green), the game ends and restarts.

The way I've set up the Game looks like this:
(I haven't included the code for function "blinkLED" here -- it turns the actual LED on/off.)

    void runSimon(void){
    int sequence[MAX_SEQ_LEN];
    int i;
    int count = 0;

    // Seeds the random number generator.
    srand((unsigned)time(NULL));

    // Generate the random LED sequence & store it as an array.
    for (i = 0; i < MAX_SEQ_LEN; i++){
        sequence[i] = (rand() % NUM_LEDS);
    }

    // The game begins!
    while (continueSuperLoop() == TRUE){

        // Loop the game while the sequence length is less than the pre-defined maximum (currently it's 5).
        while (count < MAX_SEQ_LEN){

            for (i = 0; i <= count; i++){

                // Blink the first 'count' LEDs in the sequence, one at a time.
                blinkLED(sequence[i], 1, ONE_SEC);

                //
                //
                //THE ISSUE SHOULD BE HERE (!)
                //
                // Monitors whether or not the player has made a mistake...if so, blink the red LED thrice, then restart the game. 
                if (digitalRead(sequence[ !i ] == SWITCH_ON)){
                    blinkLED(LED_1_R, 3, HALF_SEC);
                    Sleep(3 * ONE_SEC);
                    continue;
                }

                // Monitors whether or not the correct switch is being pressed -- waits for it to be released
                while (digitalRead(sequence[i]) == SWITCH_ON){}
            }
            count++;
        }

        // If 'count' is equal to 'MAX_SEQ_LEN', the green LED blinks 3x to indicate the player has won .
        if (count == MAX_SEQ_LEN){
            blinkLED(LED_0_G, 3, HALF_SEC);
            Sleep(3 * ONE_SEC);
        }
    }
}

Where I indicated an issue, I'm not sure how the "digitalRead(sequence[ ! i ]" behaves; I need this line to read every switch that's not supposed to be pressed.

I don't think the compiler understands what I'm trying to do here, though -- for example, if the first number in the sequence is 3 (representing the 4th LED), I need to specify that every other number (0, 1, 2) and its corresponding switch should not be pressed.

Would a solution be to store the current number in the sequence, having a set of four TRUE/FALSE flags for each LED, and monitoring the three non-current numbers and their corresp. switches to see if they are pressed?



I'm getting quite frustrated with writing this program. I'm pretty new to programming. Any help is appreciated.

I'm not sure I understand the rules of this game correctly but one thing that jumps out instantly is

digitalRead(sequence[ !i ]

I think you want

!digitalRead(sequence[ i ]

Also, you need to fix your game flow. Right now it's:

1. Light LED.
2. Check if user pressed the right button.

You need to wait for some time before checking a switch or wait for ANY switch to be pressed and see if it's the correct one. So something like this:

 1. Light LED.
 2. Wait for timeout or ANY switch to be pressed.
 3. If timeout: error
 4. else: check if switch that was pressed is correct.

In C, ! operator is a unary NOT. When applied to an integer i , it is equivalent to if (i == 0) return 1; else return 0; if (i == 0) return 1; else return 0; . Then you are using !i as an index for sequence array, so it will be either sequence[0] or sequence[1] , and clearly this is not what you want. Also your == is inside of digitalRead call :)

I would suggest explicitly checking for every other button not to be pressed. Like this:

int isOtherPressed = 0;
for (ledId = 0; ledId < NUM_LEDS; ledId++) {
    if (ledId != sequence[i] && digitalRead(ledId) == SWITCH_ON) {
        isOtherPressed = 1;
    }
}

if (isOtherPressed) {
    // restart the game
}

However, I'm suspicious about the whole gameplay you have, but maybe it's just because I don't know how digitalRead works. For example, the way you use continue doesn't seem to stop the game. Maybe you meant break ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM