Я хочу сохранить файл в VB.net из количества попыток пользователя

Я студент, пытающийся изучить консольное приложение .Net Framework, и я хочу закодировать случайное число от 0000 до 9999 (как пин-код, который вам нужно угадать). До сих пор мне приходилось устанавливать его как случайное число от 1000 до 9999, так как система не позволяет мне сделать 0000. Кроме того, я хочу сохранить количество попыток, которые пользователь имеет в виде текстового файла, например. если пользователь пытается 50 раз, я хотел бы сказать

Username          Tries 

Я пробовал Randomise() Rnd(*9999) и X = EasyNum.Next(1000, 9999), но тогда я не могу сравнивать, если не конвертирую это в целое число.

Module Module1
    Dim Tries As String = 0
    Dim EasyNum As New Random
    Dim HardNum As New Random
    Dim Attempt As String
    Sub Main()
        Dim Difficulty As String
        Console.WriteLine("Welcome to MasterMind")
        Console.WriteLine("Choose between Easy and Hard difficulty")

        Difficulty = Strings.LCase(Console.ReadLine)
        While Difficulty <> "easy" And Difficulty <> "hard"
            Console.WriteLine("That's not a correct mode")
            Difficulty = Strings.LCase(Console.ReadLine)
        End While
        If Difficulty = "easy" Then
            Easy()
        ElseIf Difficulty = "hard" Then
            Hard()
        End If

    End Sub

    Dim EasyGuess1 As Integer
    Dim EasyGuess2 As Integer
    Dim X As String
    Dim Y As Integer
    Sub Easy()

        Console.WriteLine("You have chosen the easy difficulty")
        Console.WriteLine("You have to guess a 4 Digit number between 1000 and 9999")
        Console.WriteLine("Enter your guess")

        X = EasyNum.Next(1000, 9999)
        Console.WriteLine(X)
        EasyGuess1 = Console.ReadLine
        Tries = +1
        If Mid(CStr(EasyGuess1), 1, 1) = Mid(CStr(X), 1, 1) Then
            Console.WriteLine("You have 1 number correct, try again?")
            Attempt = Strings.LCase(Console.ReadLine)
            While Attempt <> "yes" And Attempt <> "no"
                Console.WriteLine("Enter either yes or no")
                Attempt = Strings.LCase(Console.ReadLine)
            End While
        ElseIf Mid(CStr(EasyGuess1), 2, 1) = Mid(CStr(X), 2, 1) Then
            Console.WriteLine("You have 1 number correct, try again?")
            Attempt = Strings.LCase(Console.ReadLine)
            While Attempt <> "yes" And Attempt <> "no"
                Console.WriteLine("Enter either yes or no")
                Attempt = Strings.LCase(Console.ReadLine)
            End While
        End If
        If Attempt = "yes" Then
            EasyYes()
        ElseIf Attempt = "no" Then
            EasyNo()
        End If
        Console.WriteLine("incorrect")

        Console.ReadKey()
    End Sub
    Sub EasyYes()
        Console.WriteLine("Enter a new guess")
        EasyGuess1 = Console.ReadLine
    End Sub
    Sub EasyNo()
        Dim Save As String
        Dim File As System.IO.File
        Console.WriteLine("Do you want to save your tries? Enter Yes or no")
        Save = Strings.LCase(Console.ReadLine)
        If Save = "yes" Then
            System.IO.File.Create(Tries, "C:\X\Code\VB\Challenges\Challenge 1\MasterMind Test")
        End If
    End Sub
    Sub Hard()

        Console.WriteLine("You have chosen the hard difficulty")

    End Sub
    Sub HardYes()

    End Sub
    Sub HardNo()

    End Sub

End Module

Когда я пытаюсь сохранить попытки, я получаю это:

System.InvalidCastException: 'Conversion from string "C:\X\Code\VB\Challenges\Cha" to type 'Integer' is not valid.' InnerException FormatException: Input string was not in a correct format.

Чего я сам не понимаю.

Вы неправильно вызываете метод System.IO.File.Create. Вы должны создать файл, а затем записать содержимое в этот файл. Взгляните на документы для команды Создавать.

JayV 28.05.2019 00:03

