BACK TO THE TIC-TAC-TOE GAME


It is time to turn your attention to this book's final game project, the Tic-Tac-Toe game. You will create the Tic-Tac-Toe game by following the same five basic development steps that you have followed for all preceding game projects.

Designing the Game

The Tic-Tac-Toe game is played on a single window and is made up of one form and the 18 controls listed in Table 11.1.

Table 11.1: Form Controls for the Tic-Tac-Toe Game

Control Type

Control Name

Description

Panel1

pnlLeft

Used to represent the left vertical bar on the game board

Panel2

pnlRight

Used to represent the right vertical bar on the game board

Panel3

pnlTop

Used to represent the top horizontal bar on the game board

Panel4

pnlBottom

Used to represent the bottom horizontal bar on the game board

PictureBox1

pbxA1

The left PictureBox control on the first row of th board game

PictureBox2

pbxA2

The middle PictureBox control on the first row of the game board

PictureBox3

pbxA3

The right PictureBox control on the first row of the game board

PictureBox4

pbxB1

The left PictureBox control on the second row of the game board

PictureBox5

pbxB2

The middle PictureBox control on the second row of the game board

PictureBox6

pbxb3

The right PictureBox control on the second row of the game board

PictureBox7

pbxC1

The left PictureBox control on the third row of the game board

PictureBox8

pbxC2

The middle PictureBox control on the third row of the game board

PictureBox9

pbxC3

The right PictureBox control on the third row of the game board

Button1

btnPlay

Used to initiate game play

Button2

btnExit

Used to terminate the game

Label1

lbloutput

Identifies the TextBox control that is used to display status messages

TextBox1

txtOutput

Used to display status messages

ImageList1

imlsquares

Stores an indexed collection of graphics used to represent player moves

Step 1: Creating a New Visual Basic Project

The first step in creating the Tic-Tac-Toe game is to open up Visual Basic and create a new project, as outlined below.

  1. If you have not already done so, start up Visual Basic 2005 Express Edition and then click on File and select New Project. The New Project dialog will appear.

  2. Select the Windows Application template.

  3. Type Tic-Tac-Toe as the name of your new application in the Name field located at the bottom of the New Project window.

  4. Click on OK to close the New Project dialog.

Visual Basic will create a new project for you and display a form, which you will then use to design your new game's user interface.

Step 2: Creating the User Interface

The first step in laying out the user interface is to add controls to the form and to move and resize them to the appropriate locations. As you go through each step, make sure that you reference Figure 11.13 so that you'll know where each control needs to be placed and what size it needs to be.

  1. Begin by setting the Size property of the form to 605, 591.

  2. Next, create the grid lines that organize the game board by adding four Panel controls and resizing them as shown in Figure 11.13.

  3. Add PictureBox controls inside each of the game board's nine cells and resize them until they take up almost all of the available space.

  4. Add two Button controls to the bottom left hand corner.

  5. Add a TextBox control to the bottum right-hand side of the game board and resize it as shown in Figure 11.13.

  6. Add a Label control and place it just over the upper left-hand corner of the TextBox control.

  7. Finally, add an ImageList control.

image from book
Figure 11.13: Completing the interface design for the Tic-Tac-Toe game.

At this point, the overall layout of the Tic-Tac-Toe game's user interface is now complete. You can start making changes to the form and control properties.

Step 3: Customizing Form and Control Properties

Let's begin by making the required changes to properties belonging to the form object, as listed in Table 11.2.

Table 11.2: Property Changes for Form 1

Property

Value

Name

frmMain

ControlBox

False

Cursor

Hand

FormBorderStyle

Fixed3D

StartPosition

CenterScreen

Text

Tic-Tac-Toe

Make the property changes shown in Table 11.3 to the Panel controls.

Table 11.3: Property Changes for Panel Controls

Control

Property

Value

Panel1

Name

pnlLeft

 

BackColor

Black

Panel2

Name

pnlRight

 

BackColor

Black

Panel3

Name

pnlTop

 

BackColor

Black

Panel4

Name

pnlBottom

 

BackColor

Black

Make the property changes shown in Table 11.4 to the PictureBox controls.

Table 11.4: Property Changes for Picture Box Controls

