2

I seem to be having trouble with my program working and I am finding it hard to understand what I have done wrong.

I need help with the following :

  1. As well as not allowing the user to not enter a number I need it to not allowing the user to enter a string on the column/row section. I was thinking something to do with he ASCII values EDIT this I fixed I think

  2. Saving and loading the game - I had both of these working then I don't know what I did as now they no longer works. I don't know here to call up the save game file.

This is the skeleton code for the AQA As Level. They give you it (it's not illegal!) Please help me!

 Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)
        Dim validColumn, validRow As Boolean ' These are currently set for the user to define them
        Do
            Try
                Do
                    Console.Write("Please enter column: ")
                    Column = Console.ReadLine()
                    If Column < 0 Or Column > 9 Then
                        Console.WriteLine(" That is an Invalid Input")
                    End If
                    validColumn = True     'Sets value to true if the input is valid
                    Console.WriteLine()
                Loop Until Column < 10 And Column >= 0
            Catch Ex As Exception   'If the Exception code is run then the value is set to false and the code loops. 
                validColumn = False
                Console.WriteLine("Enter number from 0 to 9")
            End Try
        Loop Until validColumn = True   'Code will loop until the ValidCol = True
        ' Below is the exact same code, but for the row. 
        Do
            Try
                Do
                    Console.Write("Please enter row: ")
                    Row = Console.ReadLine()
                    If Row < 0 Or Row > 9 Then
                        Console.WriteLine(" That is an invalid Input")
                    End If
                    validRow = True  'Sets value to true if the input is valid
                    Console.WriteLine()
                Loop Until Row < 10 And Row >= 0 'This code above will loop intil row is below than 10 
            Catch Ex As Exception 'If the Exception code is run then the value is set to false and the code loops
                validRow = False
                Console.WriteLine()
                Console.WriteLine("Enter number from 0 to 9")
                Console.WriteLine()
            End Try
            'Code will loop until the ValidRow = True
        Loop Until validRow = True
    End Sub

Other code

'Skeleton Program for the AQA AS Paper 1 Summer 2016 examination 'this code should be used in conjunction with the Preliminary Material 'written by the AQA Programmer Team 'developed in the Visual Studio 2008 programming environment 'Version Number 1.0 Imports System.IO Module Module1 Const TrainingGame As String = "Training.txt" ' Calls the training text file used by new players Structure TShip ' Starts a new structure for use later that includes a stringed name and a size as an integer Dim Name As String Dim Size As Integer End Structure Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) ' This part of the code advances on their column and row selection from earlire Dim Row As Integer Dim Column As Integer GetRowColumn(Row, Column) If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then ' m is miss h is a hit Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") ElseIf Board(Row, Column) = "-" Then ' Message to user to say that they have shot in a sqaure they habe already shot in Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Board(Row, Column) = "m" Else Console.WriteLine("Hit at (" & Column & "," & Row & ").") Board(Row, Column) = "h" End If End Sub
Sub SetUpBoard(ByRef Board(,) As Char)
    Dim Row As Integer
    Dim Column As Integer
    For Row = 0 To 9
        For Column = 0 To 9
            Board(Row, Column) = "-"
        Next
    Next
End Sub

Sub LoadGame(ByVal Filename As String, ByRef Board(,) As Char)
    Dim Row As Integer
    Dim Column As Integer
    Dim Line As String
    Using FileReader As StreamReader = New StreamReader(Filename)
        For Row = 0 To 9
            Line = FileReader.ReadLine()
            For Column = 0 To 9
                Board(Row, Column) = Line(Column)
            Next
        Next
    End Using
End Sub

Sub PlaceRandomShips(ByRef Board(,) As Char, ByVal Ships() As TShip)
    Dim Valid As Boolean
    Dim Row As Integer
    Dim Column As Integer
    Dim Orientation As Char
    Dim HorV As Integer
    For Each Ship In Ships
        Valid = False
        While Not Valid
            Row = Int(Rnd() * 10)
            Column = Int(Rnd() * 10)
            HorV = Int(Rnd() * 2)
            If HorV = 0 Then
                Orientation = "v"
            Else
                Orientation = "h"
            End If
            Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation)
        End While
        Console.WriteLine("Computer placing the " & Ship.Name)
        PlaceShip(Board, Ship, Row, Column, Orientation)
    Next
End Sub

Sub PlaceShip(ByRef Board(,) As Char, ByVal Ship As TShip, ByVal Row As Integer, ByVal Column As Integer, ByVal Orientation As Char)
    Dim Scan As Integer
    If Orientation = "v" Then
        For Scan = 0 To Ship.Size - 1
            Board(Row + Scan, Column) = Ship.Name(0)
        Next
    ElseIf Orientation = "h" Then
        For Scan = 0 To Ship.Size - 1
            Board(Row, Column + Scan) = Ship.Name(0)
        Next
    End If
