 |
| Visual Basic 2010 General Discussion For any discussions about Visual Basic 2010 topics which aren't related to a specific Wrox book |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the Visual Basic 2010 General Discussion section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

November 12th, 2010, 07:44 PM
|
|
Authorized User
|
|
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
Naughts & Crosses Game
Hi guys,
Earlier this week my computing teacher challenged my and another student to write a game of Naughts & Crosses, or Tic-tac-toe, in a console window . He expected that this would take us a couple of weeks, anyway I've put the Visual Basic.NET source code below. Please tell me if can see any possible exploits for it (my teacher has a penchant for testing things to destruction! ) and how I can improve it.
Code:
Option Strict On
Option Explicit On
Option Infer Off
'By Sam Christy - 12/November/2010
Module Module1
Sub Main()
'Declare Variables
Dim grid(2, 2) As String, turn As String = "", victor As String = "None"
Dim input As Integer = 0, x As Integer = 0, y As Integer = 0, i As Integer = 1
Start:
'Enumerate the grid
grid(0, 0) = "1" : grid(0, 1) = "2" : grid(0, 2) = "3"
grid(1, 0) = "4" : grid(1, 1) = "5" : grid(1, 2) = "6"
grid(2, 0) = "7" : grid(2, 1) = "8" : grid(2, 2) = "9"
'Set the Console's Title and text colour
Console.Title = "Naughts and Crosses - by Sam Christy" : Console.ForegroundColor = ConsoleColor.Yellow
'Begin the game, alternating between X's and O's turn
For i = 1 To 9
If i Mod 2 = 1 Then
turn = "X" 'Crosses' Turn
DrawBoard(grid)
Console.WriteLine("{0}Player Input{0}═════════════{0}", vbNewLine)
InputValidation(input, x, y, grid, turn)
grid(x, y) = "X"
input = 0
End If
If i Mod 2 = 0 Then
turn = "O" 'Naughts' Turn
DrawBoard(grid)
Console.WriteLine("{0}Player Input{0}═════════════{0}", vbNewLine)
InputValidation(input, x, y, grid, turn)
grid(x, y) = "O"
input = 0
End If
victor = CheckGame(grid)
If victor <> "None" Then
Exit For
ElseIf i = 9 Then
Console.Clear()
Console.WriteLine("Draw - You both suck!")
End If
Next
'Announce Winner!
If victor = "O" Then
Console.WriteLine("Naughts Win!")
ElseIf victor = "X" Then
Console.WriteLine("Crosses Win!")
End If
Console.Beep()
DrawBoard(grid)
Console.ReadLine() 'Keep the Console open
Console.Clear()
GoTo Start
End Sub
Sub InputValidation(ByRef input As Integer, ByRef x As Integer, ByRef y As Integer, ByRef grid(,) As String, ByVal turn As String)
Dim d, n, m As Boolean
Do Until d = True And n = True And m = True
'Check that the user input is even an integer
d = True
Console.Write("{0}: ", turn)
Try
input = CInt(Console.ReadLine())
Catch
d = False
DisplayError(1)
End Try
'Check that the number is between 1 and 9
If d = True Then
n = True
If input < 1 Or input > 9 Then
n = False
DisplayError(2)
End If
End If
'Obtain the desired coordinates and evaluate if the move is valid
If d = True And n = True Then
GetCoords(input, x, y)
m = MoveValid(grid, x, y)
If m = False Then
DisplayError(3)
End If
End If
Loop
Console.Clear()
End Sub
Function CheckGame(ByVal grid(,) As String) As String
If grid(0, 0) = grid(0, 1) And grid(0, 1) = grid(0, 2) Then 'Check First Row
Return grid(0, 0) 'Return Victor!
ElseIf grid(1, 0) = grid(1, 1) And grid(1, 1) = grid(1, 2) Then 'Check Second Row
Return grid(1, 0) 'Return Victor!
ElseIf grid(2, 0) = grid(2, 1) And grid(2, 1) = grid(2, 2) Then 'Check Third Row
Return grid(2, 0) 'Return Victor!
ElseIf grid(0, 0) = grid(1, 0) And grid(1, 0) = grid(2, 0) Then 'Check First Column
Return grid(0, 0) 'Return Victor!
ElseIf grid(0, 1) = grid(1, 1) And grid(1, 1) = grid(2, 1) Then 'Check Second Column
Return grid(0, 1) 'Return Victor!
ElseIf grid(0, 2) = grid(1, 2) And grid(1, 2) = grid(2, 2) Then 'Check Third Column
Return grid(0, 2) 'Return Victor!
ElseIf grid(0, 0) = grid(1, 1) And grid(1, 1) = grid(2, 2) Then 'Check First Diagonal
Return grid(0, 0) 'Return Victor!
ElseIf grid(0, 2) = grid(1, 1) And grid(1, 1) = grid(2, 0) Then 'Check Second Diagonal
Return grid(0, 2) 'Return Victor!
Else
Return "None"
End If
End Function
Function MoveValid(ByVal grid(,) As String, ByVal x As Integer, ByVal y As Integer) As Boolean
If grid(x, y) = "O" Or grid(x, y) = "X" Then
Return False
Else
Return True
End If
End Function
Sub GetCoords(ByVal input As Integer, ByRef x As Integer, ByRef y As Integer)
Select Case input
Case Is = 1 : x = 0 : y = 0
Case Is = 2 : x = 0 : y = 1
Case Is = 3 : x = 0 : y = 2
Case Is = 4 : x = 1 : y = 0
Case Is = 5 : x = 1 : y = 1
Case Is = 6 : x = 1 : y = 2
Case Is = 7 : x = 2 : y = 0
Case Is = 8 : x = 2 : y = 1
Case Is = 9 : x = 2 : y = 2
End Select
End Sub
Sub DrawBoard(ByVal grid(,) As String)
Console.WriteLine("┌───┬───┬───┐")
Console.WriteLine("│ {0} │ {1} │ {2} │", grid(0, 0), grid(0, 1), grid(0, 2))
Console.WriteLine("├───┼───┼───┤")
Console.WriteLine("│ {0} │ {1} │ {2} │", grid(1, 0), grid(1, 1), grid(1, 2))
Console.WriteLine("├───┼───┼───┤")
Console.WriteLine("│ {0} │ {1} │ {2} │", grid(2, 0), grid(2, 1), grid(2, 2))
Console.WriteLine("└───┴───┴───┘")
End Sub
Sub DisplayError(ByVal e As Integer)
Select Case e
Case 1
Console.ForegroundColor = ConsoleColor.Red : Console.Beep()
Console.WriteLine("ERROR! Input is invalid,{0}Please enter an integer which is between 1 and 9.", vbNewLine)
Console.ForegroundColor = ConsoleColor.Yellow
Case 2
Console.ForegroundColor = ConsoleColor.Red : Console.Beep()
Console.WriteLine("ERROR! The square you requested doesn't exist,{0}Please enter an integer which is between 1 and 9.", vbNewLine)
Console.ForegroundColor = ConsoleColor.Yellow
Case 3
Console.ForegroundColor = ConsoleColor.Red : Console.Beep()
Console.WriteLine("ERROR! Square is currently occupied,{0}Please choose one which still contains a number.", vbNewLine)
Console.ForegroundColor = ConsoleColor.Yellow
End Select
End Sub
End Module
PS: In the InputValidation Sub-Routine would it have been good programming practice to use a GoTo statement to loop the input process when invalid information is entered?
I ask because my teacher told me to avoid using GoTo Statements, so I deliberately avoided using them for this purpose despite the fact that they would have made it considerably easier.
When should I use them? They must have some purpose else they wouldn't be ubiquitous across programming languages...
__________________
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction."
- Albert Einstein
|
|

