Created
April 12, 2022 20:15
-
-
Save Gunslap/9e060e62d4df4f598a97324543333744 to your computer and use it in GitHub Desktop.
A higher/lower number guessing game WORDLE knockoff in PowerShell... because why not?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
BINERDLE - a binary response number guessing game! | |
.Description | |
Try to guess the number using only "HIGHER" and "LOWER" as clues before your guesses run out! | |
.Parameter numGuesses | |
The number of guesses to give the player. Default 10. | |
.Parameter min | |
The minimum number the random number can be. Default 0. | |
.Parameter max | |
The maximum number the random number can be. Default 1000. | |
.Parameter multiplay | |
If TRUE, disables the once per day mode and uses a different random number each time the game is launched. Default = FALSE | |
.Example | |
# Start a round with default settings | |
Play-Binerdle | |
#> | |
function Play-Binerdle { | |
param( | |
[int] $numGuesses = 10, #number of guesses to give the player | |
[int] $min = 0, #lowest number random num can be | |
[int] $max = 1000, #highest number random num can be | |
[bool] $multiplay = $false #if true, use a totally random number instead of a seed based on date | |
) | |
Write-Host "Welcome to BINERDLE - a binary response number guessing game!" | |
$scoreData = @() | |
#initialize the round: | |
#pick a random number for the player to guess: | |
if($multiplay){ | |
$randomNumber = Get-Random -Minimum $min -Maximum $max | |
} | |
else{ | |
$randomNumber = Get-Random -Minimum $min -Maximum $max -SetSeed $(Get-Date -Date (Get-Date).Date -UFormat %s) | |
$scoreData = Get-ScoreData | |
#Check if the player has already played today | |
if($null -ne $scoreData){ | |
if($(Get-Date $scoreData[-1].Date) -ge $(Get-Date -Date (Get-Date).Date)){ | |
Write-Host "You have already played today, come back tomorrow!" | |
if((Read-Host "View Play Stats? y/n").ToLower() -eq "y"){ | |
$scoreStats = Generate-ScoreStats -scoreData $scoreData | |
Print-ScoreStats -scoreStats $scoreStats | |
} | |
Exit | |
} | |
} | |
} | |
#keep track of guesses so far: | |
$guessTrack = 0 | |
#keep track of the overall guess pattern so far: | |
$guessPattern = "" | |
#set the win condition tracker to false: | |
$win = $false | |
#loop while the player still has remaining guesses and hasn't won | |
while($guessTrack -lt $numGuesses -AND $win -eq $false){ | |
$guess = 0 #reset current guess value | |
$guessTrack += 1 #increment the current guess number by 1 | |
#validate the input as an integer between $min and $max | |
do { | |
$inputValid = [int]::TryParse((Read-Host "$guessTrack/$numGuesses Guess a number between $min and $max"), [ref]$guess) | |
if (-not $inputValid) { | |
Write-Host "your input was not an integer number." | |
} | |
elseif ($guess -lt $min -OR $guess -gt $max) { | |
Write-Host "your input was outside the range of $min - $max" | |
$inputValid = $false | |
} | |
} while (-not $inputValid) | |
#If the player guessed correctly - they win! | |
if($randomNumber -eq $guess){ | |
if($guessTrack -eq 1){Write-Host "Correct! You Won in 1 try!"} | |
else{Write-Host "Correct! You Won in $guessTrack tries!"} | |
$guessPattern += "Win!" | |
$win = $true | |
} | |
#If the player's guess was higher than the answer - write out LOWER | |
elseif ($randomNumber -lt $guess) { | |
Write-Host "LOWER" | |
$guessPattern += "LOWER`n" | |
} | |
#If the player's guess was lower than the answer - write out HIGHER | |
elseif ($randomNumber -gt $guess) { | |
Write-Host "HIGHER" | |
$guessPattern += "HIGHER`n" | |
} | |
} | |
#if the player didn't win, tell them the correct answer | |
if($win -eq $false){ | |
Write-Host "$guessTrack/$numGuesses tries: Correct answer was $randomNumber" | |
$guessPattern = $guessPattern.substring(0,$guessPattern.length -1) #remove the final new line character | |
} | |
#ask the player if they'd like to print out their guess pattern | |
if((Read-Host "Print out guess pattern? y/n").ToLower() -eq "y"){ | |
if($multiplay){ | |
if($win -eq $true){$guessPattern = "BINERDLE $guessTrack/$numGuesses `n" + $guessPattern}else{$guessPattern = "BINERDLE X/$numGuesses `n" + $guessPattern} | |
} | |
else{ | |
if($win -eq $true){$guessPattern = "BINERDLE $(Get-Date -Format "MM/dd/yyyy") $guessTrack/$numGuesses `n" + $guessPattern}else{$guessPattern = "BINERDLE $(Get-Date -Format "MM/dd/yyyy") X/$numGuesses `n" + $guessPattern} | |
} | |
Write-Host $guessPattern | |
Set-Clipboard $guessPattern | |
} | |
#If set to multiplay mode, ask the player if they'd like to play another round. | |
if($multiplay){ | |
if((Read-Host "Play again? y/n").ToLower() -eq "y"){ | |
#relaunch the game with the same parameters | |
Play-Binerdle -numGuesses $numGuesses -min $min -max $max -multiplay $true | |
} | |
} | |
#If set to daily play mode, write out the score and ask the player if they'd like to view their stats | |
else{ | |
$scoreData = Write-ScoreData -guesses $(if($win){$guessTrack}else{"X"}) -scoreData $scoreData | |
if((Read-Host "View Play Stats? y/n").ToLower() -eq "y"){ | |
$scoreStats = Generate-ScoreStats -scoreData $scoreData | |
Print-ScoreStats -scoreStats $scoreStats | |
} | |
} | |
} | |
<# | |
Helper Function to retreive the player's previous score data file | |
#> | |
function Get-ScoreData{ | |
param( | |
[string] $path = (Get-Location).Path #path to scoresheet | |
) | |
if(Test-Path -Path "$path\binerdalscore.csv"){ | |
$scoreData = Import-Csv -Path "$path\binerdalscore.csv" | |
} | |
return $scoreData | |
} | |
<# | |
Helper Function to write out the player's score data file | |
#> | |
function Write-ScoreData{ | |
param( | |
[string] $path = (Get-Location).Path, #path to scoresheet | |
$guesses = "X", | |
$scoreData = @() | |
) | |
#Generate today's | |
$scoreData += [PSCustomObject]@{ | |
Guesses = $guesses | |
Date = (Get-Date (Get-Date).Date -Format "MM/dd/yyy") | |
} | |
#export the file | |
$scoreData | Export-Csv -Path "$path\binerdalscore.csv" -force -NoTypeInformation | |
return $scoreData | |
} | |
<# | |
Helper Function to generate stats from the score data | |
#> | |
function Generate-ScoreStats{ | |
param( | |
$scoreData | |
) | |
$gamesPlayed = @($scoreData).Count | |
$winNum = 0 | |
$currentStreak = 0 | |
$longestStreak = 0 | |
$guessDistribution = @{} | |
#count up the stats | |
foreach($game in $scoreData){ | |
if($game.Guesses -eq "X"){ | |
if($currentStreak -gt $longestStreak){ | |
$longestStreak = $currentStreak | |
} | |
$currentStreak = 0 | |
} | |
else{ | |
$winNum += 1 | |
$currentStreak += 1 | |
} | |
if($guessDistribution.ContainsKey($game.Guesses)){ | |
$guessDistribution[$game.Guesses] += 1 | |
} | |
else{ | |
$guessDistribution.Add($game.Guesses, 1) | |
} | |
} | |
#check if the current streak is the longest streak | |
if($currentStreak -gt $longestStreak){ | |
$longestStreak = $currentStreak | |
} | |
#time till next game starts | |
$nextGameTime = New-TimeSpan -Start $(Get-Date) -End (get-Date).Date.AddDays(1) | |
$nextGameTime = "" + $nextGameTime.Hours + ":" + $nextGameTime.Minutes + ":" + $nextGameTime.Seconds | |
$scoreStats += [PSCustomObject]@{ | |
gamesPlayed = $gamesPlayed | |
winPercent = if($winNum -eq 0){0}else{[math]::Round($winNum/$gamesPlayed*100)} | |
currentStreak = $currentStreak | |
longestStreak = $longestStreak | |
guessDistribution = $guessDistribution | |
nextGameTime = $nextGameTime | |
} | |
return $scoreStats | |
} | |
<# | |
Helper Function to Print the play stats out to the screen | |
#> | |
function Print-ScoreStats { | |
param ( | |
$scoreStats | |
) | |
Write-Host "Games Played: " $scoreStats.gamesPlayed | |
Write-Host "% of Games Won: " $scoreStats.winPercent | |
Write-Host "Current Streak: " $scoreStats.currentStreak | |
Write-Host "Max Streak: " $scoreStats.longestStreak | |
Write-Host "Guess Distribution: " | |
Write-Host $($scoreStats.guessDistribution.GetEnumerator() | Sort-Object Name | Select-Object @{N='Won By Tries #'; E={$_.Name}},@{N='Rounds Played'; E={$_.Value}} | Out-String) | |
Write-Host "Time Until Next Round Available : " $scoreStats.nextGameTime | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment