const int COLS = 8, ROWS = 8, CELL = 64;
const int GEM_TYPES = 5;
struct Cell { int type = -1; };
struct Board {
Cell cells[ROWS][COLS];
void Fill() {
for (int r = 0; r < ROWS; ++r)
for (int c = 0; c < COLS; ++c)
cells[r][c].type = rand() % GEM_TYPES;
}
Cell& At(int r, int c) { return cells[r][c]; }
};
Piece matching logic
struct Match { int row, col, len; bool horizontal; };
std::vector<Match> FindMatches(const Board& board) {
std::vector<Match> matches;
// Horizontal runs of 3+
for (int r = 0; r < ROWS; ++r) {
for (int c = 0; c < COLS - 2; ) {
int t = board.cells[r][c].type;
int len = 1;
while (c + len < COLS && board.cells[r][c+len].type == t) ++len;
if (len >= 3) matches.push_back({r, c, len, true});
c += len;
}
}
// Vertical runs of 3+
for (int c = 0; c < COLS; ++c) {
for (int r = 0; r < ROWS - 2; ) {
int t = board.cells[r][c].type;
int len = 1;
while (r + len < ROWS && board.cells[r+len][c].type == t) ++len;
if (len >= 3) matches.push_back({r, c, len, false});
r += len;
}
}
return matches;
}
Animations with Lerp
struct SwapAnim {
int r1,c1, r2,c2;
float t = 0.0f; // 0..1 animation progress
bool done() const { return t >= 1.0f; }
// Returns animated position of cell (r1,c1)
Vector2 PosA(float dt) {
t = std::min(1.0f, t + dt * 5.0f); // 0.2s swap
Vector2 from(c1*CELL, r1*CELL), to(c2*CELL, r2*CELL);
return Vector2::Lerp(from, to, t);
}
Vector2 PosB(float dt) {
Vector2 from(c2*CELL, r2*CELL), to(c1*CELL, r1*CELL);
return Vector2::Lerp(from, to, t);
}
};
Undo/redo stack
struct Move { int r1,c1, r2,c2; };
class UndoStack {
public:
void Push(Move m) { undos_.push_back(m); redos_.clear(); }
bool CanUndo() const { return !undos_.empty(); }
bool CanRedo() const { return !redos_.empty(); }
Move PopUndo() { auto m = undos_.back(); undos_.pop_back(); redos_.push_back(m); return m; }
Move PopRedo() { auto m = redos_.back(); redos_.pop_back(); undos_.push_back(m); return m; }
private:
std::vector<Move> undos_, redos_;
};