Color Guessing Game in Powershell

257 Views Asked by At

I'm working on writing a script in PowerShell for a Color guessing game. The computer randomly picks a color then the player tries to guess the color. I had it working up until I switched some lines of code in the script in an attempt to get these two variables to display correctly. Now, I can't get the code to run past the point where a player declares if they want to play the game or not. My current error is with a do loop, where the console doesn't see that I have a while loop, and so throws an error and won't run the rest of the code.

I managed to get the formatting fixed with Visual Studio Code's format document feature, but I still can't get this one while loop problem figured out.

Write-Host ''; 'Hello again my friend!'; ''
$name = Read-Host "What is your name?"
Write-Host ''; "It's good to see you again, $name! Would you like to guess my favorite color?"; ''
$command = Read-Host @'
"How do you answer? (Yes or No?)"
1. Yes (y)
2. No (n)
3. Quit (q)
Enter Choice
'@
switch -Wildcard ($command) {
    'Y' { 'Yes!'; '' } 
    { $_ -eq 'y' -or $_ -like 'Ye*' } {
        Write-Host "This will be fun! Let us begin!"
        Break
    }
    'N' { 'No!'; '' }
    { $_ -eq 'n' -or $_ -like 'No*' } {
        Write-Host "That's too bad, perhaps another day!"
        Exit
    }
    'Q' { 'Quit'; '' }
    { $_ -eq 'q' -or $_ -like 'qu*' } {
        Write-Host 'So long!'
        Exit
    }
    default {
        'Invalid Command, Please start over.'
        Exit
    }
}

[string]$playagain = 'y'
[int]$playerwins = 0
[int]$compwins = 0
[int]$totalguesses = 0
[int]$playergames = 0
[int]$compgames = 0
[int]$round = 1
[int]$game = 1
$cpuchoice = $color


while ($playagain -eq 'y') { 
    Write-Host ''; "Game $game!"; ''
    $cpuchoice = @([System.Enum]::GetValues([System.ConsoleColor])) | Get-Random -Count 1
        
    do {
        Write-Host "Round $round! What is my favorite color?"; ''
        $listcolor = Read-Host "Would you like to see a list of available colors? Choose 'y' for yes, and 'n' for no."
        if ($listcolor -eq 'y') {
            [System.Enum]::GetValues([System.ConsoleColor])
        }
        elseif ($listcolor -eq 'n') {
            Write-Host "Suit yourself, let's start."
        }
        else {
            Write-Host "Your choice was invalid. Please choose 'y' for yes, or 'n' for no."
        }
        do {
            $playerchoice = Read-host "Enter your guess"
        } while (([System.Enum]::GetValues([System.ConsoleColor])) -notcontains $playerchoice) {

            if ($playerchoice -eq $cpuchoice ) {
                Write-Host "You win, my favorite color is $cpuchoice." -ForegroundColor $cpuchoice; ''
                $playerwins = $playerwins + 1
                $totalguesses = $totalguesses + 1
            }
            elseif ($playerchoice -ne $cpuchoice ) {
                Write-Host "You lose, try again."; ''
                $playerguesses += $playerchoice
                $playerguesses = $playerguesses.Split(',')
                $totalguesses = $totalguesses + 1
                Write-Host "Here are your guesses so far: "
                $playerguesses
                ''
            } 
            $round = $round + 1         
        }                               
        until($playerwins -eq 1) {
            $playergames = $playergames + 1
            Write-Host "You've won this round and have won $playergames games." -ForegroundColor Green
            Write-Host "Your total guesses: $totalguesses."
            Write-Host "Your wins - $playergames" -ForegroundColor Yellow
            Write-Host "Computer wins - $compgames" -ForegroundColor Yellow
            ''
        }
        $playagain = Read-Host "I enjoyed this game. Would you like to challenge again, $name? Y or N"
        while (("y", "n") -notcontains $playagain) {
            if ($playagain -eq "y") {
                Write-Host "I look forward to our next battle!"; ''
                $playerwins = 0
                $compwins = 0
                $game = $game + 1
            }
            elseif ($playagain -eq "n") {
                Write-Host "Thank you for playing!"
                exit
            }
        }
    }        
}                                 

The do loop that causes the error is the one that starts with "Write-Host "Round $round!" after the first while statement.

Any help is appreciated! Thanks!

1

There are 1 best solutions below

2
mclayton On

Your program is being parsed like this:

while ($playagain -eq 'y')
{ 

    # do loop #1
    do
    {

        # do loop #2
        do {
        }
        while (([System.Enum]::GetValues([System.ConsoleColor])) -notcontains $playerchoice)

        # floating script block #1
        # (doesn't execute the scriptblock, but it gets sent to the output stream instead)
        {
           if ($playerchoice -eq $cpuchoice ) {
           ... etc ...
        }

        # try to invoke a cmdlet "until" with 2 parameters
        # i.e. ($playerwins -eq 1) and { ... }
        until ($playerwins -eq 1) {
           $playergames = $playergames + 1
           ... etc ...
        }

        # while loop #1
        while (("y", "n") -notcontains $playagain) {
           ...
        }

    }
    
}

The error is telling you the first do (do loop #1) doesn't have a trailing while or until.

There's no clear and simple fix I can offer to make your code run short of a significant rework because there's a number of issues (e.g. the floating script block #1, the dangling until and the while \ until-less do), but that's what the current error is saying anyway...