Create a network of pipes before the water starts to flow in our re-creation of a classic puzzler. Jordi Santonja shows you how.
Pipe Mania, also called Pipe Dream in the US, is a puzzle game developed by The Assembly Line in 1989 for Amiga, Atari ST, and PC, and later ported to other platforms, including arcades. The player must place randomly generated sections of pipe onto a grid. When a counter reaches zero, water starts to flow and must reach the longest possible distance through the connected pipes.
Let’s look at how to recreate Pipe Dream in Python and Pygame Zero. The variable start
is decremented at each frame. It begins with a value of 60*30
, so it reaches zero after 30 seconds if our monitor runs at 60 frames per second. In that time, the player can place tiles on the grid to build a path. Every time the user clicks on the grid, the last tile from nextTiles
is placed on the play area and a new random tile appears at the top of the next tiles. randint(2,8)
computes a random value between 2 and 8.
grid
and nextTiles
are lists of tile values, from 0 to 8, and are copied to the screen in the draw
function with the screen.blit
operation. grid
is a two-dimensional list, with sizes gridWidth=10
and gridHeight=7
. Every pipe piece is placed in grid
with a mouse click. This is managed with the Pygame functions on_mouse_move
and on_mouse_down
, where the variable pos contains the mouse position in the window. panelPosition
defines the position of the top-left corner of the grid in the window. To get the grid cell, panelPosition
is subtracted from pos
, and the result is divided by tileSize
with the integer division //
. tileMouse
stores the resulting cell element, but it is set to (-1,-1)
when the mouse lies outside the grid.
The images
folder contains the PNGs with the tile images, two for every tile: the graphical image and the path image. The tiles
list contains the name of every tile, and adding to it _block
or _path
obtains the name of the file. The values stored in nextTiles
and grid
are the indexes of the elements in tiles
.
The image waterPath
isn’t shown to the user, but it stores the paths that the water is going to follow. The first point of the water path is located in the starting tile, and it’s stored in currentPoint
. update
calls the function CheckNextPointDeleteCurrent
, when the water starts flowing. That function finds the next point in the water path, erases it, and adds a new point to the waterFlow
list. waterFlow
is shown to the user in the draw
function.
pointsToCheck
contains a list of relative positions, offsets, that define a step of two pixels from currentPoint
in every direction to find the next point. Why two pixels? To be able to define the ‘cross’ tile, where two lines cross each other. In a ‘cross’ tile the water flow must follow a straight line, and this is how the only points found are the next points in the same direction. When no next point is found, the game ends and the score is shown: the number of points in the water path, playState
is set to 0
, and no more updates are done.
Get your copy of Wireframe issue 46
You can read more features like this one in Wireframe issue 46, available directly from Raspberry Pi Press — we deliver worldwide.
And if you’d like a handy digital version of the magazine, you can also download issue 46 for free in PDF format.
Website: LINK