Advanced PowerShell Event 10

Last event of the games and I was so busy playing and experimenting with the script that I nearly forgot to send it in!

In this one we have to deal and play a hand of black jack.  One of the confusions I had on this was that I’ve never played blackjack so wasn’t sure of the rules but had played pontoon which has a similar premise but rules that are different enough to be awkward.

The Scripting Guys solution is here http://www.microsoft.com/technet/scriptcenter/funzone/games/solutions08/apssol10.mspx  and the Guest Commentary by //o// is here http://www.microsoft.com/technet/scriptcenter/funzone/games/solutions08/expssol10.mspx

My solution is this

#REQUIRES -Version 2.0
## create deck
cls

function Cardvalue{
param ($count, $card)
    $val = $card -split " "
    switch ($val[0]){
        "Two"{$count += 2}
        "Three"{$count += 3}
        "Four"{$count += 4}
        "Five"{$count += 5}
        "Six"{$count += 6}
        "Seven"{$count += 7}
        "Eight"{$count += 8}
        "Nine"{$count += 9}
        "Ten"{$count += 10}
        "Jack"{$count += 10}
        "Queen"{$count += 10}
        "King"{$count += 10}
        "Ace"{$count += 11}
    }
    $count
}

$Suites = @("Hearts", "Diamonds", "Spades", "Clubs")
$cards = @("Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King","Ace")

$pack = @()
foreach ($suit in $Suites){
    foreach ($card in $cards) {
        $pack += $card, " of ", $suit -join ""
    }
}
## now we need to shuffle the pack
$spack = @()
$random = New-Object System.Random
do
{
    $card = $random.Next(0,52)
    if (($card -le 51) -and ($pack[$card] -ne " ")){
        $spack += $pack[$card]
        $pack[$card] = " "
    }

}while ($spack.Count -lt 52)

## now we deal the cards
$player = @()
$player += $spack[0]
$player += $spack[2]

$dealer = @()
$dealer += $spack[1]
$dealer += $spack[3]

$nextcard = 4

## play the players hand
while ($true){
    $pvalue = 0
    Write-Host "`n`nYour cards:"
    for ($i=0; $i -lt $player.count; $i++){
        Write-Host " ", $player[$i]
        $pvalue = Cardvalue $pvalue $player[$i]
    }
    if ($pvalue -lt 21){
        Write-Host "`n You have ", $pvalue
        Write-Host "`nDealer’s cards:"
        Write-Host " ", $dealer[0]
        $act = Read-Host "`nStay (s) or hit (h) ?"
        if ($act.ToUpper() -eq "S"){
            break
        }
        else {
            $player += $spack[$nextcard]
            $nextcard ++
        }
    }
    else {
        if ($pvalue -eq 21) {
            Write-Host "`n You have ", $pvalue, "You win"
            exit
        }
        else {
            Write-Host "`n You have ", $pvalue, "Sorry, you lose"
            exit
        }
    }
} # end while

# play the dealers hand
while ($true){
    $dvalue = 0
    Write-Host "`n`nDealer’s cards:"
    for ($i=0; $i -lt $dealer.count; $i++){
        Write-Host " ", $dealer[$i]
        $dvalue = Cardvalue $dvalue $dealer[$i]
    }
## the dealer has bust
    if ($dvalue -gt 21){
        Write-Host "`n The dealer has ", $dvalue, "You win"
        break
    }

## dealer has less points so needs another card
    if ($pvalue -gt $dvalue) {
        $dealer += $spack[$nextcard]
        $nextcard ++
    }
## the dealer has the same or more points
    else {
        Write-Host "The dealer has ", $dvalue, "Sorry, you lose"
        break
    }

} #end while

It says I’m using PowerShell V2 but is just for string joining.

One of the rules was that we had to use the full name of the cards.  Rather than carrying the value of the cards around with the name I decided to write a function to calculate the value of a given card.  It splits the incoming card name, uses a switch statement to increase the points counter by the correct value and returns the total points for the cards to the main code.

First off we need to create a deck of cards.  Create an array to hold the suites and an array to hold the card numbers.  Use two nested foreach loops to create the cards and add to the pack (another array).  Now comes the fun bit – shuffling the pack.  I could have created a shuffled pack but this way seemed more straight forward.

Create an empty array and set up a random number generator.  Our original pack has 52 cards which are indexed in the array 0 – 51.  We need to set up our random number generator to create values seemingly between 0 and 52!  This is because the upper bound in the generator is exclusive i.e. it creates values greater and equal to 0 and less than 52.  I used a random in one of the posts on the beginner events and forgot about this – thanks to Jonathan for pointing it out.

Our random number generator enables us to pick out cards at random until we have selected them all.

Create a couple of arrays – for the player and the dealer.  Each player gets two cards first and third to player, second and fourth to dealer.

Starting with the player.  Write out the cards and their value and show one of the dealers cards.  The player wins on 21 loses over 21 points or gets the chance to stay or get a new card.  If the player stays his turn finishes and the dealer takes over.  If the player hits then they get to go round the loop again until they stay or meet the winlose criteria.

If the player decides to stay the dealer takes over.  Similar loop until the dealer gets 21 and wins, gets more than 21 and loses or gets greater than or equal to the points the player had at which point he wins.

It sounds a lot more complicated than it is but was fun to write and even more fun to test :-)


Share this post :

About these ads
This entry was posted in Powershell. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s