Чтобы расширить комментарий JayV; вы переходите к созданию вот так: file.create(Int32, String). Но если вы посмотрите на документацию, предоставленную Джеем, вы увидите, что нет перегрузки функции, которая принимает эту последовательность аргументов. Функция всегда ожидает String первым и Int32 вторым, потому что вы передаете строку в качестве второго аргумента, vb пытается преобразовать ее в Int32 для вас, что, конечно, не работает в этом случае, потому что это путь к файлу. Таким образом, вы получаете InvalidCast Exception. Несмотря на это, create не та функция, которую можно использовать здесь, как указал Кристоф.

AConfusedSimpleton 28.05.2019 08:45

Пожалуйста, включите Option Strict. Это процесс из 2 частей. Сначала для текущего проекта. В обозревателе решений дважды щелкните Мой проект. Выберите «Скомпилировать» слева. В раскрывающемся списке Option Strict выберите ON. Во-вторых, для будущих проектов — перейдите в меню «Инструменты» -> «Параметры» -> «Проекты и решения» -> «Параметры по умолчанию для VB». В раскрывающемся списке Option Strict выберите ON. Это убережет вас от ошибок во время выполнения.

Mary 28.05.2019 16:25

@Christoph Кристоф, я пытался сделать то, что вы сказали, и я получил сообщение об ошибке, в котором говорится, что это prntscr.com/nuizrd - для файла сохранения. Затем я также изменил file.write на creat, что дало мне эту ошибку, prntscr.com/nuj2ni. Я также добавил «imports system.io», и это дало мне это сообщение. prntscr.com/nuj101. Я также включил OptionStrict, спасибо за совет :) Я все еще очень запутался в vb, мой учитель «слишком занят, чтобы помочь», и это самая сложная вещь, которую я когда-либо делал сам

NeoJoker26 28.05.2019 19:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
144
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Есть много вопросов, но я не хочу их вам портить.

Я определенно рекомендую поставить «Option Strict On» в настройках проекта, чтобы вы сразу видели, где есть ошибки преобразования (строка, присвоенная целому числу и т. д.).

Чтобы сохранить файл, он должен быть примерно таким

If Save = "yes" Then
    File.WriteAllText("C:\X\Code\VB\Challenges\Challenge 1\MasterMind Test", Tries.ToString())
End If

(есть также функции File.Append...).

Класс Random немного сложен, это объект, который предоставляет случайные значения, но сам по себе еще не является случайным значением. Всегда используйте один и тот же случайный объект для всех разных чисел, иначе вы можете получить одно и то же число:

Private Randomizer As New Random(Environment.TickCount)
Private EasyNum As Int32 = Randomizer.Next(0, 10000) '0 to 9999
Private HardNum As Int32 = Randomizer.Next(0, 100000) '0 to 99999

Значение "от" метода Next рандомизатора всегда является включающим, значение "до" исключающим по каким-либо причинам.

Для увеличения переменной используется синтаксис

Tries += 1 

вместо «Попытки = +1»

Чтобы записать число с начальными цифрами, используйте may use

Console.Out.WriteLine($"The correct solution would have been: {EasyNum:0000}")

или

EasyNum.ToString("0000")

(Добавьте «Импорт System.IO» поверх сценария.)

Christoph 28.05.2019 00:34

@ Класс Random использует системные часы для начального числа, поэтому, если у вас нет особой причины, нет необходимости предоставлять начальное значение. Хорошая мысль об использовании одного экземпляра Random.

Mary 28.05.2019 16:35

@Mary: Не уверен, что это все еще то же самое, но в прошлом Random имел гранулярность в 1 секунду, что приводило к высокой вероятности того же двух чисел, если два Random были созданы в течение короткого промежутка времени (что, конечно, не рекомендуется).

Christoph 28.05.2019 21:59
Ответ принят как подходящий

Комментарии в очереди. Пожалуйста, прочитайте все комментарии. Эта программа все еще работает не слишком хорошо, но я оставлю ее вам, чтобы привести ее в порядок.

