2024-05-26 22:08:01 +02:00

128 lines
3.2 KiB
C++

/******************************************************************************
* @file : gridbw.h
* @brief : contains the tetris grid as binary so black and white version
******************************************************************************
* @attention
*
* Copyright (c) muebau 2023
* All rights reserved.</center></h2>
*
******************************************************************************
*/
#ifndef __GRIDBW_H__
#define __GRIDBW_H__
#include <iterator>
#include <vector>
#include "pieces.h"
using namespace std;
class GridBW
{
private:
public:
uint8_t width;
uint8_t height;
std::vector<uint32_t> pixels;
GridBW(uint8_t width, uint8_t height):
width(width),
height(height),
pixels(height)
{
if (width > 32)
{
this->width = 32;
}
}
void placePiece(Piece* piece, uint8_t x, uint8_t y)
{
for (uint8_t row = 4 - piece->getRotation().height; row < 4; row++)
{
pixels[y + (row - (4 - piece->getRotation().height))] |= piece->getGridRow(x, row, width);
}
}
void erasePiece(Piece* piece, uint8_t x, uint8_t y)
{
for (uint8_t row = 4 - piece->getRotation().height; row < 4; row++)
{
pixels[y + (row - (4 - piece->getRotation().height))] &= ~piece->getGridRow(x, row, width);
}
}
bool noCollision(Piece* piece, uint8_t x, uint8_t y)
{
//if it touches a wall it is a collision
if (x > (this->width - piece->getRotation().width) || y > this->height - piece->getRotation().height)
{
return false;
}
for (uint8_t row = 4 - piece->getRotation().height; row < 4; row++)
{
if (piece->getGridRow(x, row, width) & pixels[y + (row - (4 - piece->getRotation().height))])
{
return false;
}
}
return true;
}
void findLandingPosition(Piece* piece)
{
// move down until the piece bumps into some occupied pixels or the 'wall'
while (noCollision(piece, piece->x, piece->landingY))
{
piece->landingY++;
}
//at this point the positon is 'in the wall' or 'over some occupied pixel'
//so the previous position was the last correct one (clamped to 0 as minimum).
piece->landingY = piece->landingY > 0 ? piece->landingY - 1 : 0;
}
void cleanupFullLines()
{
uint8_t offset = 0;
//from "height - 1" to "0", so from bottom row to top
for (uint8_t row = height; row-- > 0; )
{
//full line?
if (isLineFull(row))
{
offset++;
pixels[row] = 0x0;
continue;
}
if (offset > 0)
{
pixels[row + offset] = pixels[row];
pixels[row] = 0x0;
}
}
}
bool isLineFull(uint8_t y)
{
return pixels[y] == (uint32_t)((1 << width) - 1);
}
void reset()
{
if (width > 32)
{
width = 32;
}
pixels.clear();
pixels.resize(height);
}
};
#endif /* __GRIDBW_H__ */