End Sub

Function ValidateBoatPosition(ByVal Board(,) As Char, ByVal Ship As TShip, ByVal Row As Integer, ByVal Column As Integer, ByVal Orientation As Char)
    Dim Scan As Integer
    If Orientation = "v" And Row + Ship.Size > 10 Then
        Return False
    ElseIf Orientation = "h" And Column + Ship.Size > 10 Then
        Return False
    Else
        If Orientation = "v" Then
            For Scan = 0 To Ship.Size - 1
                If Board(Row + Scan, Column) <> "-" Then
                    Return False
                End If
            Next
        ElseIf (Orientation = "h") Then
            For Scan = 0 To Ship.Size - 1
                If Board(Row, Column + Scan) <> "-" Then
                    Return False
                End If
            Next
        End If
    End If
    Return True
End Function

Function CheckWin(ByVal Board(,) As Char)
    Dim Row As Integer
    Dim Column As Integer
    For Row = 0 To 9
        For Column = 0 To 9
            If Board(Row, Column) = "A" Or Board(Row, Column) = "B" Or Board(Row, Column) = "S" Or Board(Row, Column) = "D" Or Board(Row, Column) = "P" Then
                Return False
            End If
        Next
    Next
    Return True
End Function

Sub PrintBoard(ByVal Board(,) As Char)
    Dim Row As Integer
    Dim Column As Integer
    Console.WriteLine()
    Console.WriteLine("The board looks like this: ")
    Console.WriteLine()
    Console.Write(" ")
    For Column = 0 To 9
        Console.Write(" " & Column & "  ")
    Next
    Console.WriteLine()
    For Row = 0 To 9
        Console.Write(Row & " ")
        For Column = 0 To 9
            If Board(Row, Column) = "-" Then
                Console.Write(" ")
            ElseIf Board(Row, Column) = "A" Or Board(Row, Column) = "B" Or Board(Row, Column) = "S" Or Board(Row, Column) = "D" Or Board(Row, Column) = "P" Then
                Console.Write(" ")
            Else
                Console.Write(Board(Row, Column))
            End If
            If Column <> 9 Then
                Console.Write(" | ")
            End If
        Next
        Console.WriteLine()
    Next
End Sub

Sub DisplayMenu()
    Console.WriteLine("MAIN MENU") ' Main Menu Screen that is displayed to the user
    Console.WriteLine()
    Console.WriteLine("1. Start new game")
    Console.WriteLine("2. Load training game")
    Console.WriteLine(" 3. Change game limit")
    Console.WriteLine("4. Load Saved Game")
    Console.WriteLine("9. Quit")
    Console.WriteLine()
End Sub
Function GetMainMenuChoice() ' Will check if the menu choice is picked can go through
    Dim Choice As Integer ' Dim choice as an integer
    Try
        Console.Write("Please enter your choice: ") ' Ask user to enter their choice for the menu option
        Choice = Console.ReadLine() ' User enters here
        Console.WriteLine()
        If Choice <> "1" And Choice <> "2" And Choice <> "9" And Choice <> "10" Then
            Console.WriteLine("ERROR: Invalid input!") ' If their choice doesnt fit 1, 2 or 9 then it says this message
        End If
        Return Choice ' Return the choice to another part of code
    Catch Ex As Exception
        Console.WriteLine("Please enter a valid input (1, 2,9 or 10)")
    End Try
End Function

Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip)
    Dim GameWon As Boolean = False
    Dim score As Integer = 0
    Dim gamelimit As Integer = 50
    Do
        PrintBoard(Board)
        MakePlayerMove(Board, Ships)
        score = score + 1
        Console.WriteLine("You have taken {0} number of moves,", score)
        GameWon = CheckWin(Board)
        If GameWon Then
            Console.WriteLine("All ships sunk!")
            Console.WriteLine()
        End If
    Loop Until GameWon Or score = 50
    If score = 50 Then
        Console.WriteLine("You used all your moves up. Try again ")

    End If

End Sub
Sub SaveGame(ByRef Board(,) As Char)
    Dim SaveGameWrite As StreamWriter
    SaveGameWrite = New StreamWriter("TEST.txt", True)

    For x As Integer = 0 To 9
        For y As Integer = 0 To 9
            SaveGameWrite.Write(Board(x, y))
        Next
    Next
    SaveGameWrite.Close()