Module Module1
    Dim Tries As Integer = 0
    'Use only a single instance of Random
    Dim EasyNum As New Random
    'Dim HardNum As New Random
    Dim Attempt As String
    Sub Main()
        Dim Difficulty As String
        Console.WriteLine("Welcome to MasterMind")
        Console.WriteLine("Choose between Easy and Hard difficulty")

        Difficulty = Strings.LCase(Console.ReadLine)
        'AndAlso prevents the second condition from executing if the first condition is true
        While Difficulty <> "easy" AndAlso Difficulty <> "hard"
            Console.WriteLine("That's not a correct mode")
            Difficulty = Strings.LCase(Console.ReadLine)
        End While
        If Difficulty = "easy" Then
            Easy()
            'ElseIf Difficulty = "hard" Then
            '    Hard() 'Not implemented
        End If

    End Sub


    'Dim EasyGuess2 As Integer
    'Dim X As String
    'Dim Y As Integer
    Sub Easy()
        Dim EasyGuess1 As Integer
        Console.WriteLine("You have chosen the easy difficulty")
        Console.WriteLine("You have to guess a 4 Digit number between 1000 and 9999")
        Console.WriteLine("Enter your guess")
        'X = EasyNum.Next(1000, 9999)
        'The next method returns a non-negative integer not a string
        'To get 0 to 9999 with leading zeros do the following
        'Returns a non-negative random integer that is less than the specified maximum.
        Dim X = EasyNum.Next(10000).ToString("0000")
        Console.WriteLine(X)
        'Console.ReadLine returns a String. You should Not assign a String to an Integer
        'EasyGuess1 = Console.ReadLine
        'Never trust a user :-) Use .TryParse to set the variable
        Integer.TryParse(Console.ReadLine, EasyGuess1)
        'This just assigns the value of 1 to Tries
        'Tries = +1
        'If you want to increment Tries
        Tries += 1
        'Let's compare apples and apples
        'If you just convert EasyGuess1 To a string and EasyGuess1 is 54
        'the string is "54" You want a 4 character string
        'If Mid(EasyGuess1.ToString("0000"), 1, 1) = Mid(CStr(X), 1, 1) Then
        '    'but you only compared the first character, what about the rest?
        '    'Mid is aroung for backward compatibility. It should not be used for new code.
        '    'The position Integer is one based which is not at all sympatico with .net
        '    Console.WriteLine("You have 1 number correct, try again?")
        '    Attempt = Strings.LCase(Console.ReadLine)
        '    While Attempt <> "yes" And Attempt <> "no"
        '        Console.WriteLine("Enter either yes or no")
        '        Attempt = Strings.LCase(Console.ReadLine)
        '    End While
        'ElseIf Mid(CStr(EasyGuess1), 2, 1) = Mid(CStr(X), 2, 1) Then
        '    Console.WriteLine("You have 1 number correct, try again?")
        '    Attempt = Strings.LCase(Console.ReadLine)
        '    While Attempt <> "yes" And Attempt <> "no"
        '        Console.WriteLine("Enter either yes or no")
        '        Attempt = Strings.LCase(Console.ReadLine)
        '    End While
        'End If
        Dim CorrectCharacters = TestInput(EasyGuess1, X)
        Console.WriteLine($"You have guessed {CorrectCharacters} correctly. Try again?")
        'Use the .net way. The framework is available to all languages in .net
        'so it will be easier to learn other languages.
        Attempt = (Console.ReadLine).ToLower
        If Attempt = "yes" Then
            EasyYes()
        ElseIf Attempt = "no" Then
            EasyNo()
        End If
        Console.WriteLine("incorrect")

        Console.ReadKey()
    End Sub
    Sub EasyYes()
        Dim guess As Integer
        Console.WriteLine("Enter a new guess")
        'You are doing this twice ???
        'EasyGuess1 = Console.ReadLine
        Integer.TryParse(Console.ReadLine, guess)
        'EasyGuess1 will be 0 if the entry is other than an integer
        'Very nice bu this Sub doesn't do anything
    End Sub
    Sub EasyNo()
        Dim Save As String
        'Unused local variable and if you needed this it is a poor choice for a variable name
        'Dim File As System.IO.File
        Console.WriteLine("Do you want to save your tries? Enter Yes or no")
        Save = Console.ReadLine.ToLower
        If Save = "yes" Then
            'Give the file name an extension.
            'When you pass (String, Integer) to the Create method, the Integer is the number of bytes 
            'buffered for reads And writes to the file.
            'Not exactly what you were expecting.
            'System.IO.File.Create("C:\X\Code\VB\Challenges\Challenge 1\MasterMind Test.txt", Tries)
            'Imports System.IO at top of file
            File.WriteAllText("C:\X\Code\VB\Challenges\Challenge 1\MasterMind Test.txt", Tries.ToString)
        End If
    End Sub
    Sub Hard()
        Console.WriteLine("You have chosen the hard difficulty")
    End Sub

    Private Function TestInput(Guessed As Integer, RandString As String) As Integer
        Dim Correct As Integer
        Dim Guess As String = Guessed.ToString("0000")
        'A String can be a Char array
        'Here we check each character in the 2 strings for equality
        'and if true then increment Correct
        For i = 0 To 3
            If Guess(i) = RandString(i) Then
                Correct += 1
            End If
        Next
        Return Correct
    End Function