November 12th, 2010, 10:09 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
Oh you should ALWAYS use GoTos! On every line you can! Then everybody will laugh at you.
HINT: Don't just *avoid* using GoTo. Forget that such a statement EXISTS!!! Pretend you never heard of it. GoTo was all the rage through about 1975 or so. By the early 1980's it was out of fashion. By the 1990s any professional programmer who used it was assumed to be incompetent. And probably was.
p.s.: Java doesn't have GOTO. JavaScript doesn't have GOTO. VBScript doesn't have GOTO. Why MicroSlop decided to continue to support GOTO in VB.NET is a mystery to me. And one of my friends was a senior architect on the VB.NET team. And he couldn't explain it.
|
|

November 12th, 2010, 10:19 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
How about this?
Code:
Do
Console.Write("{0}: ", turn)
Try
input = CInt(Console.ReadLine())
If input >= 1 And input <= 9 Then
GetCoords(input, x, y)
If MoveValid(grid, x, y) Then
' valid input, valid move, accept it
Exit Do ' this is the only way out of the loop
End If
DisplayError(3) ' invalid move
Else
DisplayError(2) ' invalid input
End If
Catch
DisplayError(1) ' not a number
End Try
Loop
|
|
The Following User Says Thank You to Old Pedant For This Useful Post:
|
SamC (November 13th, 2010)
|
|

