Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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.

share|improve this question
    
have you considered c++'s std::vector? You'll need a separate code block to add new items to setOrder. – Sveltely Mar 28 '14 at 1:31
    
I am completely unfamiliar with c++'s std::vector, and not sure if it is supported in arduino... All I know is Arduino is made using c and c++ and some of their methods. – LucasA618 Mar 28 '14 at 1:41
up vote 1 down vote accepted

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.
share|improve this answer
    
Thank you for your corrections, what should I do instead of sizeof(setOrder)? And I plan to also look into vectors, I know nothing about them so the video will be helpful. – LucasA618 Mar 28 '14 at 1:58
    
updated the answer – Sveltely Mar 28 '14 at 2:06
    
That's a good point about the inputs... could I make a temp variable and set it equal to the player's action then just run the var though each of the if statements that way they wouldn't need to make multiple inputs for one move? – LucasA618 Mar 28 '14 at 2:21
    
Yeah, that could work. I'm also not sure how you determine "when an input is finished" - what keeps the loop from reading a hundred (or thousand, or million) inputs as quickly as possible, causing the player to lose immediately? – Sveltely Mar 28 '14 at 2:25
1  
I would suggest creating a subroutine getPosition() which returns one of 5 values, centre, left, right, up, down and maybe "invalid" as well. Then you keep polling this routine waiting for the user to move the joystick to one position, or release it back to know when the next move is coming. – sj0h Mar 28 '14 at 2:44

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.

share|improve this answer
    
Hmm.. sorry, I hate to have a lack of knowledge, but I have no idea what you've done here... Starting with "enum" and yeah pretty much all I understand in this is the if statement, but overall I am unclear what you are doing here. Sorry. – LucasA618 Mar 28 '14 at 2:51
    
Nope I lied you lost me on the if statements too... Sorry! I'm learning still if you could explain that'd be great. – LucasA618 Mar 28 '14 at 2:55
    
an enum is a type (like an int or char) that has a restricted set of possible values. Try another random tutorial from google. As for the ifs.. what particularly don't you understand? – Sveltely Mar 28 '14 at 3:00
    
Okay thank you for trying to explain. I'll consult with my teacher in the morning and see if he can better help me understand because I'm still fairly lost. Sorry I don't want to waste your time trying to completely teach me something. Thank you for your help/input, if you have anything further it's greatly appreciated! – LucasA618 Mar 28 '14 at 3:01

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.

share|improve this answer

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.

share|improve this answer
    
Thank you, I'm going to give this a try. – LucasA618 Mar 28 '14 at 1:57

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.