Я студент, пытающийся изучить консольное приложение .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.
Чего я сам не понимаю.
Чтобы расширить комментарий JayV; вы переходите к созданию вот так: file.create(Int32, String)
. Но если вы посмотрите на документацию, предоставленную Джеем, вы увидите, что нет перегрузки функции, которая принимает эту последовательность аргументов. Функция всегда ожидает String
первым и Int32
вторым, потому что вы передаете строку в качестве второго аргумента, vb пытается преобразовать ее в Int32
для вас, что, конечно, не работает в этом случае, потому что это путь к файлу. Таким образом, вы получаете InvalidCast Exception
. Несмотря на это, create
не та функция, которую можно использовать здесь, как указал Кристоф.
Пожалуйста, включите Option Strict. Это процесс из 2 частей. Сначала для текущего проекта. В обозревателе решений дважды щелкните Мой проект. Выберите «Скомпилировать» слева. В раскрывающемся списке Option Strict выберите ON. Во-вторых, для будущих проектов — перейдите в меню «Инструменты» -> «Параметры» -> «Проекты и решения» -> «Параметры по умолчанию для VB». В раскрывающемся списке Option Strict выберите ON. Это убережет вас от ошибок во время выполнения.
@Christoph Кристоф, я пытался сделать то, что вы сказали, и я получил сообщение об ошибке, в котором говорится, что это prntscr.com/nuizrd - для файла сохранения. Затем я также изменил file.write на creat, что дало мне эту ошибку, prntscr.com/nuj2ni. Я также добавил «imports system.io», и это дало мне это сообщение. prntscr.com/nuj101. Я также включил OptionStrict, спасибо за совет :) Я все еще очень запутался в vb, мой учитель «слишком занят, чтобы помочь», и это самая сложная вещь, которую я когда-либо делал сам
Есть много вопросов, но я не хочу их вам портить.
Я определенно рекомендую поставить «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» поверх сценария.)
@ Класс Random использует системные часы для начального числа, поэтому, если у вас нет особой причины, нет необходимости предоставлять начальное значение. Хорошая мысль об использовании одного экземпляра Random.
@Mary: Не уверен, что это все еще то же самое, но в прошлом Random имел гранулярность в 1 секунду, что приводило к высокой вероятности того же двух чисел, если два Random были созданы в течение короткого промежутка времени (что, конечно, не рекомендуется).
Комментарии в очереди. Пожалуйста, прочитайте все комментарии. Эта программа все еще работает не слишком хорошо, но я оставлю ее вам, чтобы привести ее в порядок.
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 не складывается (и я не знаю, как это обойти) В классе мы типа покрытые массивы, но я до сих пор не понимаю, как они работают
Interger.TryParse(String, IntegerVariable) — это функция, доступная в .net. Он проверяет строку, чтобы увидеть, можно ли ее преобразовать в допустимое целое число. Если это возможно, он возвращает True (здесь код не использует возвращаемое значение) и устанавливает IntegerVariable в значение. Если результат будет ложным, значением IntegerVariable будет значение, когда оно было объявлено. Если в объявлении не было указано никакого значения, оно будет равно нулю.
x += 1
увеличит значение x на 1. Это эквивалентно x = x+1
x=+1
присвоит x значение +1. Это было бы так же, как х = 1
Ваш код работает, но говорит, что доступ запрещен ("System.UnauthorizedAccessException: 'Отказано в доступе к пути' C:\X\Code\VB\Challenges\Challenge 1\MasterMind\Saved'"), как я мог обойти это?
Попробуйте указать путь к папке «Документы». Пользователь должен иметь доступ туда.
Пропустил вопрос .ToLower. Он изменяет строку на нижний регистр. Это метод класса .net String. Класс Strings и его методы обеспечивают обратную совместимость с VB6. Для нового кода используйте методы .net.
Кое-что из этого можно найти в гугле. Например, выполните поиск «Integer.TryParse в .net». Посмотрите на строку Microsoft Docs. Сначала это может быть немного сложно, но если вы будете продолжать, вы начнете понимать. Вы можете выбрать вверху страницы, на каком языке вы хотите видеть примеры.
Вопрос X должен быть новым вопросом. Поместите код в свой новый вопрос, чтобы продемонстрировать, что вы не понимаете.
Я просмотрел код Parse и думаю, что теперь понимаю его лучше, спасибо :) Я думаю, что я также начну использовать AndAlso, а не и/или, поскольку это имеет больше смысла для меня, я также попытался переключить путь на путь к моему документу , моя загрузка, и я даже создал нового пользователя, который был настолько «общедоступным», насколько я мог его получить, но я все еще получаю то же сообщение об ошибке.
Что делает Dim CorrectCharacters = TestInput(EasyGuess1, X)? Когда я запускаю его, он показывает, сколько символов одинаковы, как это сделать? и могу ли я включить это для других переменных, а не только для строк?
TestInput — это функция в самом низу листинга кода. Он имеет 2 параметра: целое число, которому мы передали число EasyGuess1 (пользовательский ввод), и строку, которую мы передали X (случайное число, дополненное нулями, чтобы создать строку из 4 символов). Поскольку это функция (в отличие от подпрограммы), она должна что-то возвращать; в этом случае он возвращает целое число, которое присваивается CorrectCharacters. Это специализированная функция, предназначенная только для взаимодействия с вашим кодом. Проверьте это в нижней части кода, чтобы увидеть, как это работает.
Не могли бы вы принять мой ответ, нажав на галочку (галочку) слева от ответа.
Вы неправильно вызываете метод
System.IO.File.Create
. Вы должны создать файл, а затем записать содержимое в этот файл. Взгляните на документы для команды Создавать.