End Module

Во-первых, большое спасибо. Во-вторых, я запутался в нескольких вещах. Что означает/делает синтаксический анализ? какая разница между += и =+? Что делает ".toLower"? я не знаю, как сохранить значение, например. если X равно 5, то, если пользователь вводит его снова, тогда я устанавливаю его в x = 0 и снова ввожу пользовательский ввод x, что происходит, так это то, что X не складывается (и я не знаю, как это обойти) В классе мы типа покрытые массивы, но я до сих пор не понимаю, как они работают

NeoJoker26 28.05.2019 19:18

Interger.TryParse(String, IntegerVariable) — это функция, доступная в .net. Он проверяет строку, чтобы увидеть, можно ли ее преобразовать в допустимое целое число. Если это возможно, он возвращает True (здесь код не использует возвращаемое значение) и устанавливает IntegerVariable в значение. Если результат будет ложным, значением IntegerVariable будет значение, когда оно было объявлено. Если в объявлении не было указано никакого значения, оно будет равно нулю.

Mary 28.05.2019 19:25
x += 1 увеличит значение x на 1. Это эквивалентно x = x+1x=+1 присвоит x значение +1. Это было бы так же, как х = 1
Mary 28.05.2019 19:27

Ваш код работает, но говорит, что доступ запрещен ("System.UnauthorizedAccessException: 'Отказано в доступе к пути' C:\X\Code\VB\Challenges\Challenge 1\MasterMind\Saved'"), как я мог обойти это?

NeoJoker26 28.05.2019 22:01

Попробуйте указать путь к папке «Документы». Пользователь должен иметь доступ туда.

Mary 29.05.2019 01:32

Пропустил вопрос .ToLower. Он изменяет строку на нижний регистр. Это метод класса .net String. Класс Strings и его методы обеспечивают обратную совместимость с VB6. Для нового кода используйте методы .net.

Mary 29.05.2019 01:36

Кое-что из этого можно найти в гугле. Например, выполните поиск «Integer.TryParse в .net». Посмотрите на строку Microsoft Docs. Сначала это может быть немного сложно, но если вы будете продолжать, вы начнете понимать. Вы можете выбрать вверху страницы, на каком языке вы хотите видеть примеры.

Mary 29.05.2019 01:42

Вопрос X должен быть новым вопросом. Поместите код в свой новый вопрос, чтобы продемонстрировать, что вы не понимаете.

Mary 29.05.2019 01:44

Я просмотрел код Parse и думаю, что теперь понимаю его лучше, спасибо :) Я думаю, что я также начну использовать AndAlso, а не и/или, поскольку это имеет больше смысла для меня, я также попытался переключить путь на путь к моему документу , моя загрузка, и я даже создал нового пользователя, который был настолько «общедоступным», насколько я мог его получить, но я все еще получаю то же сообщение об ошибке.

NeoJoker26 29.05.2019 20:54

Что делает Dim CorrectCharacters = TestInput(EasyGuess1, X)? Когда я запускаю его, он показывает, сколько символов одинаковы, как это сделать? и могу ли я включить это для других переменных, а не только для строк?

NeoJoker26 29.05.2019 21:00

TestInput — это функция в самом низу листинга кода. Он имеет 2 параметра: целое число, которому мы передали число EasyGuess1 (пользовательский ввод), и строку, которую мы передали X (случайное число, дополненное нулями, чтобы создать строку из 4 символов). Поскольку это функция (в отличие от подпрограммы), она должна что-то возвращать; в этом случае он возвращает целое число, которое присваивается CorrectCharacters. Это специализированная функция, предназначенная только для взаимодействия с вашим кодом. Проверьте это в нижней части кода, чтобы увидеть, как это работает.

Mary 29.05.2019 23:27

Не могли бы вы принять мой ответ, нажав на галочку (галочку) слева от ответа.

Mary 29.05.2019 23:29

Другие вопросы по теме