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:
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:
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:
- double-click the button and paste the above code into the
btnReact_Click procedure
- double-click the tmr1 timer and paste the corresponding code
(higher up the page) into its Timer procedure
- 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:
 |
Make a funny picture appear when someone cheats.
|
 |
Make an appropriate sound play if the user
cheats or if the user gets a very good time.
|
 |
Add a few comments to the program to help you or anyone else
understand how your program works.
|
 |
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.)
|
 |
Can you include a label that displays the user's best time,
or average time, or number of cheat attempts or... ? |