# NOTICE!!

THIS TUTORIAL IS OUT OF DATE! Please check out the UPDATED version, here: Make Your Own Arduboy Game: Part 5 - Your First Game!

This is Part 5 in a series on learning how to program your own Arduboy game. If you have skipped the previous parts, please read over Part 1, Part 2, Part 3 and Part 4.

I think you’ve got all the skills you need to make your first game! This game will be a number guessing game where the Arduboy picks a random number and the player has 7 attempts to guess the number. After each guess, the Arduboy will tell the player a hint. If the player guesses right, the player wins!

# Starting Code

Okay, let’s start a new project. Open up the Arduino IDE and go to File > New. In the new window, add some comments at the top that include your name and the title of this game.

Whenever I make a new game, the first things I do are: 1) Include the Arduboy library, 2) Create a new `Arduboy` object, 3) Prepare the `setup()` and `loop()` sections.

Here’s what the code looks like when we’re ready to begin:

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;

void setup() {
arduboy.begin();
arduboy.clear();

}

void loop() {
arduboy.clear();

arduboy.display();
}``````

# Setting Up Variables

For our game, we need to set up some variables. We need one to keep track of how many attempts the players has left, what the number the player is guessing, what number the Arduboy picked, and one to know if the player has won or not.

At this point, you only know how to use `int`'s, so we’ll continue using them. In the next part, I’m going to teach you about more of them.

Anyway, let’s initialize the variables by adding this code before `setup()`:

``````int playerwin;
int attempts;
int guessednumber;
int randomnumber;``````

Inside of `setup()`, let’s assign these variables to 0.

``````playerwin = 0;
attempts = 0;
guessednumber = 0;``````

`randomnumber` isn’t supposed to be 0. Instead, let’s use the following code to assign a random number to it between 1 and 100;

``````srand(7/8);
randomnumber = 1 + rand() % 100;``````

This is some wizardry if you don’t know much about computer programming. But keep following these tutorials and we’ll explain them in a later part.

Next, we’re going to put most of our game’s code between the `arduboy.clear()` and `arduboy.display()` functions. So, put a comment in between them so we can keep track of where we are. Your code should now look like this:

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;

}

void loop() {
arduboy.clear();
//Gameplay code goes here
arduboy.display();
}``````

# Else

We want our player to know if they have won or not. So, our `playerwin` variable will help with that. If `playerwin` is equal to 0, the player has not won. If `playerwin` is not equal to 0, then the player has won. In our code, we can put 2 `if` statements in to handle this.

``````if( playerwin == 0 ) {
//Ask the player for a number and play the game
}
if( playerwin == 1 ) {
//Tell the player that they won!
}``````

There can be some problems from doing our code this way, so I am going to teach you a better method using the `if-else` statement.

What we want is for our game to run some code if the player didn’t win, yet, and run other code if they did. At the end of an `if` statement, we can add `else` and more braces for a new section of code. Confused? Take a look below:

``````if( playerwin == 0 ) {
//Ask the player for a number and play the game
} else {
//Tell the player that they won!
}``````

Else is just another way to say otherwise. The above code says that if `playerwin` is equal to 0, then we need to run some code, otherwise we need to run some other code.

# Coding The Game

Let’s stick the above `if-else` statement into the game and see where we’re at:

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;
}

void loop() {
arduboy.clear();
if( playerwin == 0 ) {
//Ask the player for a number and play the game
} else {
//Tell the player that they won!
}
arduboy.display();
}``````

Now, we have two sections of code we need to finish: 1) Asking the player for numbers and 2) Telling the player that they won.

# Guessing A Number

The player will have 7 attempts to guess a number. So, when their attempts is at 7, we’ll show them a game over screen instead of letting them guess, again. We’ll use another `if-else` statement.

``````if( attempts == 7 ) {
//Game Over screen
} else {
//Player has more attempts
}``````

We’ll worry about the Game Over screen in a minute. For now, let’s modify the part with players having more attempts remaining.

The first thing we want to do is handle the buttons. If a player uses the Up or Down button, the `guessednumber` will increase or decrease. When the player presses the A Button, the player will actually attempt to guess that number.

``````if( arduboy.pressed(UP_BUTTON) == true ) {
guessednumber = guessednumber + 1;
}
if( arduboy.pressed(DOWN_BUTTON) == true ) {
guessednumber = guessednumber - 1;
}
if( arduboy.pressed(A_BUTTON) == true ) {
//Guess number
}``````

