Warning

You're browsing the old v2.x documentation. This version is no longer maintained. Click here to go the v3.x documentation.

# Step 3.2.2: Testing if a piece overlaps

The next one is the `overlaps()` function that is to check if a piece overlaps the blocks on the playfield. This is a key function as it has to run every time we're about to move or rotate a piece, to check whether a move is legal.

If you remember the previous steps, we have defined both the shape and the playfield as integers where each bit corresponds to a block. For this reason we can use bitwise operations to check if the piece overlaps. The only difficulty is to extract the individual parts of the piece that's comparable with a single row of the playfield. I'll try to explain this with the help of the following figure:

The blocks in black are parts of the plyfield and the ones in orange are parts of the piece. We will compare 4 times 2 integers, the rows of the palyfield to the rows of the piece. The former is easy, we just take the corresponding row from the `palyfield` array. But for the latter we will need bitwise operations to extract a row from the piece. So here's the plan:

• Since each row in the piece is a 4-bit nibble, we can extract them by masking out the rest of the nibbles: the first row equals `shape & %1111000000000000`, the second row equals `shape & %0000111100000000`, etc…
• We need to align the rows that we have just extracted. So we need to shift the second row 4 bits to the left, the third row 8 bits and the last row 12 bits. This way they'll all be placed in the left end.
• Now we have to shift all of them to right as much as the piece's X position, to be able to compare them with the palyfield.

It is worth to code this operation into a separate function, because we will use it for another purpose later! Here is how it can be coded:

```REM -- Extract a single row from the shape
FUN extract_row(shape, row!, x!)
REM -- Step 1: mask the nibble
REM -- Step 2: move it to the left end
REM -- Step 3: move it right by the piece's  X position
RETURN RSHIFT(LSHIFT(shape & mask[row!], bitpos![row!]), x!)

REM -- Helper data for bitwise calculations
DATA mask[] = %1111000000000000, %0000111100000000, ~
%0000000011110000, %0000000000001111
DATA bitpos![] = 0, 4, 8, 12
ENDFUN```

Unlike in CBM BASIC, the bitwise AND operator in XC=BASIC is the ampersand (`&`) character. The keyword `AND` is different. It is a conditional operator that can be used in an `IF ... THEN` statement.

When we have extracted all rows from the shape, we can compare them with the palyfield easily using the bitwise AND operation. If the AND operation results in true for any bit, it means there was an overlap.

Here is the `overlaps()` function:

```REM -- Check if the piece overlaps the playfield
REM -- at the given position
REM -- Returns 1 or 0 (true or false)
FUN overlaps!(shape_no!, rotation!, x!, y!)
REM -- Get shape by number and rotation
tmp_shape = get_shape(shape_no!, rotation!)
REM -- Check row by row
FOR i! = 0 TO 3
playfield_row = \playfield[i! + y!]
piece_row = extract_row(tmp_shape, i!, x!)
IF piece_row & playfield_row <> 0 THEN RETURN 1
NEXT
RETURN 0
ENDFUN```

Read the above code carefully and notice the following:

• The function returns a byte, so we've appended an `!` to its name
• We need to access the global variable `playfield` from within the function so we must prepend it with a backslash: `\playfield`

Are you still following? Good, let's move on to the next routine.