patternshellMinor
Bush wanderer console game
Viewed 0 times
consolebushgamewanderer
Problem
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(
board
Prompt the player to move in either N, E, S or W direction and then
reprint the board to show the new position.
Example:
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 templa
Bush Wanderer
Task 1
Create a 5x5 grid of hashes(
#) where the player is an x on theboard
Prompt 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 templa
Solution
I like it, I learnt a few things about objects from this. I also really liked the board size can be easily changed.
Immediate Collision
When playing I noticed the Dragon was allowed to start in the same position as the Player. While it's not explicitly stipulated in the tasks, it might be nice to avoid that:
The C# Type
Replace the C# type with:
Replace all instances of
Change parameter type of
New
And testing the direction:
Function full of
Instead of evaluating conditions, setting return values then returning a
The loop was working fine, but it seemed odd the Dragon would move before the next turn and after a collision had been checked. You could reorder the loop from this:
To this:
Immediate Collision
When playing I noticed the Dragon was allowed to start in the same position as the Player. While it's not explicitly stipulated in the tasks, it might be nice to avoid that:
$treasureChest, $dragonCharacter | ForEach-Object {
Get-RandomBoardPosition -Entity $_ -BoardSize $boardSize
}
Do {
Get-RandomBoardPosition -Entity $playerCharacter -BoardSize $boardSize
} Until ($playerCharacter.Y -ne $dragonCharacter.Y -or $playerCharacter.X -ne $dragonCharacter.X)The C# Type
Replace the C# type with:
$Directions = @{
North = 0
South = 1
East = 2
West = 3
}Replace all instances of
[Direction]::North and [Direction]::North -as [Int] with $Directions.North.Change parameter type of
Test-ValidPlayerDirection from [Direction] to [String] (or omit the type altogether).New
Get-PlayerDirectionChoice function:function Get-PlayerDirectionChoice(){
$options = $Directions.GetEnumerator() | % {
New-Object System.Management.Automation.Host.ChoiceDescription $_.Name
}
$host.UI.PromptForChoice($title, $message, $options, 0)
}And testing the direction:
$choice = Get-PlayerDirectionChoice
if(Test-ValidPlayerDirection ($choice)){
...Function full of
IfsInstead of evaluating conditions, setting return values then returning a
[Bool], return the condition itself:function Test-ValidPlayerDirection($choice){
Return -not (
($playerCharacter.Y -eq 0 -and $choice -eq $Directions.North) -or
($playerCharacter.Y -eq ($boardSize - 1) -and $choice -eq $Directions.South) -or
($playerCharacter.X -eq ($boardSize - 1) -and $choice -eq $Directions.East) -or
($playerCharacter.X -eq 0 -and $choice -eq $Directions.West)
)
}
function Test-EntityCollision($FirstEntity, $SecondEntity){
Return $FirstEntity.X -eq $SecondEntity.X -and $FirstEntity.Y -eq $SecondEntity.Y
}The loop was working fine, but it seemed odd the Dragon would move before the next turn and after a collision had been checked. You could reorder the loop from this:
# Get the gardener to put the bushes back before the character leaves.
# Determine where the player is going to go.
# Move the character based on the choice selected.
# Raise the moves
# Show the updated board
# Check to see if the dragon caught the player
# Check to see if the player found the treasure
# Get the gardener to put the bushes back before the dragon leaves.
# Move the dragonTo this:
# Determine where the player is going to go.
# Get the gardener to put the bushes back before the character leaves.
# Move the character based on the choice selected.
# Get the gardener to put the bushes back before the dragon leaves.
# Move the dragon
# Raise the moves
# Show the updated board
# Check to see if the dragon caught the player
# Check to see if the player found the treasureCode Snippets
$treasureChest, $dragonCharacter | ForEach-Object {
Get-RandomBoardPosition -Entity $_ -BoardSize $boardSize
}
Do {
Get-RandomBoardPosition -Entity $playerCharacter -BoardSize $boardSize
} Until ($playerCharacter.Y -ne $dragonCharacter.Y -or $playerCharacter.X -ne $dragonCharacter.X)$Directions = @{
North = 0
South = 1
East = 2
West = 3
}function Get-PlayerDirectionChoice(){
$options = $Directions.GetEnumerator() | % {
New-Object System.Management.Automation.Host.ChoiceDescription $_.Name
}
$host.UI.PromptForChoice($title, $message, $options, 0)
}$choice = Get-PlayerDirectionChoice
if(Test-ValidPlayerDirection ($choice)){
...function Test-ValidPlayerDirection($choice){
Return -not (
($playerCharacter.Y -eq 0 -and $choice -eq $Directions.North) -or
($playerCharacter.Y -eq ($boardSize - 1) -and $choice -eq $Directions.South) -or
($playerCharacter.X -eq ($boardSize - 1) -and $choice -eq $Directions.East) -or
($playerCharacter.X -eq 0 -and $choice -eq $Directions.West)
)
}
function Test-EntityCollision($FirstEntity, $SecondEntity){
Return $FirstEntity.X -eq $SecondEntity.X -and $FirstEntity.Y -eq $SecondEntity.Y
}Context
StackExchange Code Review Q#121887, answer score: 4
Revisions (0)
No revisions yet.