Recreating Simon with VEX

  1. last week

    I am trying to recreate the game Simon using Vex products. I have all of it built, but I cannot figure out why my code does not do what is expected. The code is below.

    #pragma config(Sensor, dgtl1,  yellowButton,         sensorTouch)
    #pragma config(Sensor, dgtl2,  blueButton,        sensorTouch)
    #pragma config(Sensor, dgtl3,  greenButton,        sensorTouch)
    #pragma config(Sensor, dgtl4,  redButton,        sensorTouch)
    #pragma config(Sensor, dgtl5,  yellowLed,         sensorLEDtoVCC)
    #pragma config(Sensor, dgtl10, greenLed,          sensorLEDtoVCC)
    #pragma config(Sensor, dgtl11, redLed,            sensorLEDtoVCC)
    #pragma config(Sensor, dgtl12, blueLed,           sensorLEDtoVCC)
    //*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
    
    void clearLCD() { // Celar the LCD Screen
    	clearLCDLine(0);
    	clearLCDLine(1);
    }
    
    int buttons; // This is used to detect which button(s) are pressed
    
    bool buttonPressed = false; // This variable is to control when the loop stops running
    bool correctButton = false; // This variable is to tell if the game should continue
    
    void waitForButton(tSensors correctButtonToPress) { // Function to wait for a button
    
    	buttonPressed = false; // Make sure that all variables are setup correctly
    	correctButton = false; // "
    
    	clearTimer(T1);	// This is also used for controlling when the loop stops running
    
    	while (!buttonPressed && time1[T1] < 2000) { // This loop is used to wait for button presses.
    		buttons = (SensorValue[redButton] << 3)+(SensorValue[greenButton] << 2)+(SensorValue[blueButton] << 1)+SensorValue[yellowButton]; // Sets the buttons variable to whatever button
    																																																																			// is pressed (RED = 8, GREEN = 4, BLUE = 2, YELLOW = 1)
    																																																																			// (0 if no button is pressed)
    		if (buttons > 0) { // If there is a button pressed
    			buttonPressed = true;  // Tell the game that a button has been pressed
    
    			switch (buttons) {	// Check which button was pressed
    				case 8: // If the red button was pressed ...
    					if (correctButtonToPress == redButton) { // If the RED button is the button we want, tell the game that the player got it right
    						correctButton = true;
    						SensorValue[redLed] = false;
    						playTone(450, 50);
    						SensorValue[redLed] = true;
    					} else {																	 // Otherwise, thell the game that the player was wrong
    						correctButton = false;
    					}
    				case 4: // If the green button was pressed...
    					if (correctButtonToPress == greenButton) { // If the GREEN button is the button we want, tell the game that the player got it right
    						correctButton = true;
    						SensorValue[greenLed] = false;
    						playTone(560, 50);
    						SensorValue[greenLed] = true;
    					} else {																	 // Otherwise, thell the game that the player was wrong
    						correctButton = false;
    					}
    				case 2: // If the blue button was pressed...
    					if (correctButtonToPress == blueButton) { // If the BLUE button is the button we want, tell the game that the player got it right
    						correctButton = true;
    						SensorValue[blueLed] = false;
    						playTone(650, 50);
    						SensorValue[blueLed] = true;
    					} else {																	 // Otherwise, thell the game that the player was wrong
    						correctButton = false;
    					}
    				case 1: // If the yellow button was pressed...
    					if (correctButtonToPress == yellowButton){ // If the YELLOW button is the button we want, tell the game that the player got it right
    						correctButton = true;
    						SensorValue[yellowLed] = false;
    						playTone(525, 50);
    						SensorValue[yellowLed] = true;
    					} else {																	 // Otherwise, thell the game that the player was wrong
    						correctButton = false;
    					}
    				default: // If a combination of buttons was pressed, end the game
    					correctButton = false;
    					break;
    			}
    		}
    	}
    }
    
    void playVictorySong() // Victory Theme
    {
    // All this does is play a tune.  I doubt this would cause the problem.
    }
    
    bool shouldContinue = true;
    
    task main()
    {
    	SensorValue[redLed] = false;
    	SensorValue[blueLed] = false;
    	SensorValue[yellowLed] = false;
    	SensorValue[greenLed] = false;
    	
    	wait1Msec(2000);
    
    	char sequence[50]; // This character array is a list of letters that holds the sequence.
    
    	for (int i = 0; i < 50; i++) { // This loop just sets the sequence to blank
    		sequence[i] = ' ';
    	}
    
    	for (int i = 0; i < 50; i++) { // This loop controls the logic of the game.
    		if (!shouldContinue) { // If the game should not continue, display "Game Over", and a point count
    			displayLCDCenteredString(0, "Game Over!");
    
    			int points = i-1;
    			string pointsString; // To hold the string for displaying the number of points
    
    			sprintf(pointsString, "Points: %d", points); // Creates a string with the point count in it
    
    			displayLCDCenteredString(1, pointsString); // Display the point count
    			playTone(9000, 50);
    			break;
    		}
    
    		int next = random[3];		// This generates a random number between 0 and 3.
    
    		switch (next) {	//This just checks what the number is, and sets the colro at the current position in the sequence.
    			case 0:							// if the number is zero, set this position to RED
    				sequence[i] = 'R';
    			case 1:							// if the number is one, set this position to GREEN
    				sequence[i] = 'G';
    			case 2:							// if the number is two, set this position to BLUE
    				sequence[i] = 'B';
    			case 3:							// if the number is three, set this position to YELLOW
    				sequence[i] = 'Y';
    			default:						// if somehow the number is not one of these, don't do anything
    				break;
    		}
    
    		for (int j = 0; j < 50; j++) { // This loop displays the sequence using beeps from the speaker, as well as lighing up the LEDs.
    
    			switch (sequence[j]) { // This checks which color, then lights us the correct LED and plays the correct sound.
    				case 'R':									// If the color is RED, Turn on the Red LED, play a sound, then turn off the LED
    					SensorValue[redLed] = false;
    					playTone(450, 50);
    					SensorValue[redLed] = true;
    				case 'G':									// If the color is GREEN, Turn on the Green LED, play a sound, then turn off the LED
    					SensorValue[greenLed] = false;
    					playTone(560, 50);
    					SensorValue[greenLed] = true;
    				case 'B':									// If the color is BLUE, Turn on the Blue LED, play a sound, then turn off the LED
    					SensorValue[blueLed] = false;
    					playTone(650, 50);
    					SensorValue[blueLed] = true;
    				case 'Y':									// If the color is YELLOW, Turn on the Yellow LED, play a sound, then turn off the LED
    					SensorValue[yellowLed] = false;
    					playTone(525, 50);
    					SensorValue[yellowLed] = true;
    				default:									// If the color is somehow not any of the others, do nothing.
    					break;
    			}
    		}
    
    		// The next part is the most complicated. It has to check that the player is inputing the correct series of buttons.
    
    		for (int j = 0; j < 50; j++) { // This loop waits for a button to be pressed, then either continues or ends the game depending on the button
    			char next = sequence[j]; // This is just to make checking which button needs to be pressed easier
    
    			if (next=='R') { // If the red button is next in the sequence wait for a button to be pressed, then check if it was the red button
    				waitForButton(redButton);
    			} else if (next=='G') { // If the green button is next in the sequence wait for a button to be pressed, then check if it was the red button
    				waitForButton(greenButton);
    			} else if (next=='B') { // If the blue button is next in the sequence wait for a button to be pressed, then check if it was the red button
    				waitForButton(blueButton);
    			} else if (next=='Y') { // If the yellow button is next in the sequence wait for a button to be pressed, then check if it was the red button
    				waitForButton(yellowButton);
    			}
    
    			if (!correctButton){				// If the wrong button was pressed, tell the game to display "Game Over"
    				shouldContinue = false;
    				break;
    			}
    			
    			buttonPressed = false;
    		}
    	}
    
    	if (shouldContinue) { // If the game is over, and the player succeded, tell them they won and play a victory song
    		clearLCD();	// Clear the LCD
    		displayLCDCenteredString(0, "You Win!"); // Display "You Win!" on the LCD
    		playVictorySong();   // Play a Victory Song
    	}
    
    }

    If you would like a picture of the bot itself, let me know. But for some reason, the code, as I said, does not behave as expected. It is supposed to generate a random sequence, one at a time, like the game Simon, and display it to the user. For some reason, the LEDs turn on, but they wont turn off, and then the sounds are all messed up. The sound plays normally for the first button, then you press the button, and the sound plays too long, then the loss tone plays. Not sure what is wrong.

    Any help is appreciated. Thanks in advance!

  2. callen

    Jun 12 Braintree, MA, USA

    I don't have time to go through all of that and I haven't used the LEDs and don't code in RobotC, but here are two quick things:

    1. Where is the LED plugged in? As in, which two of the three holes are you using? In this thread ( https://www.vexforum.com/index.php/6413-question-on-programming-led-indicators-using-robot-c/0 ) the OP had a similar problem, and the wires were in the wrong holes.
    2. As a general rule you don't want to assign a fixed length to something that could be arbitrarily long. It would be better to use pointers to dynamically increase the size of the array (which is really replacing it and throwing out the original). Then in your for loops you go until the last item instead of always going to 50. But 50 is small enough that the Cortex should be able to get through the wasted processing quickly, and at the same time 50 is big enough that it's unlikely anyone will get further. So you should be safe.
 

or Sign Up to reply!