Control

Property

Value

PictureBox1

Name

pbxA1

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox2

Name

pbxA2

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox3

Name

pbxA2

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox4

Name

pbxB1

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox5

Name

pbxB2

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox6

Name

pbxB3

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox7

Name

pbxC1

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox8

Name

pbxC2

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

PictureBox9

Name

pbxC3

 

Enabled

False

 

Size

164, 134

 

SizeMode

StretchImage

Make the property changes shown in Table 11.5 to the Button controls.

Table 11.5: Property Changes for Button Controls

Control

Property

Value

Button1

Name

btnPlay

 

Text

Play

Button2

Name

btnExit

 

Text

Exit

Make the property changes shown in Table 11.6 to the Label control.

Table 11.6: Property Changes for Label Control

Control

Property

Value

Label1

Name

lblOutput

 

Font.Bold

True

 

Text

Status

Make the property changes shown in Table 11.7 to the TextBox control.

Table 11.7: Property Changes for Textbox Control

Control

Property

Value

TextBoxl

Name

txtOutput

 

Font.Bold

True

 

Readonly

True

 

TabStop

False

Finally, change the name of the Name property for the ImageList control to imlSquares. Change the ImageList control's ImageSize property to 164, 134 and then add the following bitmap images to its Images property (collection) as shown in Table 11.8. You'll find copies of the Bitmap images required to complete this project, along with the source code, on this book's companion web site.

Table 11.8: Bitmap Images to Add to the Imagelist Controls Images Collection

Property

File

Index No.

Name

X.bmp

0

Name

O.bmp

1

Name

Blank.bmp

2

That's it. The user interface for this game is now complete. Let's move on to the next step and begin adding program code.

Step 4: Adding a Little Programming Logic

The first task in putting together the program code for the Tic-Tac-Toe game is to define class-level variables, as shown below. These variables represent values used by two or more procedures within the application.

 Public Class frmMain     Private strPlayer As String = "" 'Used to track whose turn it is     'Declare variables representing game board cells     Private strpbxA1 As String = "Open"     Private strpbxA2 As String = "Open"     Private strpbxA3 As String = "Open"     Private strpbxB1 As String = "Open"     Private strpbxB2 As String = "Open"     Private strpbxB3 As String = "Open"     Private strpbxC1 As String = "Open"     Private strpbxC2 As String = "Open"     Private strpbxC3 As String = "Open" End Class 

The first statement defines a variable named strPlayer, which is used to keep track of each player's turn. The remaining statements are used to keep track of when each of the game board cells have been selected by a player.

The form's Load event procedure, shown below, is responsible for preparing the game for initial play. This is accomplished by calling on two custom procedures.

 'This procedure executes procedures required to set up the game Private Sub frmMain_Load(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles MyBase.Load      SetGameDefaults() 'Call procedure that sets default assignments      ClearBoard()   'Call procedure that clears the game board End Sub 

The first procedure called by the form's Load event procedure is the SetGameDefaults procedure, shown below. When called, this procedure displays instructions in the TextBox control and sets Player X as the first player.

 'This procedure sets default assignments Private Sub SetGameDefaults()      txtOutput.Text = "Click on Play to begin" 'Display opening message      strPlayer  = "Player X"    'Set Player X to go first End Sub 

The second procedure called by the form's Load event procedure is the ClearBoard procedure, shown below. This procedure is responsible for clearing off the game board by displaying blank squares in each of the game's PictureBox controls. The procedure also sets the values assigned to the variables used to track the status of each game board cell to Open.

 'This procedure clears out the game board Private Sub ClearBoard()      'Load a blank image into each game board cell      pbxAl.Image = imlSquares.Images(2)      pbxA2.Image = imlSquares.Images(2)      pbxA3.Image = imlSquares.Images(2)      pbxB1.Image = imlSquares.Images(2)      pbxB2.Image = imlSquares.Images(2)      pbxB3.Image = imlSquares.Images(2)      pbxC1.Image = imlSquares.Images(2)      pbxC2.Image = imlSquares.Images(2)      pbxC3.Image = imlSquares.Images(2)      'Mark each game board cell as open and available for selection      strpbxA1 = "Open"      strpbxA2 = "Open"      strpbxA3 = "Open"      strpbxB1 = "Open"      strpbxB2 = "Open"      strpbxB3 = "Open"      strpbxC1 = "Open"      strpbxC2 = "Open"      strpbxC3 = "Open" End Sub 

