I'm trying to make an arduino copy of Simon Says, the kids game where you press the colors in the same succession they appeared before, with a Joy Stick for an independent study at school. I think what I have so far will, or would, work however the array I've made gives me the "error: storage size of 'setOrder' isn't known" which makes sense because I've declared it as "int setOrder[];", but this is exactly what I want. An array which has no variables when it is created but can add variables in as the game progresses... This is what I have in my code thus far, please tell me how it looks, and how I can make an array like this. Thank You!!

int xAxis = A0;
int yAxis = A1;
int push = 6;

int blue = 9;
int yellow = 10;
int green = 11;
int red = 12;
int play = 0;
int setOrder[];      /* HERE IS THE PROBLEM */

void setup()
{
  Serial.begin(9600);

  pinMode(blue, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(push, INPUT);
  digitalWrite(push, HIGH); 
}

void loop()
{
 if(!digitalRead(push)){
   play = 1;
   Serial.println("start!");
 } 

 if(play = 1){
   for(int i = 0; i<=sizeof(setOrder); i++){
     setOrder[i] = random(1, 4);
     for(int j = 0; j<=sizeof(setOrder); j++){
       int k = setOrder[j];
       if(k=1){
       digitalWrite(blue, HIGH); delay(750); digitalWrite(blue, LOW);
       }
       if(k=2){
       digitalWrite(yellow, HIGH); delay(750); digitalWrite(yellow, LOW);
       }
       if(k=3){
       digitalWrite(green, HIGH); delay(750); digitalWrite(green, LOW);
       }
       if(k=4){
       digitalWrite(red, HIGH); delay(750); digitalWrite(red, LOW);
       }
     }  

     int playback[sizeof(setOrder)];
     for(int l = 0; l<=sizeof(playback); l++){

       //player presses RIGHT green led
       if(analogRead(xAxis) > 600){
         playback[l] = 4;
           if(playback[l] == setOrder[l]){
             digitalWrite(green, HIGH);
           }
           else{
             digitalWrite(green, HIGH); digitalWrite(blue, HIGH); digitalWrite(yellow, HIGH); digitalWrite(red, HIGH);
             play = 0;
             break;
           }
       }

       //player presses LEFT yellow led
       if(analogRead(xAxis) < 400){
         playback[l] = 2;
           if(playback[l] == setOrder[l]){
             digitalWrite(yellow, HIGH);
           }
           else{
             digitalWrite(green, HIGH); digitalWrite(blue, HIGH); digitalWrite(yellow, HIGH); digitalWrite(red, HIGH);
             play = 0;
             break;
           }
       }

       //player presses DOWN blue led
       if(analogRead(yAxis) > 600){
         playback[l] = 1;
           if(playback[l] == setOrder[l]){
             digitalWrite(blue, HIGH);
           }
           else{
             digitalWrite(green, HIGH); digitalWrite(blue, HIGH); digitalWrite(yellow, HIGH); digitalWrite(red, HIGH);
             play = 0;
             break;
           }
       }

       //player presses UP red led
       if(analogRead(yAxis) < 400){
         playback[l] = 3;
           if(playback[l] == setOrder[l]){
             digitalWrite(red, HIGH);
           }
           else{
             digitalWrite(green, HIGH); digitalWrite(blue, HIGH); digitalWrite(yellow, HIGH); digitalWrite(red, HIGH);
             play = 0;
             break;
           }
       }

     }

   }

 }

}

Also I'm not sure if I'm using the "break();" method correctly, if someone could tell me that'd be great! thanks again.

有帮助吗?

解决方案

I'd recommend you look into std::vector.

On the first line after you check if (play = 1) your main play area, you run a for loop using sizeof(setOrder) without having put data into setOrder first. Even if this did compile, logically your code would always skip the loop. Once you figure out vectors (which I'm pretty sure is what you're looking for), you might want to change this to checking the size of your setOrder vector against a predefined maximum value (at which point the player wins?).

Here's a tutorial on vectors I found from google.

Also, a couple other possible mistakes/recommendations here:

  • break your loop down into several sub-functions that you can call, so that reading your code isn't one giant block. This will also make it easier to find errors, as you can check that each function works, one function at a time.
  • When you check if (play = 1), you're actually using the assignment = operator, not a conditional check ==. You're assigning the value of 1 to play, instead of checking to see if play is equal to 1.
  • You're using sizeof(setOrder) incorrectly. sizeof(X) returns the number of bytes X takes up, not necessarily the number of elements in X. If you use a vector, there's a vector.size() function that returns the number of elements in the vector
  • Whem you check for the player's action, you call analogRead(xAxis) four times - once for each direction. The player's first input will always be checked in the first call. If it's false, the player will need to give another input to make it to the second if statement.

其他提示

For the direction detection, you might look at something like this:

enum Directions {
    Center,
    Left,
    Right,
    Up,
    Down
}

const int threshold = 100;

int getJoyStick() 
{
    // get the X,Y coordinates with 0,0 the centre
    int x = analogRead(xAxis) - 500;
    int y = analogRead(yAxis) - 500;

    /check if we are in the middle.  Both X and Y need to be small for this to happen
    if (abs(x) < threshold && abs(y) < threshold) return Center;

    //to detect up, down, left, right draw diagonals at 45 degrees from the centre
    //if we are more to the right than we are up or down, then it is Right.  This
    //is to cope if it isn't exactly horizonal or vertical
    //so y big might mean up, but if x is bigger, than it is actually to the right
    if (x>y) {
      if (x>-y) return Right; else return Down;
    }
    else {
      if (x>-y) return Up; else return Left;
    }
}

The enum is just to show the nice way of doing it. You would just the same codes through all the code. But instead if it's simpler for you, you could just return numeric codes for each of the directions.

If you are in c++ langage like the c++ tag in your post suggest so, use std::vector instead of array.

A vector is a list that can grow during program execution. Here is a documentation about vector.

If you are going to use plain old C arrays, the easiest path would be an array of static length, long enough to accept your biggest number of entries. Then you keep a separate counter saying how much of the array you are using at the moment.

const int MAX_ORDER_LENGTH = 1024;
int setOrder[MAX_ORDER_LENGTH];
int setOrderSize = 0;  //the number of entries currently used

Then when you are adding entries, make sure that setOrderSize stays less than MAX_ORDER_LENGTH.

beware that sizeof(setOrder) doesn't give the number of entries in the array. It is actually the number of bytes that structure takes up.

the break; commands will drop you out of the innermost for loop, but not the outer one.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top