I am making a random number guessing program where users try to guess a number between 1 and 100 while receiving whether they were higher or lower. one of the stipulations was that there must be a function to quit the program upon the user entering Q or q so I formatted my loop as such:
$RandomNumber = Get-Random -Minimum 1 -Maximum 101
write-output $RandomNumber
$GuessNumber = 0
While ($RandomNumber -ne $Guess)
{
$Guess = Read-Host -Prompt 'Guess a number between 1 and 100 Or enter Q to quit'
if ($Guess -eq 'q' -or 'Q')
{
Write-output "Thank you for playing"
BREAK
}
if ($Guess -gt 100 -or $Guess -le 1)
{
Write-Output 'Invalid Input please enter a number between 1 and 100'
}
if ($Guess -le $RandomNumber)
{
Write-output 'Your number is lower than the hidden number please guess again'
$GuessNumber = $GuessNumber 1
}
if ($Guess -gt $RandomNumber)
{
Write-output 'Your number is higher than the hidden number please guess again'
$GuessNumber = $GuessNumber 1
}
if ($Guess -eq $RandomNumber)
{
$GuessNumber = $GuessNumber 1
Write-output 'Congratulations you guessed the number in' $GuessNumber 'tries'
}
}
the issue I run into is even when the input is equal to 10 for example it still outputs "Thank you for playing" meaning that if loop has taken effect. I am not sure why this occurs as I'm new to powershell and a reasoning for this happening would be helpful
CodePudding user response:
Replace
if ($Guess -eq 'q' -or 'Q')
with
if ($Guess -eq 'q' -or $Guess -eq 'Q')
CodePudding user response:
The condition is wrong. $Guess -eq 'q' -or 'Q'
returns true always, it should be $Guess -eq 'q' -or $Guess -eq 'Q'
CodePudding user response:
Your error partially comes from -or 'Q'
which evaluates to $true
always:
$false -or 'somestring' # => True
And it's also worth noting, -eq
is case insensitive ('q' -eq 'Q'
is $true
).
The other error comes from comparing a string with an integer. The output from Read-Host
is System.String
in this case:
'50' -gt 100 # => True
'50' -lt 100 # => False
On the other hand, you could make your code more readable using a switch
statement. For input validation you could use a recursive script block to make sure its always right (between 1 and 100 or Q). To break the outer while
loop you can use a labeled break
.
$RandomNumber = Get-Random -Minimum 1 -Maximum 101
$validation = {
$choice = Read-Host 'Guess a number between 1 and 100 Or enter Q to quit'
if($choice -notmatch '^([1-9][0-9]?|100|q)$') {
Write-Warning 'Invalid Input, try again.'
return & $validation
}
$choice
}
$attempts = 0
:outer while($true) {
$choice = & $validation
if($choice -eq 'q') {
# End the Game
'Thanks for Playing'
break
}
$attempts
switch([int]$choice) {
{$_ -gt $RandomNumber} {
"$_ was greater than hidden number"
break
}
{$_ -lt $RandomNumber} {
"$_ was lower than hidden number"
break
}
default {
"You guessed right after $attempts tries, Congratulations!"
break outer
}
}
}