Program a game of bingo with ReportLab and Panda3D for Python

Enable Mouse

When setting up a 3D world it is often just easier to drive the camera around and find the object you are looking for. To do so, remove the disableMouse on line 29 so you can use the built-in camera controls. Once you have found your object, call getCam, which uses pprint (line 63) to output the camera position, which can then be added to the code as needed.


The initTiles section (lines 65-103) creates all of the 3D objects that represent bingo numbers and shuffles them to prepare for calling. To start, self.tiles (line 66) is a list of strings that represent the tiles, and self.tiles3d (line 67) is a dictionary of 3D objects. The key is the string from the self.tiles list.

Bingo tiles start with one letter from the word "BINGO" and then one of 15 numbers. Column 1 (B) goes from 1 to 15, column 2 (I) from 16 to 30, and so on.

Line 69 creates bingoWord = "BINGO", and line 70 initializes total to  . Line 71 loops over each character in bingoWord and creates 15 tiles for each (line 72). The next line then creates the tile by starting with char, the current character from bingoWord, and appending a number created by the loop counter i plus the accumulated total plus 1 (otherwise it would start at 0). Once that is done, total increments by 15 before the loop moves on to the next column.

Lines 76 and 77 are identical to the earlier code in __init__ to load a font. Although the same font loads here, it is included again so that the tiles can be a different font from the title.

Now that you have a list of tiles, they are all turned into 3D objects. Line 79 initializes oldLetter to blank, then line 80 starts the loop over self.tiles. Lines 81-88 create a 3D text object the same way as in __init__, then lines 89-93 check which column a tile is in from its first letter (tile [ 0 ]) and assigns the x for each column.

Line 95 checks to see whether oldLetter has changed (have you moved to the next column?), and if so, lines 96 and 97 set z=20 and update oldLetter. Once that is done, line 99 sets the calculated x and z values with setPos (line 99). The y coordinate is hard-coded at -50 because everything is the same distance from the camera. The setTwoSided line (100) makes it so that if a letter is flipped around backward it will still look right, before decrementing z (line 101) and adding the tile to the self.tiles3d dictionary.

Finally, random.shuffle on line 103 makes sure the tiles are in a random order. Now it's time to play bingo!

Play Bingo!

The callTile section (lines 105-121) calls the tile, which will fly up close to the camera so it appears really big (Figure 4) and say the name of the tile before it flies back down to the other side of the screen to show what is now a called number (Figure 5).

Figure 4: When a number is called, it flies close to the camera and is announced by eSpeak.
Figure 5: After a number is called, it moves to the right half of the screen. Resetting the game will move all numbers to the left again.

Line 106 checks and manual to see whether auto calling is currently active or whether this was called manually. If neither are true, then nothing should be done and the line returns. Then, len ( self.tiles) > 0 checks to make sure tiles are available. If a tile is available, it is stored in tile; otherwise, it encounters the return (lines 108, 109).

Now a couple of things need to be set up to move the tile around. Because this function works on all 60 tiles, the first thing you need to know is the location the tile starts, which you find out by calling getPos on the 3D tile object stored in self.tiles3d (line 111). The new position of the tile will be the x position plus 17, with the same y and z coordinates calculated on line 112.

After that, the lerps (linear interpolations) need to be set up. The lerps' job is, for any slice of time, to calculate where the object is located between two positions. By default, a lerp starts with the object's current position, but you can override that if needed. The lerp also wants to know where to go and how long it takes to get there. You can optionally provide arguments to change the starting position or starting and ending behavior, or even to provide a function to calculate movement on the fly.

Line 114 is the lerp to move the bingo number up close to the camera over two seconds. Line 115 uses the newly calculated x position and flies the number from right in front of the camera down to a position on the right-hand side of the screen.

So far you have told the tile how to move, but you haven't actually moved it yet. You can think of lerps as dance moves. You can learn how to do each step, but then you have to put them together in the right order to perform the whole dance. That is where Sequence comes in. It takes a set of lerps and executes them in the order provided, so line 117 starts with the lerp i that moves from the initial position up to the camera. Then the special Wait function delays for the provided number of seconds, and park finishes in the position on the right side of the screen where you want the tile to land. If this sequence were to be used repeatedly, you could store it in a variable, but here, just call start so the movement begins.

Line 118 calls self.speak in a new thread, which lets the speech and the movement happen at the same time.

To wrap up, append tile to self.calledTiles (line 120) and then, if auto calling is on ( == True), call self.autoCall again (line 121) to schedule callTile to be run in five seconds.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • DIY Scoreboard

    We look at a broadcast video system network that uses Python code to control a video router and check out another program that creates a scoreboard.

  • Panda3D

    Several free game engines are available for Linux users, but programming with them is often less than intuitive. Panda3D is an easy-to-use engine that is accessible enough for newcomers but still powerful enough for the pros at Disney Studios.

  • Top Coder

    Springtime is application time! Mike Schilli, who has experience with job application procedures at companies in Silicon Valley, digs up a question asked at the Google Engineering interview and explains a possible solution in Go.

  • Nerf Target Game

    A cool Nerf gun game for a neighborhood party provides a lesson in Python coding with multiple processors.

  • Tutorials – WM Tiling

    Regular window managers are so 2016 – install a tiling WM and work faster, smarter, and cooler.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More