Something Fun for the Holidays�Random Numbers & Tic Tac Toe

If you are a little like I am you will be doing something with your computer even during the holidays. (More than likely I will be playing Red Alert 2 with the kids, but I may sneak in a little writing.) For you workaholics, I have included a little holiday fare. This way you will be able to do something constructive, yet be able to tear yourself away when company comes knocking on the door.

Random numbers are commonly employed in applications for a wide variety of reasons. In this week's letter let's take a quick look at the Random class in the Common Language Runtime.

The System Namespace

The System namespace is a root namespace in the Common Language Runtime (CLR). One of the classes in the System namespace is the Random class. (That's right! Random numbers are encapsulated in a class in .NET.) Like VB6 random numbers are based on a mathematical algorithm from a finite set of numbers. The result is that you get pseudo-random numbers, but these numbers are random enough for many practical purposes (just not the lottery).

Random numbers in VB.NET can be initialized with or without a seed value and can be constrained to a range of numbers. If the same seed is used then the generated number sequence will be identical. A good strategy is to seed the random numbers using a unique value like the time. Table 1 describes the members of the Random class and is followed by some code examples demonstrating how to use the Random class. Members of the System.Random class.
Member Name Description
Constructs instance of Random Class.
New(ByVal Seed As Integer)
Constructs instance of Random class using Seed value.
Next() As Integer
Returns next integer in the random number sequence.
Next(ByVal maxValue As Integer) As Integer
Returns a positive integer less than maxValue.
Next(ByVal minValue As Integer,
ByVal maxValue As Integer) As Integer
Returns a number greater than or equal to minValue and less than or maxValue.
NextBytes(ByVal buffer() As Byte)
Returns an array of random bytes greater than or equal to 0 and less than Byte.MaxValue.
NextDouble() As Double
Returns a random Double between 0.0 and 1.0.

The basic use of the Random class is to create an instance of the class and use the Random.Next method to acquire subsequent random numbers. You do not have to re-create the Random object each time you want a random number. The following fragments demonstrate several examples of creating Random objects and getting random numbers.

The first example creates a Random object and displays the first random number in a message box.

Dim R As New Random()

The second example creates an instance of the Random class with a seed value of 100.

Dim R As New Random(100)
Dim I As Integer = R.Next()

The third example creates a Random object, seeding the object from a time-related value and requests a number between 1 and 100, excluding the value 100.

Dim R As New Random(Now.Millisecond)
R.Next(1, 100)

A simple Tic-Tac-Toe game is provided in the listing below, providing some more examples of using the Random class.

TicTacToe: Random Number Example

In keeping with the theme of this article, listing 1 contains a prototype of a Tic-Tac-Toe game (see figure). Just in case someone has forgotten, Tic-Tac-Toe is a simple game where players alternate turns, each player marking an empty square until all squares are marked or someone has three consecutive horizontal, vertical, or diagonal squares marked. If no player has three consecutive squares then the game is a Cats game.

The code is all implemented in a Windows application on a form. The computer player is as random as it can be (so everyone has a really good chance of winning).

Figure 1: Tic-Tac-Toe against a Random computer player.

Listing 1: Computer uses Random numbers to determine where to place "O".

1:  Public Class Form1
2:      Inherits System.Windows.Forms.Form
4:  [ Windows Form Designer generated code ]
6:    Private Sub Button2_Click(ByVal sender As System.Object, _
7:    ByVal e As System.EventArgs) Handles Button2.Click
8:    Close()
9:   End Sub
11:  Private Sub Initialize()
13:   Dim I As Integer
14:   For I = 0 To Me.Controls.Count - 1
15:    If (TypeOf Controls(I) Is Label) Then
16:     Dim L As Label = Controls(I)
17:     If (L.Tag <> Nothing) Then
18:      L.Text = ""
19:      Squares(L.Tag) = L
20:     End If
21:    End If
22:   Next
24:  End Sub
26:  Private Random As System.Random
27:  Private Turns As Integer = 0
28:  Private Squares(8) As Label
29:  Private UserTurn As Boolean = False
31:  Private Sub NewGame()
33:   Static UserFirst As Boolean = False
34:   UserFirst = Not UserFirst
35:   Initialize()
36:   Random = New Random(Now.Millisecond)
37:   Turns = 0
39:   If (UserFirst) Then
40:    UserTurn = True
41:   Else
42:    UserTurn = False
43:    ComputerTurn()
44:   End If
45:  End Sub
47:  Private Sub Button1_Click(ByVal sender As System.Object, _
48:   ByVal e As System.EventArgs) Handles Button1.Click
49:   NewGame()
50:  End Sub
53:  Private Sub Form1_Load(ByVal sender As System.Object, _
54:   ByVal e As System.EventArgs) Handles MyBase.Load
56:   NewGame()
58:  End Sub
60:  Private Sub Label9_Click(ByVal sender As System.Object, _
61:   ByVal e As System.EventArgs) Handles Label1.Click, _
62:   Label2.Click, Label3.Click, Label4.Click, Label5.Click, _
63:   Label6.Click, Label7.Click, Label8.Click, Label9.Click
65:   If (Not UserTurn Or IsGameOver()) Then Exit Sub
67:   With CType(sender, Label)
68:    If (.Text = "") Then
69:     .Text = "X"
70:     Turns += 1
72:     If (Not IsGameOver()) Then
73:      UserTurn = False
74:      ComputerTurn()
75:     End If
76:    Else
77:     Beep()
78:    End If
79:   End With
82:  End Sub
84:  Private Function TakeTurn(ByVal Turn As Integer) As Boolean
85:   If (Squares(Turn).Text = "") Then
86:    Squares(Turn).Text = "O"
87:    Return True
88:   Else
89:    Return False
90:   End If
91:  End Function
93:  Private Sub ComputerTurn()
94:   Dim Turn As Integer = Random.Next(0, 9)
96:   While (True)
97:    If (TakeTurn(Turn)) Then Exit While
98:    Application.DoEvents()
99:    Turn = Random.Next(1, 9)
100:   End While
102:   Turns += 1
103:   IsGameOver()
104:   UserTurn = True
106:  End Sub
108:  Private Overloads Function SquaresEqual( _
109:   ByVal First As Integer, _
110:   ByVal Second As Integer, _
111:   ByVal Third As Integer) As Boolean
113:   Return Squares(First).Text = Squares(Second).Text _
114:    And Squares(Second).Text = Squares(Third).Text _
115:    And Squares(First).Text <> ""
117:  End Function
119:  Private Overloads Function SquaresEqual(ByVal First As Integer, _
120:   ByVal Second As Integer, ByVal Third As Integer, _
121:   ByRef Value As String) As Boolean
124:   Dim Result As Boolean
125:   Result = SquaresEqual(First, Second, Third)
127:   If (Result) Then
128:    Value = Squares(First).Text
129:   End If
131:   Return Result
132:  End Function
135:  Private Function IsWinner( _
136:   Optional ByRef Value As String = "") As Boolean
138:   Return SquaresEqual(0, 1, 2, Value) Or _
139:     SquaresEqual(0, 3, 6, Value) Or _
140:     SquaresEqual(0, 4, 8, Value) Or _
141:     SquaresEqual(1, 4, 7, Value) Or _
142:     SquaresEqual(2, 5, 8, Value) Or _
143:     SquaresEqual(2, 4, 6, Value) Or _
144:     SquaresEqual(3, 4, 5, Value) Or _
145:     SquaresEqual(6, 7, 8, Value)
147:  End Function
149:  Private Sub ScoreGame()
150:   Dim Value As String = ""
151:   If (IsWinner(Value)) Then
152:    MsgBox(Value & " is the winner!")
153:   Else
154:    MsgBox("Cats Game!")
155:   End If
156:  End Sub
158:  Private Function IsGameOver() As Boolean
160:   If (Turns >= 9 Or IsWinner()) Then
161:    ScoreGame()
162:    Return True
163:   Else
164:    Return False
165:   End If
167:  End Function
169: End Class

Line 26 declares an uninitialized Random member named Random. Line 36 constructs a Random object, seeding with the number of milliseconds for the current time value, every time a new game is started. Line 94 requests a random number between 0 and 9, including 0 and excluding 9. This represents the 9 possible spaces on the Tic-Tac-Toe board. Line 94 is included in the ComputerTurn method. The computer tries random numbers between 0 and 9 until it finds an empty square to place it's O. After each player's turn the game checks to see if the game is over. If all squares are marked or a player has won then the game is scored.

About the Author

Paul Kimmel is a freelance writer for and Look for cool Visual Basic .Net topics in his upcoming book Visual Basic .Net Unleashed available in January of 2002. Paul founded Software Conceptions, Inc. in 1990. Contact Paul Kimmel at for help building VB.NET applications or migrating VB6 applications to .NET.


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Enterprises are increasingly looking to platform as a service (PaaS) to lower their costs and speed their time to market for new applications. Developing, deploying, and managing applications in the cloud eliminates the time and expense of managing a physical infrastructure to support them. PaaS offerings must deliver additional long-term benefits, such as a lower total cost of ownership (TCO), rapid scalability, and ease of integration, all while providing robust security and availability. This report …

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date