Video Poker in PowerShell

In between real work, and to learn a bit about PowerShell since I don’t use it often, I created a video poker game. It’s rough and I don’t have time to make it pretty or add a GUI, but maybe it will inspire someone else? I also know very little about poker…

I took a couple things out as it caused html entities to appear instead of the actual character. First you need some new lines “`n” in $message on line 137. Next you need to change line 96 to $Suites = @(“♠”,”♣”,”♥”,”♦”)

# Around 4 hours coding and around 130 lines of code. Needs to be smaller and cleaner, and tested, but...
# Images 1d.png (A) to 13d.png, d being diamonds - 
# This is the console version and I'll likely never make a GUI.
#Param ( [string]$Draw = 5)
Function Get-Score($hand) {
    #$win = $hand.ToArray()
    $isWin = $false
    $isFlush = $false

    $score = 0
    $match_rank = @()
    $match_rank_hash = @{}
    $match_loyalty = @{}
    foreach ($card in $hand) {

        $rank = $card.Substring(0,$card.Length-1) 
        $suite = $card.Substring($card.get_Length()-1)

        if (-not $match_loyalty.ContainsKey($suite)) {
            $match_loyalty[$suite] = 0
        }
        $match_loyalty[$suite] += 1

        if (-not $match_rank_hash.ContainsKey($rank)) {
            $match_rank_hash[$rank] = 0
        }
        $match_rank_hash[$rank] += 1

        $match_rank += $rank
    }

    $straight_high = @("A","10","J","Q","K")
    $straight_low = @("9","10","J","Q","K")

    ForEach ($k in $match_loyalty.Keys) {
        if ($match_loyalty[$k] -eq 5) {
            $isFlush = $true
            break
        }
    }

    if (-not (Compare-Object [string]$match_rank [string]$straight_high)) {
        $score += 500
        if ($isFlush) {
            $score += 400
        }
    }

    elseif (-not (Compare-Object [string]$match_rank [string]$straight_low)) {
        $score += 450
        if ($isFlush) {
            $score += 400
        }
    }

    elseif (-not (Compare-Object -ReferenceObject $match_rank -DifferenceObject $straight_high)) {
        $score += 200
        if ($isFlush) {
            $score += 400
        }
    }

    elseif (-not (Compare-Object -ReferenceObject $match_rank -DifferenceObject $straight_low)) {
        $score += 150
        if ($isFlush) {
            $score += 400
        }
    }

    else {
        if ($isFlush) {
            $score += 400
        }  
        else {
            foreach ($k in $match_rank_hash.keys) {
                if ($match_rank_hash[$k] -eq 4) {
                    $score += 45
                } else {
                    if ($match_rank_hash[$k] -eq 2) {
                        $score += 5
                    }

                    if ($match_rank_hash[$k] -eq 3) {
                        $score += 10
                    }
                }
            }
        }
    }
    return $score
}

Function Build-Deck($filter) {
    [System.Collections.ArrayList]$Deck = @()
    $Cards = @("a","j","q","k")
    $Suites = @("s","c","h","d")
    2..10 | Foreach { $Cards += $_ }

    ForEach ($suite in $Suites) {
        ForEach ($card in $Cards) { 
            $card = $card.ToString() + "" + $suite.ToString()  # + ".png"
 
            if ($filter -ne $null) {

                if ($filter.Contains($card)) {
                    continue 
                }
            }
            $Deck += $card.ToUpper()
        }
    }
    return $Deck
}
    
Function Deal-Cards($draw) {

    $deck = Build-Deck
    [System.Collections.ArrayList]$deltCards = @()

    $deltCards = $deck | Get-Random -Count $draw # OR 7
    return $deltCards
}

Function Redeal-Cards([System.Collections.ArrayList]$delt, $held) {
    
    $deck = Build-Deck -filter $delt
    $math = 0
    foreach ($idx in $held) {
        [int]$index = $idx.ToString()
        $deltCard = $deck | Get-Random -Count 1
        $delt[$index] = $deltCard
    }
    return $delt
}

$GAME = $true # set for testing but could be selector for GUI version.
$message = "Enter or Y will deal a new hand. Enter the number for each card(s) you wish to replace followed by enter. Q will exit the game."

if ($GAME) {
    $score = 95
    $Hold = @()
    $Dealt = Deal-Cards -draw 5

    Clear-Host
    Write-Host $message

    # check win
    $gotScore = Get-Score $Dealt
    if ($gotScore -gt 0) {
        $score += $gotScore 
         Write-Host ("SCORE: $" + $score.ToString() + " won " + $gotScore)
         Write-Host $Dealt
         $Prompt = "Deal? "

    } else {
        Write-Host ("SCORE: $" + $score.ToString())
        Write-Host "$Dealt"
        Write-Host "[0][1][2][3][4]"
        $ReDealt = @()
        $Prompt = "Toss "
    }
    
    Do {

        if (score -eq 0) {
            Clear-Host
            Write-Host "You Lose!"
            break
        }
       
        $UserInput = Read-Host $Prompt
        if ($UserInput.ToLower() -eq "q") { 
            Clear-Host
            break 
        } 

        try {
            Clear-Host
            if ($UserInput.ToLower() -ne "q" -or $UserInput.ToLower() -ne "y" -or $UserInput.ToLower() -ne "n") {
                # This is a new deal.
                if ($UserInput.Length -eq 0 -or $UserInput -eq "y") {
                    
                    $Dealt = Deal-Cards -draw 5
                    $score = $score -= 5

                    # check win
                    $gotScore = Get-Score $Dealt
                    if ($gotScore -gt 0) {
                        $score += $gotScore 

                        $Prompt = "Deal?"
                        $ReDealt = Redeal-Cards -delt $Dealt -held $Hold
                        Write-Host $message
                        Write-Host ("SCORE: $" + $score.ToString() + " won " + $gotScore)
                        Write-Host "$ReDealt"
                        $ReDealt = @()
                        $Hold = @()
                    } else {
                        $Prompt = "Toss "
                        Write-Host $message
                        Write-Host ("SCORE: $" + $score.ToString())
                        Write-Host "$Dealt"
                        Write-Host "[0][1][2][3][4]"
                    }
                } 
                # This is a redeal of new cards.
                if ($UserInput.Length -gt 0) {
                    $tmp = $UserInput.ToCharArray()
                    foreach ($char in $tmp) {
                         $Hold += $char
                    }
                    Write-Host $message
                    $Prompt = "Deal?"
                    $ReDealt = Redeal-Cards -delt $Dealt -held $Hold
                    # check win
                    $gotScore = Get-Score $ReDealt
                    if ($gotScore -gt 0) {
                        $score += $gotScore
                        Write-Host ("SCORE: $" + $score.ToString() + " won " + $gotScore)
                    } else {
                        Write-Host ("SCORE: $" + $score.ToString())
                    }
                    Write-Host "$ReDealt"
                    $ReDealt = @()
                    $Hold = @()
                }
            }
        } catch {
            Write-Host "Cut that out!"
            continue
        }

    } Until ($UserInput.ToLower() -eq "q" -or $UserInput.ToLower() -eq "n") 
} else {
    [System.Collections.ArrayList]$Hold = @()
    $UserInput = "024"
    $tmp = $UserInput.ToCharArray()
    foreach ($char in $tmp) {
        if ($char -ne $null) {
            $Hold += $char
        }
    }

    $Dealt = Deal-Cards -draw 5
    Write-host "New hand " + $Dealt
    $ReDealt = Redeal-Cards -delt $Dealt -held $Hold
    Write-Host "Redeal " + $ReDealt
}