Reaction Timer
Up
Before attempting this project, please do the very easy 'Random Number' Project.

The Plan

We'll try to game a program to measure the user's reaction time to very high precision. It must detect attempts to cheat. In part 1 (this page) we learn how to make a button-based approach and in part 2 we will move to a keyboard-based approach that most users would prefer.  In part 1 you will learn:

bullethow to generate random numbers
bulletloops
bullethow to use the Select...Case code structure as an alternative to the If...Then structure

Here's my idea: There will be a single button that the user will press when (s)he is ready. Then, after a random length of time, the button's text will change to indicate that the user must now hit the button again as soon as possible. When the user does hit the button then the program will display the user's time and the button will revert to its original standby state. Unfortunately is is possible that some users may try to cheat (hard to believe, I know, but possible nevertheless).

As I see it, our program therefore has three states:

A standby state, in which the program waits for the user to indicate that (s)he is ready to begin.

A wait state in which the program is measuring out a random of length of time (if the user click the button now then that is an attempt at cheating.

A reaction timing state in which the signal has been given for the user to click the button as soon as possible.

If we make sure that the text displayed on the button is different in each state then the text itself can be used as the program's reference to know what state it is in and what it should do when the button is pressed. It's important then to make no mistakes when referring to the button's text property in the properties window or the code window.

Make a new Windows Application project with the name Reactions and and save it immediately (using File>Save All) with the name Reactions.

Make the form quite small and add a label, a button and a timer control. Set properties as follows:

bulletForm:
text = Reaction Timer by (YOUR NAME HERE)
 
bulletLabel:
name = lblTime
autosize = false
textalign = middlecenter
font size = 16
text = (empty)
 
bulletButton:
name = btnReact
text = Click me to start     (make sure the text is exactly correct)
font size = 16
bulletbackcolor = WhiteSmoke (in the web palette)
 
bulletTimer:
name = tmr1

Your form should look something like this (the timer control is not visible):

Now that we've finished creating the controls and setting their properties we can get to work on the code. The program starts up it 'standby state' which corresponds to the button displaying the text shown in the picture above. When the button is clicked we want to enter the 'wait state', so we need these lines of code:

lblTime.Text = ""
btnReact.Text = "Wait..."
btnReact.BackColor = Color.LightGreen
tmr1.Interval = 3000 + 4000 * Rnd()
tmr1.Enabled = True

The first line ensures that the label does not display any text while in the wait state (we don't want it to display a previous time). The third line changes the colour of the button to make the change of state more obvious. The forth line sets the timer interval to a random time between 3 and 7 seconds and takes into account that the timer interval is in milliseconds not seconds (3 seconds = 3000 milliseconds etc). The last line gets the timer going. We've now entered the 'wait state', as indicated by the second line.

Either of two events could take us out of the standby state:

bulletthe timer control could reach its assigned time, activate its code and take us into the reaction timing state.
bulleta dishonest user might click the button while it is in the wait state, even though (s)he has been instructed to 'Wait'.

For the time being, let's assume that or user is honest, and let's think about what should happen when the timer 'goes off'. How about this code:

btnReact.Text = "Click me NOW!"
btnReact.BackColor = Color.Pink
tmr1.Enabled = False
StartTime = DateAndTime.Timer

The first line tells the user that his or her reactions are now being timed - we are in the 'reaction timing' state. The third line disables the time for otherwise it will going 'going off' at regular intervals forever. The last line records the start of the reaction time in seconds form, as opposed to the usual hours, minutes and seconds. The reaction time will be found later by subtracting the start time from the finish time (the time when the user finally hits the button).

Let's think now about the code for the 'reaction timing state'. The time that this state was entered has been recorded and we when the button is pressed while in this state we can deduct the start time from the finish time and display the result in the label. How about:

lblTime.Text = "Last time: " & DateAndTime.Timer - StartTime & " seconds."
btnReact.Text = "Click me to start"
btnReact.BackColor = Color.WhiteSmoke

The first line calculates the reaction time by subtracting the start time from the current time in seconds which is obtained from the timer property (not to be confused with the timer control). The reaction time is displayed in the label. The second line takes us back to the initial 'standby state'.

I've provided three blocks of code but two of them are supposed to respond to the same event: the clicking of the button. How will the program know which block of code to run? This is equivalent to asking 'How will the program know what state it is in?' and we have already said the program can know what state it is in by examining the button's caption. We could handle this with an If structure but for a change let's look at an alternative approach called the Select Case structure. This is a good alternative if there are more than two options, which will soon be the case in our program.

Here's what it looks like:

Select Case btnReact.Text
Case "Click me to start"
	lblTime.Text = ""
	btnReact.Text = "Wait..."
	btnReact.BackColor = Color.LightGreen
	tmr1.Interval = 3000 + 4000 * Rnd()
	tmr1.Enabled = True

Case "Click me NOW!"
	lblTime.Text = "Last time: " & _
	DateAndTime.Timer - StartTime & " seconds."
	btnReact.Text = "Click me to start"
	btnReact.BackColor = Color.WhiteSmoke
End Select

The first line tells the program to examine the btnReact.text. The next line tells the computer what to do if the text is equal to "Click me to start" (which means we are in the 'standby state'). A similar line further down the code deals with the case that the text is equal to "Click me NOW!' (which means we are in the reaction timing state).

You should have a working program, then, if you:

  1. double-click the button and paste the above code into the btnReact_Click procedure
  2. double-click the tmr1 timer and paste the corresponding code (higher up the page) into its Timer procedure
  3. we have also used a variable in this program. You'll have to identify it and declare it in the  right place - will you declare it at the beginning of the procedure in which it is used or will you (if it is used in more than one procedure) declare it just after the Public Class wrapper line at the top of the code window?

Test your program - does it work as you expected? It should do, provided you don't cheat, but if you cheat (by clicking too early) then our program does not do a good job of detecting that. So how do we catch the cheats? Cheats are people who click when the button's text is 'Wait...' so all we have to do is include this additional case in our Case structure:

Case "Wait..."
	lblTime.Text = "You cheated!!!"
	btnReact.Text = "Click me to start"
	btnReact.BackColor = Color.WhiteSmoke
	tmr1.Enabled = False

This simply puts a reproachful message in the label then sets the button back to its initial 'standby state'.

Here's the full code for this project in case you got lost. I've included a couple of comments (in green) to help you find your way around:

Going further

Many users would prefer to use the spacebar on the keyboard to control the reaction timer, rather than the  button. To see how to do this, click HERE to move to part 2 of this project.

Going even further

As always, there a many ways that you can improve this project... for extra credit. Here are some ideas:
bullet

Make a funny picture appear when someone cheats.
 

bullet

Make an appropriate sound play if the user cheats or if the user gets a very good time.
 

bullet

Add a few comments to the program to help you or anyone else understand how your program works.
 

bullet

It's annoying to see so many decimal places in the times - can you make them all appear to 2 decimal places only? (Use the Help system to find out about the Format() function.)
 

bullet

Can you include a label that displays the user's best time, or average time, or number of cheat attempts or...  ?

Previous Up Next