Game play cannot begin until the first player (Player x) clicks on the Button control labeled Play, at which time the btnPlay procedure, shown below, is executed. This procedure is responsible for executing two custom procedures. The first procedure that is called is the ClearBoard procedure, which we have already examined. The second procedure called is the PlayGame procedure.

 'This procedure executes when the button labeled Play is clicked Private Sub btnPlay_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles btnPlay.Click      ClearBoard()  'Call the procedure that clears out the game board      PlayGame()  'Call the procedure that begins game play End Sub 

The PlayGame procedure, shown below, displays a text message in the game's TextBox control in order to identify whose turn it is. In addition, the procedure enables each of the PictureBox controls on the game board. This allows the first player to make the first move. Finally, this procedure disables the btnPlay Button control.

 'This procedure begins game play Private Sub P1ayGame()      'Post message that identifies whose turn it is      txtOutput.Text = strPlayer & "'s turn."     'Enable all game board cells      pbxA1.Enabled = True      pbxA2.Enabled = True      pbxA3.Enabled = True      pbxB1.Enabled = True      pbxB2.Enabled = True      pbxB3.Enabled = True      pbxC1.Enabled = True      pbxC2.Enabled = True      pbxC3.Enabled = True      btnPlay.Enabled = False 'Disable access to the button labeled Play End Sub 

Players can end the game at any time by clicking on the Button control labeled Exit, in which case the btnExit procedure, shown below, is executed.

 'This procedure executes when the button labeled Exit is clicked Private Sub btnExit_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles btnExit.Click      Application.Exit() End Sub 

Each cell on the game board is made up of a PictureBox control. The following statements make up the Click event procedure for the game's first PictureBox control.

 'This procedure executes when a player clicks on the first cell 'in the first row Private Sub pbxA1_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxA1.Click      Dim strGameOver As String = ""  'Used to track game status      'Notify the player if the cell has already been selected      If strpbxA1 <> "Open" Then           txtOutput.Text = "The square has already been taken." & _             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxA1.Image = imlSquares.Images(0)           strpbxA1 = "Player X"      Else           pbxA1.Image = imlSquares.Images(1)           strpbxA1 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

This procedure declares a local variable named strGameOver. Next, an IfThen code block is used to check whether the cell has already been selected by examining the value assigned to the corresponding strpbxA1 variable. If the cell is available, an IfThenElse code block displays a graphic representing the current player in the call. A call is then made to the CheckForWinner function procedure. If the game has been won, the CheckForWinner Function procedure will return a string of either Player X or Player O, which is then passed on to the DetermineGameStatus procedure.

