Skip to content

Instantly share code, notes, and snippets.

@Gunslap
Created April 12, 2022 20:15
Show Gist options
  • Save Gunslap/9e060e62d4df4f598a97324543333744 to your computer and use it in GitHub Desktop.
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?
<#
.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