November 12th, 2010, 10:22 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
And why repeat so much code?
Code:
For i = 1 To 9
If i Mod 2 = 1 Then turn = "X" Else turn = "O"
turn = "X" 'Crosses' Turn
DrawBoard(grid)
Console.WriteLine("{0}Player Input{0}═════════════{0}", vbNewLine)
InputValidation(input, x, y, grid, turn)
grid(x, y) = turn ' why not reuse this??
input = 0 ' what's this for??? can't see any use
victor = CheckGame(grid)
If victor <> "None" Then
Exit For
ElseIf i = 9 Then
Console.Clear()
Console.WriteLine("Draw - You both suck!")
End If
Next
|
|

November 12th, 2010, 10:24 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
Why are these all ByRef???
ByRef input As Integer, ByRef x As Integer, ByRef y As Integer
|
|

November 12th, 2010, 10:28 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
So, personally, I would have expected you to create a game where the human played the computer. I kind of suspect that's what your instructor had in mind.
Some of the code in there is kind of brute force, but wth.
You're going to hate me for this, but...
What was the point in having the 2D array? Why not just do it with a 1D array so that the square number is the array index? So you don't have to keep converting back and forth?
|
|

November 13th, 2010, 08:53 AM
|
|
Authorized User
|
|
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
Lol that was my initial idea, there must be a reason why I chose to implement a more complex method, but I can't remember it for the life of me.
He said create it for two human players, although I can imagine that when I hand it in my next task will be to add an option for playing against the computer. How would I implement AI?
__________________
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction."
- Albert Einstein
|
|

November 14th, 2010, 12:58 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
Quote:
|
How would I implement AI?
|
The first "computer" I ever designed and built (see footnote) was one that did nothing but play tic-tac-toe (what you Brits unaccountably and much more tediously call "naughts and crosses" <grin/>).
It consisted of nothing but a transformer, a bunch of SPDT (single pole, double throw) switches, some diodes, and some Christmas tree lights.
And it never lost a game. If you played really idiotically, it could even beat you.
HINT: It doesn't take much in the way of Intelligence, Artificial or otherwise, to ensure you never lose a game at whatever-you-call-it.
***********
footnote: That was in 1960 or 1961. The cheapest computer on the market was in the hundreds of thousands of dollars, I believe.
|
|
The Following User Says Thank You to Old Pedant For This Useful Post:
|
SamC (November 14th, 2010)
|
|

November 14th, 2010, 10:37 AM
|
|
Authorized User
|
|
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
I know, the game itself is too simple. I just wondered how I would get the computer to choose its move. Would it essentially be a very long IF statement? How on earth do people write AI for games like chess?
__________________
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction."
- Albert Einstein
|
|

November 14th, 2010, 04:43 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
|
|
Quote:
Originally Posted by SamC
I know, the game itself is too simple. I just wondered how I would get the computer to choose its move. Would it essentially be a very long IF statement?
|
Yes.
Quote:
|
How on earth do people write AI for games like chess?
|
Longer if statements.
Seriously, for chess, one of the basic ways is to assign a point value to each available move and then pick the one with the highest point value. The trick is in trying to look ahead as many moves as possible in assigning the point values...and in "pruning" moves that obviously are bad early on so as to not waste time. And and and...
|
|
The Following User Says Thank You to Old Pedant For This Useful Post:
|
SamC (November 14th, 2010)
|
|
 |