The code for the second PictureBox control in the first row is shown below. As you can see, except for the changes in references that reflect the second cell instead of the first cell, the code is identical to that of the pbxA1_Click procedure.

 'This procedure executes when a player clicks on the second cell 'in the first row Private Sub pbxA2_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxA2.Click      Dim strGameOver As String = ""  'Used to track game status      'Notify the player if the cell has already been selected      If strpbxA2 <> "Open" Then           txtOutput.Text = "The square has already been taken." &_             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxA2.Image = imlSquares.Images(0)           strpbxA2 = "Player X"      Else           pbxA2.Image = imlSquares.Images(1)           strpbxA2 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the third PictureBox control on the first row is shown below.

 'This procedure executes when a player clicks on the third cell 'in the first row Private Sub pbxA3_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxA3.Click      Dim strGameOver As String = ""   'Used to track game status      'Notify the player if the cell has already been selected      If strpbxA3 <> "Open" Then           txtOutput.Text = "The square has already been taken." &_             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxA3.Image = imlSquares.Images(0)           strpbxA3 = "Player X"      Else           pbxA3.Image = imlSquares.Images(1)           strpbxA3 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the first PictureBox control on the second row is shown below.

 'This procedure executes when a player clicks on the first cell 'in the second row Private Sub pbxB1_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxB1.Click      Dim strGameOver As String = ""   'Used to track game status      'Notify the player if the cell has already been selected      If strpbxB1 <> "Open" Then           txtOutput.Text = "The square has already been taken." &_             ControlChars.CrLf &  strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxB1.Image = imlSquares.Images(0)           strpbxB1 = "Player X"      Else           pbxB1.Image = imlSquares.Images(1)           strpbxB1 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the second PictureBox control on the second row is shown below.

 'This procedure executes when a player clicks on the second cell 'in the second row Private Sub pbxB2_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxB2.Click      Dim strGameOver As String = ""   'Used to track game status      'Notify the player if the cell has already been selected      If strpbxB2 <> "Open" Then           txtOutput.Text = "The square has already been taken." &_             ControlChars.CrLf  & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxB2.Image = imlSquares.Images(0)           strpbxB2 = "Player X"      Else           pbxB2.Image = imlSquares.Images(1)           strpbxB2 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the third PictureBox control on the second row is shown below.

 'This procedure executes when a player clicks on the third cell 'in the second row Private Sub pbxB3_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxB3.Click      Dim strGameOver As String = ""   'Used to track game status      'Notify the player if the cell has already been selected      If strpbxB3 <> "Open" Then           txtOutput.Text = "The square has already been taken." & _             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxB3.Image = imlSquares.Images (0)           strpbxB3 = "Player X"      Else           pbxB3.Image = imlSquares.Images(1)           strpbxB3 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the first PictureBox control on the third row is shown below.

 'This procedure executes when a player clicks on the first cell 'in the third row Private Sub pbxC1_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxC1.C1ick      Dim strGameOver As String = ""   'Used to track game status      'Notify the player if the cell has already been selected      If strpbxC1 <> "Open" Then           txtOutput.Text = "The square has already been taken." & _             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxC1.Image = imlSquares.Images(0)           strpbxC1 = "Player X"      Else           pbxC1.Image = imlSquares.Images(1)           strpbxC1 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the second PictureBox control on the third row is shown below.

 'This procedure executes when a player clicks on the second cell 'in the third row Private Sub pbxC2_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxC2.Click      Dim strGameOver As String = "" 'Used to track game status      'Notify the player if the cell has already been selected      If strpbxC2 <> "Open" Then           txtOutput.Text = "The square has already been taken." & _             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxC2.Image = imlSquares.Images(0)           strpbxC2 = "Player X"      Else           pbxC2.Image = imlSquares.Images(1)           strpbxC2 = "Player O"      End If      'Call the procedure that checks to see if the game has been won      strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The code for the third PictureBox control on the third row is shown below.

 'This procedure executes when a player clicks on the third cell 'in the third row Private Sub pbxC3_Click(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles pbxC3.Click      Dim strGameOver As String = ""  'Used to track game status      'Notify the player if the cell has already been selected      If strpbxC3 <> "Open" Then           txtOutput.Text = "The square has already been taken." & _             ControlChars.CrLf & strPlayer & "'s turn."           Return  'Leave the Sub procedure      End If      If strPlayer = "Player X" Then           pbxC3.Image = imlSquares.Images(0)           strpbxC3 = "Player X"      Else           pbxC3.Image = imlSquares.Images(1)           strpbxC3 = "Player O"      End If      'Call the procedure that checks to see if the game has been won       strGameOver = CheckForWinner()      'Call the procedure that switched player turns or displays a      'message declaring a winner      DetermineGameStatus(strGameOver) End Sub 

The CheckForWinner Function procedure, shown below, is responsible for executing a collection of IfThen statements to see if the current player has won the game. This procedure checks each row and column, as well as diagonally. In addition, the procedure checks to see if the two players have tied, which occurs when all nine cells have been selected without a winner being declared.

 'This procedure determines whether the game has been won and by whom Function CheckForWinner()  As String      'Check the first row for a winner      If strpbxA1 = strPlayer Then           If strpbxA2 = strPlayer Then                If strpbxA3 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check the second row for a winner      If strpbxB1 = strPlayer Then           If strpbxB2 = strPlayer Then                If strpbxB3 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check the third row for a winner      If strpbxC1 = strPlayer Then           If strpbxC2 = strPlayer Then                If strpbxC3 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check the first column for a winner      If strpbxA1 = strPlayer Then           If strpbxB1 = strPlayer Then                If strpbxC1 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check the second column for a winner      If strpbxA2 = strPlayer Then           If strpbxB2 = strPlayer Then                If strpbxC2 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check the third column for a winner      If strpbxA3 = strPlayer Then           If strpbxB3 = strPlayer Then                If strpbxC3 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check diagonally from top-left to bottom-right for a winner      If strpbxA1 = strPlayer Then           If strpbxB2 = strPlayer Then                If strpbxC3 = strPlayer Then                     Return strPlayer                End If           End If      End If 'Check diagonally from top-right to bottom-left for a winner      If strpbxA3 = strPlayer Then           If strpbxB2 = strPlayer Then                If strpbxC1 = strPlayer Then                     Return strPlayer                End If           End If      End If      'Check to see if the game has resulted in a tie      Select Case "Open"           'Check each cell to see if it has been assigned to a player           Case strpbxA1           Case strpbxB1           Case strpbxB1           Case strpbxB1           Case strpbxB2           Case strpbxB3           Case strpbxC1           Case strpbxC2           Case strpbxC3           Case Else 'This option executes if all cells have been assigned                 Return "Tie"      End Select      Return "" End Function 

The DetermineGameStatus procedure, shown below, processes a single argument that identifies whether the game has been won, lost, or is still in progress. If the game is still in progress, the SwitchPlayers procedure is called in order to ready the game for the next player's turn. If the game has been won, the procedure enables the Button control labeled Play, calls the DisableSquares procedure, and displays a text message in the game's TextBox control identifying the winner of the game. Finally, if the game has ended in a tie, the btnPlay control is enabled, the DisableSquares procedure is called, and a text message is displayed in the game's TextBox control indicating that a tie has occurred.

 'This procedure determines whether or not the game is over Private Sub DetermineGameStatus(ByVal strGameOver As String)      If strGameOver = "" Then 'The game is not over yet           SwitchPlayers() 'Call procedure that switches player turns           'Post message stating that it is time for players to switch turns           txtOutput.Text = strPlayer & "'s turn."      Else           If strGameOver <> "Tie" Then 'There is a winner               btnPlay.Enabled = True 'Enable the button labeled Play               'Call procedure that disables game board cells               DisableSquares()               'Display game over message               txtOutput.Text = "Game over. " & strGameOver & " has won."          Else 'The game has resulted in a tie               btnPlay.Enabled = True 'Enable the button labeled Play               'Call procedure that disables game board cells               DisableSquares()               'Display game over message               txtOutput.Text = "Game over. There was no winner."          End If      End If End Sub 

The SwitchPlayers procedure, shown below, is very straightforward. When called, it changes the value assigned to the strPlayer variable to reflect the next player.

 'This procedure is responsible for toggling between player turns Private Sub SwitchPlayers()      If strPlayer = "Player X" Then           strPlayer = "Player O"      Else           strPlayer = "Player X"      End If End Sub 

The DisableSquares procedure, shown below, is the last procedure in the application. Its job is to disable each of the game board PictureBox controls in order to keep players from trying to take another turn once the game has ended.

 'This procedure disables all game board cells Private Sub DisableSquares()      pbxA1.Enabled = False      pbxA2.Enabled = False      pbxA3.Enabled = False      pbxB1.Enabled = False      pbxB2.Enabled = False      pbxB3.Enabled = False      pbxC1.Enabled = False      pbxC2.Enabled = False      pbxC3.Enabled = False End Sub 

Step 5: Testing the Execution of the Tic-Tac-Toe Game

OK. That's it. The Tic-Tac-Toe game is now ready to run. Go ahead and run the game by pressing F5 and make sure that everything works like it is supposed to. If you run into any problems, try using the troubleshooting tips presented in this chapter to track down any errors. Once things are in order, pass it around to a few of your friends and ask them what they think.




Microsoft Visual Basic 2005 Express Edition Programming for the Absolute Beginner
Microsoft Visual Basic 2005 Express Edition Programming for the Absolute Beginner
ISBN: 1592008143
EAN: 2147483647
Year: 2006
Pages: 126

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net