This is something we’ve seen before in the previous tutorial. After we handle the button input, we want to display the number being guessed as well as how many attempts the player has left. Add this code in:

``````arduboy.setCursor(0, 0);
arduboy.print("Attempt: ");
arduboy.print(attempts);
arduboy.print("\n");
arduboy.print("Number to guess: ");
arduboy.print(guessednumber);``````

You should know what this code does. However, there is something new: `arduboy.print("\n");` This line of code creates a linebreak, which is like hitting the Enter button on your keyboard to insert a new line of text.

Let’s go back and add one more `if-else` statement in this to handle the player making a guess! Remember, if the player guesses the random number, the player will win, otherwise (else) the player use up an attempt.

Remember, when a player wins, we already decided that `playerwin` would be changed from 0 to another number! Change the A Button code to this:

``````if( arduboy.pressed(A_BUTTON) == true ) {
if( guessednumber == randomnumber ) {
playerwin = 1;
} else {
attempts = attempts + 1;
}
}``````

Makes sense, right? Here’s what the code should currently look like! We’re almost done!

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;
srand(7/8);
randomnumber = 1 + rand() % 100;
}

void loop() {
arduboy.clear();
if( playerwin == 0 ) {
//Ask the player for a number and play the game
if( attempts == 7 ) {
//Game Over screen
} else {
//Player has more attempts
if( arduboy.pressed(UP_BUTTON) == true ) {
guessednumber = guessednumber + 1;
}
if( arduboy.pressed(DOWN_BUTTON) == true ) {
guessednumber = guessednumber - 1;
}
if( arduboy.pressed(A_BUTTON) == true ) {
if( guessednumber == randomnumber ) {
playerwin = 1;
} else {
attempts = attempts + 1;
}
}
arduboy.setCursor(0, 0);
arduboy.print("Attempt: ");
arduboy.print(attempts);
arduboy.print("\n");
arduboy.print("Number to guess: ");
arduboy.print(guessednumber);
}
} else {
//Tell the player that they won!
}
arduboy.display();
}``````

# Game Over Screen

The Game Over screen is pretty easy. We need to put 2 things into the Game Over section: 1) Tell the player they lost and what the correct number actually was, and 2) Let them push A to restart the game. We already know how to tell the player that they lost:

``````arduboy.setCursor(0, 0);
arduboy.print("You lost!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);``````

Easy, right? When the player presses the A Button, we want the variables to reset and find a new random number. Here’s what that code looks like.

``````if( arduboy.pressed(A_BUTTON) == true ) {
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}``````

# Win Screen

The Win screen will look almost identical to the Game Over screen. Let’s add this code to the Win screen:

``````arduboy.setCursor(0, 0);
arduboy.print("You won!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true ) {
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}``````

# Uh, Oh!! There’s A Problem!

Uh, oh!!! There’s a problem… We’re almost done, but there’s a problem that I specifically avoided telling you about. Go ahead and run this code on your Arduboy and see if you can figure out what it is! If you’ve done the previous tutorials in this series, you may have already figured it out!

Here’s what the code should look like so far:

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;
srand(7/8);
randomnumber = 1 + rand() % 100;
}