End Sub
Sub LoadSavedGame(ByVal Filename As String, ByRef Board(,) As Char)
    Dim Row, Column As Integer
    Dim Line As String

    Console.WriteLine("Load training game or open a saved game? T for training or S for saved")

    If Console.ReadLine = "" Then
        Console.WriteLine("Enter the filename: ")
        Filename = Console.ReadLine
    End If
    Using FileReader As StreamReader = New StreamReader("C:\" & Filename)
        For Row = 0 To 9
            Line = FileReader.ReadLine()
            For Column = 0 To 9
                Board(Row, Column) = Line(Column)
            Next
        Next
    End Using
End Sub
Sub SetUpShips(ByRef Ships() As TShip)
    Ships(0).Name = "Aircraft Carrier"
    Ships(0).Size = 5
    Ships(1).Name = "Battleship"
    Ships(1).Size = 4
    Ships(2).Name = "Submarine"
    Ships(2).Size = 3
    Ships(3).Name = "Destroyer"
    Ships(3).Size = 3
    Ships(4).Name = "Patrol Boat"
    Ships(4).Size = 2
End Sub

Sub Main()
    Dim Board(9, 9) As Char
    Dim Ships(4) As TShip
    Dim MenuOption As Integer
    Do
        SetUpBoard(Board)
        SetUpShips(Ships)
        DisplayMenu()
        MenuOption = GetMainMenuChoice()
        If MenuOption = 1 Then
            PlaceRandomShips(Board, Ships)
            PlayGame(Board, Ships)
        ElseIf MenuOption = 2 Then
            LoadGame(TrainingGame, Board)
            PlayGame(Board, Ships)
        ElseIf MenuOption = 3 Then
            PlaceRandomShips(Board, Ships)
            PlayGame(Board, Ships)
        End If
    Loop Until MenuOption = 9
End Sub

End Module

Thanks in advance,

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Look at IsNumeric(myString)... its an easy way to check if a string is numeric or not... once you know its numeric, cast it as an integer and the check that is's withing your acceptable range – Mych Apr 22 '16 at 10:16
  • So what part of the code would this be for ? I thought the number part worked. – user6240009 Apr 22 '16 at 10:19
  • You said... 1) As Well as not allowing the user to not enter a number I Need it to not allowing the user to enter a string on the column/row section. - I was thinking something to do with he ASCII values.. which now I've read it a second time I'm confused... if a user is not entering a number or a string what are they entering.... – Mych Apr 22 '16 at 10:24
  • You should really be posting each problem as a separate question - That way if several users each solve one problem, they can all get the reputation. If you have all the problems in one question, an several users answer a different problem, you can only mark one question as answered. Cheers. – David Wilson Apr 23 '16 at 00:41
  • Also, when you say that saving the game doesnt work, you should include what unexpected behaviour you're getting. By the looks of your question, you've had a look at [ask], but missed that bit :) – David Wilson Apr 23 '16 at 00:42

2 Answers2

1

For your first snippet of code, why trouble yourself with ASCII? It's outdated and can be avoided

    Dim validCol As Boolean = False
    Dim column As Integer
    While validCol = False
        Console.Write("Please enter column: ")
        Dim columnValue As String = Console.ReadLine

        If (Integer.TryParse(columnValue, column)) Then
            If column >= 0 AndAlso column < 10 Then
                validCol = True
            Else
                Console.WriteLine("Number must be between 0 and 9")
            End If
        Else
            Console.WriteLine("This is not a number.")
        End If
    End While

    'Do whatever with column

Integer.TryParse will attempt to parse the string given by the user into an Integer, if it fails you'll get your "This is not a number." message, otherwise it will go on to check if the number is within the range you want.

p3tch
  • 1,414
  • 13
  • 29
  • I checked my edited one, and it already works for letters and the wrong numbers now. Is that right or do I still need this ? – user6240009 Apr 22 '16 at 10:32
  • This was more just to show you a way of avoiding ASCII, rather than an actual implementation for your program. Your issue is it's not checking the range correctly now? I'll take a look at your edited code – p3tch Apr 22 '16 at 10:34
  • Now I have changed it I can't see if I have any issues or not or if its okay as it is . – user6240009 Apr 22 '16 at 10:36
0

Your save game sub doesn't specify a path

SaveGameWrite = New StreamWriter("TEST.txt", True)

while your load game does

Using FileReader As StreamReader = New StreamReader("C:\" & Filename)

It's highly likely that your game isn't saved to C:\ , but to a directory in your project folder. You should either, specify the path to C:\ (It's not good to save program data to root of the drive) or save the file to Application.CommonAppDataPath - So the two lines in your code would now be ..

SaveGameWrite = New StreamWriter(Application.CommonAppDataPath & "TEST.txt", True)

and

Using FileReader As StreamReader = New StreamReader(Application.CommonAppDataPath & Filename)
David Wilson
  • 4,369
  • 3
  • 18
  • 31