Wrox Programmer Forums
|
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
 
Old November 12th, 2010, 07:44 PM
Authorized User
 
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
Send a message via MSN to SamC
Post 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
 
Old November 12th, 2010, 10:09 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

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.
 
Old November 12th, 2010, 10:19 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

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)
 
Old November 12th, 2010, 10:22 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

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
 
Old November 12th, 2010, 10:24 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

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

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?
 
Old November 13th, 2010, 08:53 AM
Authorized User
 
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
Send a message via MSN to SamC
Default

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
 
Old November 14th, 2010, 12:58 AM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

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)
 
Old November 14th, 2010, 10:37 AM
Authorized User
 
Join Date: Oct 2010
Posts: 29
Thanks: 23
Thanked 0 Times in 0 Posts
Send a message via MSN to SamC
Default

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
 
Old November 14th, 2010, 04:43 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

Quote:
Originally Posted by SamC View Post
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)





Similar Threads
Thread Thread Starter Forum Replies Last Post
Pong Game Help -XM- BOOK: Professional XNA Game Programming: For Xbox 360 and Windows ISBN: 978-0-470-12677-6 4 June 20th, 2007 02:23 PM
How to be a Game Programmer & Animator mmostajab BOOK: Ivor Horton's Beginning Visual C++ 2005 0 April 12th, 2007 03:35 AM
Javascript && keeps turnig into &amp;&amp; ayrton Pro VB.NET 2002/2003 3 June 27th, 2005 03:34 PM
Blackjack Game Apocolypse2005 BOOK: Beginning Visual C++ 6 0 June 7th, 2005 12:08 PM
Linux & KDE & C++ & QT & MYSQL & Kdevelop Munnnki Linux 0 January 2nd, 2005 05:41 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.