Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun – More PowerShell Bingo

Posted on February 4, 2011March 28, 2011

For last week's Friday Fun, I posted a PowerShell script to create a traditional Bingo card. I hoped you would also learn a few PowerShell concepts along the way. This week I've taken this to the next level, and have a complete module that not only creates the card but also let's you play the game. There's a lot going on here with regular expressions, custom view PS1XML files, variable scope and more.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

There's so much here I'm not even sure where to begin. I hope when you download the module you'll take some time to go through the different script files to understand how all the pieces work. I've tried to comment alot to help, as I recommend you do in your scripts. But let me hit a few key PowerShell concepts and techniques.

First off, I now have a function to generate a Bingo number, using the traditional Bingo values. The Get-BingoNumber function breaks a few rules which is why I want you to understand. The challenge was to ensure that every number drawn was unique and had not been played before which meant I needed some mechanism to keep track of the draw history. Normally I would use a variable array. But everytime I call the function, I would end up with a new scope and new variables. This is a situation where specifying a scope comes in handy.

The Get-BingoNumber function creates a variable, $Master, in the global scope of all possible values.
[cc lang="PowerShell"]
#if no global variable for $master is found then create it
if (-Not $global:master)
{
#generate unique arrays of numbers for each letter,
#create a letter/number combination
#and then randomize again for good measure
$B=1..15 | Get-Random -count 15 | foreach {write "B$_"} | Get-Random -count 15
$I=16..30 | Get-Random -count 15 | foreach {write "I$_"} | Get-Random -count 15
$N=31..45 | Get-Random -count 15 | foreach {write "N$_"} | Get-Random -count 15
$G=46..60 | Get-Random -count 15 | foreach {write "G$_"} | Get-Random -count 15
$O=61..75 | Get-Random -count 15 | foreach {write "O$_"} | Get-Random -count 15

#build a master array of all possible numbers
$global:master=$B+$I+$N+$G+$O
}
[/cc]
The function then draws a random element from this variable.
[cc lang="PowerShell"]
#create a randomized array of $master if it doesn't already exist
if (-not $global:draw)
{
$global:draw= $global:master | Get-Random -count $global:master.count
}
#Draw each number from $draw starting at the beginning of the array
Write-Output $global:draw[0]
#remove the first element from $draw
$global:draw=$global:draw[1..$($global:draw.count)]
[/cc]
This is the value that is written to the pipeline. Without specifying the global scope I would get new variables every time. Using a variable with the scope prefix let's PowerShell know I understand what I am doing.

For the Bingo card object, I realized I didn't have to rely on Format-Table or tweaking the output. I could use a custom format file.
[cc lang="PowerShell"]




Bingo.Card

Bingo.Card





4



4



4



4



4






B


I


N


G


O








[/cc]
When this file is loaded from the module, or using Update-FormatData, my bingo card objects are properly formatted. But there was one extra trick I needed for this to work. Originally I was creating the bingo card using New-Object.
[cc lang="PowerShell"]
$obj=New-Object -TypeName PSObject -Property @{
B=$b[$x]
I=$i[$x]
N=$n[$x]
G=$g[$x]
O=$o[$x]
}
[/cc]
But this meant the object type was a PSCustomObject so my original version of my format ps1xml file applied to all custom objects as long as the module was loaded. The trick was to assign a new object type to this object.
[cc lang="PowerShell"]
#add a custom type name to this object for formatting
$obj.psobject.Typenames[0]="Bingo.Card"
[/cc]
You'll notice that this type name matches the type name in the ps1xml file. Now whenever I write a card to the pipeline it is automatically formatted the way I want.

When it comes to playing the game, I wrote a new function called Invoke-Bingo which has an alias of Play-Bingo (since Play is not a valid verb but it is OK for an alias). The function uses a number of parameter sets because you can play 3 different ways. In the default or Normal manner a new card is written to your console and a prompt awaits your first number. At the same time a second PowerShell window is open that loads the module and launches the Get-PowerShellNumber function in Prompt mode. You get numbers from one session and enter them in the other.

Because the game displays winning numbers (look at the Test-Bingo.ps1 file to see how), I wanted to make sure only valid numbers were entered. So I used a set of regular expressions to validate.
[cc lang="PowerShell"]
#use regular expression to make sure a valid call was made
Switch -regex ($call) {
"^[bB]([1-9]|[1][0-5])$" {$valid=$True}
"^[iI]([1][5-9]|[2][0-9]|[3][0])$" {$valid=$True}
"^[nN]([3][1-9]|[4][0-5])$" {$valid=$True}
"^[gG]([4][6-9]|[5][0-9]|[6][0])$" {$valid=$True}
"^[oO]([6][1-9]|[7][0-5])$" {$valid=$True}
Default {
$valid=$False
Write-Warning "$Call is an invalid option. Please try again."
}
} #Switch
[/cc]

You can also use -CardOnly to skip the draw session. Use this if you are playing along with your co-workers and someone else is drawing numbers. By the way, the free space is now randomly inserted and you can have up to 3. Use -Free when playing.

Lastly, I also created an AutoPlay mode. that automatically draws a number and updates the card whenever there is a match. Play continues until a Bingo is made. You can specify a sleep interval between draws. The default is 3 with a minimum of 1. Here's a short 30 second clip of an automatic game. The game itself took a little over a minute.
[kml_flashembed publishmethod="static" fversion="8.0.0" movie="https://jdhitsolutions.com/blog/wp-content/uploads/2011/02/PowerShellBingo.swf" width="640" height="374" targetclass="flashmovie" play="false" quality="high" base="https://jdhitsolutions.com/blog/wp-content/uploads/2011/02/" fvars="autostart=false;thumb=FirstFrame.png;thumbscale=45;color=0x1A1A1A,0x1A1A1A"]

Get Adobe Flash player

[/kml_flashembed]

Download thePowerShellBingo module. Extract the folder to Documents\WindowsPowerShell\Modules and then import the PowerShellBingo module. Enjoy, and I hope you learn a few things along the way.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

1 thought on “Friday Fun – More PowerShell Bingo”

  1. Pingback: Tweets that mention Friday Fun – More PowerShell Bingo | The Lonely Administrator -- Topsy.com

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d