I had read the question: Bush Wanderer - code intended for teaching and wanted to play with PowerShell. Including the rules of the game from that same question.
Bush Wanderer
Task 1
Create a 5x5 grid of hashes(
#) where the player is anxon the boardPrompt the player to move in either N, E, S or W direction and then reprint the board to show the new position.
Example:
x # # # # # # # # # # # # # # # # # # # # # # # # Which way would you like to move?(N,E,S or W)Task 2
Ensure the player does not move off of the board
Place a hidden chest somewhere on the board at random
End the game when the chest is found
Tell the player how many moves it took to find the chest
Add a visible (but blind) dragon that can teleport around the board at random and will eat you and end your game if it gets you before
you get the chest
Made with PowerShell v4.0. I tried to use an enum but had to create a type using c# which I don't do much. I take advantage of how PowerShell does variable scoping a far bit in this code. From about_scopes
An item you include in a scope is visible in the scope in which it was created and in any child scope
Instead of passing more parameters into my functions I just call them in the parent scope of the script which occurs by default. I also changed the player character to P as that made more sense to me.
I use the PromptForChoice to get the users choice. I had wanted to use that logic and remove the choices that are not available to the user but I can't control the choice index that is returned so I present all choices and will continue to prompt until the user enters a valid direction choice.
If someone reviews this and questions my function names that is all well and good but just know I am trying to adhere to the approved verb list for PowerShell. You are welcome to comment on this either way though. Don't hold back!
# Coordinate template to use to represent object locations in the board jagged array. [char]$bushSymbol = "#" $entityTemplate = @{X=0;Y=0;Character=$bushSymbol} $moves = 0 # Determine the size of the board. $boardSize = 5 # Base direction choices enum Add-Type -TypeDefinition @" public enum Direction { North = 0, South = 1, East = 2, West = 3 } "@ # Game board flags. $gameOver = $false # Initialize Game board entities from template $playerCharacter = $entityTemplate.psobject.Copy() $playerCharacter.Character = "P" $dragonCharacter = $entityTemplate.psobject.Copy() $dragonCharacter.Character = "D" $treasureChest = $entityTemplate.psobject.Copy() # Initialize Game board object as a jagged array $gameBoard = 1..$boardSize | ForEach-Object{,(@($bushSymbol) * $boardSize)} # Menu text. $title = "Which way?" $message = "Which direction would you like to travel?" function Get-PlayerDirectionChoice(){ # This function will present the end user with viable direction choices. Choices can be limited based on current location. $options = ([Direction]::GetNames([Direction]) | ForEach-Object{ New-Object System.Management.Automation.Host.ChoiceDescription "&$_", "Character will attempt to travel $($_.ToLower())" }) return $host.UI.PromptForChoice($title, $message, $options, 0) } function Get-RandomBoardPosition([hashtable]$Entity, [int]$BoardSize){ # Get a random x and y. Number are between 0 and the boardsize minus 1 $entity.X = Get-Random -Maximum $boardSize $entity.Y = Get-Random -Maximum $boardSize } function Test-ValidPlayerDirection([Direction]$choice){ # Function will return a boolean based on the propsed movement of the player character on the board. $result = $true # Assume true # Check to see if the player is on any of the boundries if($playerCharacter.Y -eq 0 -and $choice -eq [Direction]::North){$result = $false} if($playerCharacter.Y -eq ($boardSize - 1) -and $choice -eq [Direction]::South){$result = $false} if($playerCharacter.X -eq ($boardSize - 1) -and $choice -eq [Direction]::East){$result = $false} if($playerCharacter.X -eq 0 -and $choice -eq [Direction]::West){$result = $false} return $result } function Test-EntityCollision($FirstEntity, $SecondEntity){ # Test to see if two entities have the same X and Y values. If they do return true. if($FirstEntity.X -eq $SecondEntity.X -and $FirstEntity.Y -eq $SecondEntity.Y){ return $true } else { return $false } } function Show-GameBoard{ # Function will display on console the current game board layout as populated with it entities. Clear-Host # Edit in the positions of the objects. $gameBoard[$playerCharacter.Y][$playerCharacter.X] = $playerCharacter.Character $gameBoard[$dragonCharacter.Y][$dragonCharacter.X] = $dragonCharacter.Character # Function will draw the game board to the console. 0..($boardSize - 1) | ForEach-Object{$gameBoard[$_] -join " "} } # Get the starting location of all board entities $treasureChest, $dragonCharacter, $playerCharacter | ForEach-Object{ Get-RandomBoardPosition -Entity $_ -BoardSize $boardSize } # Start the game. Show the board Show-GameBoard Do{ # Get the gardener to put the bushes back before the character leaves. $gameBoard[$playerCharacter.Y][$playerCharacter.X] = $bushSymbol # Determine where the player is going to go. $choice = Get-PlayerDirectionChoice if(Test-ValidPlayerDirection ([Direction]::GetName([Direction],$choice))){ # Move the character based on the choice selected. switch($choice){ ([Direction]::North -as [int]) {$playerCharacter.Y = $playerCharacter.Y - 1} ([Direction]::South -as [int]) {$playerCharacter.Y = $playerCharacter.Y + 1} ([Direction]::East -as [int]) {$playerCharacter.X = $playerCharacter.X + 1} ([Direction]::West -as [int]) {$playerCharacter.X = $playerCharacter.X - 1} } # Raise the moves $moves++ # Show the updated board Show-GameBoard # Check to see if the dragon caught the player if(Test-EntityCollision $playerCharacter $dragonCharacter){"The Dragon eats you and you took $moves move(s)."; $gameOver = $true} # Check to see if the player found the treasure if(Test-EntityCollision $playerCharacter $treasureChest){"You found the treasure in $moves move(s)."; $gameOver = $true} # Get the gardener to put the bushes back before the dragon leaves. $gameBoard[$dragonCharacter.Y][$dragonCharacter.X] = $bushSymbol # Move the dragon Get-RandomBoardPosition -Entity $dragonCharacter -BoardSize $boardSize } else { # The choice used would place the player out of bounds. Write-Host "You are blocked by a magical force and cannot move that way." } } While(-not $gameOver) What the start of the game looks like
# # # # # # # # # # # D # # P # # # # # # # # # # Which direction would you like to travel? You are looking for a chest that is hidden in the bushes. Watch out for the clumsy Dragon that will eat you if he catches you. [N] North [S] South [E] East [W] West [?] Help (default is "N"): A sample success screen
# # # # P # # # # # # D # # # # # # # # # # # # # You found the treasure in 14 move(s).