void loop() {
arduboy.clear();
if( playerwin == 0 ) {
//Ask the player for a number and play the game
if( attempts == 7 ) {
//Game Over screen
arduboy.setCursor(0, 0);
arduboy.print("You lost!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true ) {
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
} else {
//Player has more attempts
if( arduboy.pressed(UP_BUTTON) == true ) {
guessednumber = guessednumber + 1;
}
if( arduboy.pressed(DOWN_BUTTON) == true ) {
guessednumber = guessednumber - 1;
}
if( arduboy.pressed(A_BUTTON) == true ) {
if( guessednumber == randomnumber ) {
playerwin = 1;
} else {
attempts = attempts + 1;
}
}
arduboy.setCursor(0, 0);
arduboy.print("Attempt: ");
arduboy.print(attempts);
arduboy.print("\n");
arduboy.print("Number to guess: ");
arduboy.print(guessednumber);
}
} else {
//Tell the player that they won!
arduboy.setCursor(0, 0);
arduboy.print("You won!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true ) {
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
}
arduboy.display();
}``````

Did you figure out the problem? Yeah, it’s kinda unexpected. The Arduboy is too fast when playing a game like this! Playing the game and pressing the A button will blast through the entire menu super fast. Same with pressing Up or Down… The numbers will scroll too fast.

# Fixing This Issue

So, we need to do 1 of 2 things to fix this speed issue. We could intentionally slow the Arduboy down, however, when making some games, they will move too slow to be enjoyable. That’s not really an option for us. The second option is to have some kind of variable that keeps track if the player is holding down the button or not. The Arduboy is so fast that if you press the button for a fraction of a second, it will already run through the code several times, thinking you’ve pressed the button several times.

Let’s start by going all the way to the top of our file to initialize some new variables.

``````int upbuffer;
int downbuffer;
int abuffer;``````

Next, let’s assign them to be 0 in our `setup()` section.

``````upbuffer = 0;
downbuffer = 0;
abuffer = 0;``````

To keep track of our button presses, we’ll have these variables hold either a 0 or a 1. If the buffer variable is 0, that means that the player did not press that button. If the buffer variable is equal to 1, that means the player did press that button.

Whenever the player lets go of a button, we want to set these variables back to 0.

This means that any time we press a button, we can check to see if the button was being held down or if it was pressed for the first time. If is being held down, we want to pretend like the button was not even pressed and ignore it.

This may be a little confusing for some people to understand, but please bear with me.

At the end of `loop()`, let’s add some code that can do that.

``````if( arduboy.notPressed(A_BUTTON) == true ) {
abuffer = 0;
}
if( arduboy.notPressed(DOWN_BUTTON) == true ) {
downbuffer = 0;
}
if( arduboy.notPressed(UP_BUTTON) == true ) {
upbuffer = 0;
}``````

Now, every place that we check to see if a button is pressed or not, we need to also check to see if the buffer variable is 0 or 1.

If the button is being pressed `and` the buffer variable is 0, then we will run the code as well and change the buffer variable to 1.

Replace all the button checks that look like the following…

``if( arduboy.pressed(A_BUTTON) == true  ) {``

to…

``````if( arduboy.pressed(A_BUTTON) == true and abuffer == 0 ) {
abuffer = 1;``````

Notice that the word `and` allows us to check for multiple things inside of an `if` statement. Do this with Up and Down Button checks, too!

From…

``if( arduboy.pressed(DOWN_BUTTON) == true  ) {``

to…

``````if( arduboy.pressed(DOWN_BUTTON) == true and downbuffer == 0 ) {
downbuffer = 1;``````

From…

``if( arduboy.pressed(UP_BUTTON) == true  ) {``

to…

``````if( arduboy.pressed(UP_BUTTON) == true and upbuffer == 0 ) {
upbuffer = 1;``````

After you do that, test your code, which should look just like this:

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;
int upbuffer;
int downbuffer;
int abuffer;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;
srand(7/8);
randomnumber = 1 + rand() % 100;
upbuffer = 0;
downbuffer = 0;
abuffer = 0;
}

void loop() {
arduboy.clear();
if( playerwin == 0 ) {
//Ask the player for a number and play the game
if( attempts == 7 ) {
//Game Over screen
arduboy.setCursor(0, 0);
arduboy.print("You lost!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true  and abuffer == 0 ) {
abuffer = 1;
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
} else {
//Player has more attempts
if( arduboy.pressed(UP_BUTTON) == true and upbuffer == 0 ) {
upbuffer = 1;
guessednumber = guessednumber + 1;
}
if( arduboy.pressed(DOWN_BUTTON) == true and downbuffer == 0 ) {
downbuffer = 1;
guessednumber = guessednumber - 1;
}
if( arduboy.pressed(A_BUTTON) == true and abuffer == 0 ) {
abuffer = 1;
if( guessednumber == randomnumber ) {
playerwin = 1;
} else {
attempts = attempts + 1;
}
}
arduboy.setCursor(0, 0);
arduboy.print("Attempt: ");
arduboy.print(attempts);
arduboy.print("\n");
arduboy.print("Number to guess: ");
arduboy.print(guessednumber);
}
} else {
//Tell the player that they won!
arduboy.setCursor(0, 0);
arduboy.print("You won!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true and abuffer == 0 ) {
abuffer = 1;
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
}
if( arduboy.notPressed(A_BUTTON) == true) {
abuffer = 0;
}
if( arduboy.notPressed(DOWN_BUTTON) == true ) {
downbuffer = 0;
}
if( arduboy.notPressed(UP_BUTTON) == true ) {
upbuffer = 0;
}
arduboy.display();
}``````

# Hints

After testing your game, you may have realized that it’s just too hard for someone to actually beat. I tried a many times and won only once. It’s almost impossible!

Let’s make the game a little easier and a little more fun by adding in hints to the player. To start this, let’s create a new variable called `lastguess` and give it a value of 0.

Every time the player makes a guess, let’s set `lastguess` to have the same value of their `guessednumber`.

Look for the line of code where the player uses one of their attempts:

``attempts = attempts + 1;``

After that line, let’s add the following:

``lastguess = guessednumber;``

Add a new linebreak after with `arduboy.print("\n");` and add a new `if-else` statement. We’re going to check the player guessed anything, yet.

``````arduboy.print("\n");
if( attempts == 0 ) {
//No last guess
} else {
//Last guess was wrong
}``````

If there have been 0 attempts so far, then let’s print out “Good luck!” Otherwise, let’s display the last guess. That code should now look like:

``````arduboy.print("\n");
if( attempts == 0 ) {
arduboy.print("Good luck!");
} else {
arduboy.print(lastguess);
}``````

Our hint will actually to tell the user if `lastguess` is less than `<` or greater than `>` the `randomnumber` and print that out. That code should now look like:

``````arduboy.print("\n");
if( attempts == 0 ) {
arduboy.print("Good luck!");
} else {
arduboy.print(lastguess);
if( lastguess > randomnumber ) {
arduboy.print(" is too high!");
}
if( lastguess < randomnumber ) {
arduboy.print(" is too low!");
}
}``````

You’ve seen all of this code before, except for checking if a number is less than `<` or greater than `>` another number.

# Full Code

Yes! You’re finally done!! Test out this code and have fun!

``````//Jonathan Holmes (crait)
//October 24th, 2016
//Number Guessing Game

#include <Arduboy.h>
Arduboy arduboy;
int playerwin;
int attempts;
int guessednumber;
int randomnumber;
int upbuffer;
int downbuffer;
int abuffer;
int lastguess;

void setup() {
arduboy.begin();
arduboy.clear();
playerwin = 0;
attempts = 0;
guessednumber = 0;
randomnumber = 0;
srand(7/8);
randomnumber = 1 + rand() % 100;
upbuffer = 0;
downbuffer = 0;
abuffer = 0;
lastguess = 0;
}

void loop() {
arduboy.clear();
if( playerwin == 0 ) {
//Ask the player for a number and play the game
if( attempts == 7 ) {
//Game Over screen
arduboy.setCursor(0, 0);
arduboy.print("You lost!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true  and abuffer == 0 ) {
abuffer = 1;
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
} else {
//Player has more attempts
if( arduboy.pressed(UP_BUTTON) == true and upbuffer == 0 ) {
upbuffer = 1;
guessednumber = guessednumber + 1;
}
if( arduboy.pressed(DOWN_BUTTON) == true and downbuffer == 0 ) {
downbuffer = 1;
guessednumber = guessednumber - 1;
}
if( arduboy.pressed(A_BUTTON) == true and abuffer == 0 ) {
abuffer = 1;
if( guessednumber == randomnumber ) {
playerwin = 1;
} else {
attempts = attempts + 1;
lastguess = guessednumber;
}
}
arduboy.setCursor(0, 0);
arduboy.print("Attempt: ");
arduboy.print(attempts);
arduboy.print("\n");
arduboy.print("Number to guess: ");
arduboy.print(guessednumber);
arduboy.print("\n");
if( attempts == 0 ) {
arduboy.print("Good luck!");
} else {
arduboy.print(lastguess);
if( lastguess > randomnumber ) {
arduboy.print(" is too high!");
}
if( lastguess < randomnumber ) {
arduboy.print(" is too low!");
}
}
}
} else {
//Tell the player that they won!
arduboy.setCursor(0, 0);
arduboy.print("You won!");
arduboy.print("\n");
arduboy.print("Correct Number: ");
arduboy.print(randomnumber);
if( arduboy.pressed(A_BUTTON) == true and abuffer == 0 ) {
abuffer = 1;
randomnumber = 1 + rand() % 100;
attempts = 0;
playerwin = 0;
}
}
if( arduboy.notPressed(A_BUTTON) == true) {
abuffer = 0;
}
if( arduboy.notPressed(DOWN_BUTTON) == true ) {
downbuffer = 0;
}
if( arduboy.notPressed(UP_BUTTON) == true ) {
upbuffer = 0;
}
arduboy.display();
}``````

For anyone wanting a graphical representation of this game, here’s a flow chart.

# What’s Next?

Wow! That was a lot! There is still a lot of stuff you need to learn to be a great programmer. I’ll teach you that stuff later, though. The next tutorial is going to be fun! You’ll learn how to make games with images!

# Credits

I wrote this tutorial in order to give back to the programming community that taught me to get into it about 10 years ago. If you’d like to follow me on Twitter, please do so at http://www.twitter.com/crait . I’d greatly appreciate that.

17 Likes

thanks for sharing your knowledge. They appreciate, thousands of kilometers away. someone found them useful

1 Like

No problemo, bud!

2 Likes

Very very helpful! Thank you! Looking forward to more guides!

2 Likes

Looks like a good place to ask my question. You dealt with single-press buttons very well. I need to tweak my 1010 game to buffer some of the buttons. But some of them should auto-repeat (i.e. - arrows when moving shapes around), and the buffer would seem to break that.

For that game, I just did what I think of as a typical debounce delay at the end of the loop. This doesn’t work very satisfactorily: sometimes the buttons get missed, other times they double press. I’ve seen games where the buttons work very well including auto-repeat but I’ve not been able to dig out how they are doing it (haven’t tried very hard yet - since 1010 isn’t time sensitive, this is an annoyance but doesn’t affect game play).

Can you provide a way to do this, or maybe that’s later?

Thanks,
Mike

In Part 7, I was going to make a little more clear how to handle button input that way, but I think your best bet would be to create a new thread for that since so many people can have different opinions on the best method for your particular game. Plus, you can post your code there. If you do that, I’ll try to read over it and see what I come up with.

Thank you very much for this amazing contribution. I am implementing …
Lol sorry for my ignorance , but these programs were not used … have some use to create games?.

I have a very good project and I thank you, I hope the following contents.

Codebender has been shut down, GCC and AVRDude are what the Arduino IDE uses to compile and upload the sketch to the Arduboy. Unless you want to create your own uploader you shouldn’t need to mess with GCC or AVRDude directly.

2 Likes

I use PlatformIO to develop ALL of my Arduino programs. I highly recommend it.

(Psst, that’s not a flow chart, it’s a state diagram. Pedantry ho!)

2 Likes

I’m really enjoying this series and I trust your work because Circuit Dude is one of the best Arduboy games out so far! I’m not familiar with C++ but being somewhat familiar with Python definitely helps out a little bit.

5 Likes

THANK YOU SO MUCH!!

1 Like

Hi,
First of all, great posts! Thank you for sharing your knowledge.
Im new at this and im learning much with your tutorials.
In this guessing number game ive encounter a “problem” (i dont really know if its a problem or something else);
At starting the game the first number to guess is 35, if you continue the next number to guess is 16, if you continue the next number to guess is 4, and so on.
And this is repeated every time you turn off the Arduboy and turn it on again.
So i dont know if i have done something wrong in the code, or its something else.
Thank you!!

It’s because `random` actually returns a fixed sequence of numbers.
For it to be passable as being actually ‘random’, you need to call `arduboy.initRandomSeed();`.

In the world of programming, generally people use what are called pseudo-random number generators for random numbers where a sequence of seemingly random numbers is needed. The sequence takes a start value (called a ‘seed’) and performs the same operation each time to generate the next number in the sequence.

The `initRandomSeed` function uses atmospheric noise from an unconnected input pin (something that’s usually genuinely random) to create the seed value so that each time the device is turned on the sequence ends up being different.

1 Like

Ok i think i understand jejejeje.
Thank you very much @Pharap !!!
Greatings

1 Like

Your approach to the button is really practical.！
But each time the value of abuffer changes to 0 needs to be fully executed loop (), does this reduce the efficiency?

Can’t wait for part 10! Keep up the good work.

# NOTICE!!

THIS TUTORIAL IS OUT OF DATE! Please check out the UPDATED version, here: Make Your Own Arduboy Game: Part 5 - Your First Game!