From 80917a8b79b0052d07060143fff346eddd189786 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 25 Mar 2024 17:27:15 +0100 Subject: Add support for QRCode login --- src/snake.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 6 deletions(-) (limited to 'src/snake.cpp') diff --git a/src/snake.cpp b/src/snake.cpp index e855250..8d45dd9 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -22,11 +22,13 @@ #define CELL_BREAKOUT_BRICK 4 #define CELL_SNAKEBRICK 5 #define CELL_PADDLE 6 +#define CELL_GOL 7 #define AXIS_X 0 #define AXIS_Y 1 #define FIELD(x,y) _field[(x) + ((y) * _width)] +#define FIELD2(x,y) _field2[(x) + ((y) * _width)] struct Paddle; @@ -38,15 +40,17 @@ struct Cell Cell(int t, QColor c) : type(t), color(QBrush(c)), player(nullptr) {} bool isFood() const { return type == CELL_FOOD; } bool willKill() const { return type == CELL_PADDLE_BACKING | type == CELL_PADDLE || type == CELL_SNAKE || type == CELL_SNAKEBRICK; } - bool isFree() const { return type == CELL_FREE; } - bool isPaddleFree() const { return type == CELL_FREE || type == CELL_SNAKEBRICK || type == CELL_BREAKOUT_BRICK || type == CELL_FOOD; } + bool isFree() const { return type == CELL_FREE || type == CELL_GOL; } + bool isPaddleFree() const { return type == CELL_FREE || type == CELL_SNAKEBRICK || type == CELL_BREAKOUT_BRICK || type == CELL_FOOD || type == CELL_GOL; } bool isBrick() const { return type == CELL_BREAKOUT_BRICK || type == CELL_SNAKEBRICK; } - bool canSpawnFood() const { return type == CELL_SNAKE || type == CELL_FREE || type == CELL_BREAKOUT_BRICK; } - bool ballWillDestroy() const { return isFood() || isBrick(); } + bool canSpawnFood() const { return type == CELL_SNAKE || type == CELL_FREE || type == CELL_BREAKOUT_BRICK || type == CELL_GOL; } + bool ballWillDestroy() const { return isFood() || isBrick() || type == CELL_GOL; } + bool isAlive() const { return type == CELL_FOOD || type == CELL_BREAKOUT_BRICK || type == CELL_GOL; } }; static const Cell empty(CELL_FREE, QColor()); static const Cell snakebrick(CELL_SNAKEBRICK, QColor::fromRgb(200, 200, 200)); +static const Cell golBrick(CELL_GOL, QColor::fromRgb(180, 200, 220)); static Cell breakoutCenterBrick(CELL_BREAKOUT_BRICK, QColor::fromRgb(255, 255, 255)); static const Cell food[] = { Cell(CELL_FOOD, QColor::fromRgb(0, 255, 0)), @@ -133,6 +137,8 @@ public: }; void GameCore::setField(int x, int y, const Cell *val) { + if (_field[x + _width * y] == val) + return; _field[x + _width * y] = val; _widget->update(x * SCALING, y * SCALING, SCALING, SCALING); } @@ -151,6 +157,7 @@ GameCore::GameCore(QWidget *widget) return; int cellCount = _width * _height; _field = (const Cell**)calloc(cellCount, sizeof(*_field)); + _field2 = (const Cell**)calloc(cellCount, sizeof(*_field)); for (int i = 0; i < cellCount; ++i) { _field[i] = ∅ } @@ -462,7 +469,53 @@ GameCore::GameCore(QWidget *widget) } } // Done with movement logic } // End loop over paddles - } + } // End paddles + // Game of life + if (tick % 13 == 0) { + auto **tmp = _field; + _field = _field2; + _field2 = tmp; + memcpy(_field, _field2, _width * _height * sizeof(void*)); + bool killall = ((tick / 4000) % 2); + int killed = 0; + for (int y = 0; y < _height; ++y) { + for (int x = 0; x < _width; ++x) { + if (FIELD2(x,y) != &golBrick && FIELD2(x,y) != &empty) { + FIELD(x,y) = FIELD2(x,y); + continue; + } + if (killall) { + if (FIELD2(x,y) == &golBrick) { + setField(x,y, &empty); + if (++killed > 5) { + goto endgol; + } + } + continue; + } + int alive = 0; + // Direct + if (x > 0 && FIELD2(x-1,y)->isAlive()) alive++; + if (y > 0 && FIELD2(x,y-1)->isAlive()) alive++; + if (x+1 < _width && FIELD2(x+1,y)->isAlive()) alive++; + if (y+1 < _height && FIELD2(x,y+1)->isAlive()) alive++; + // Diagonal + if (x > 0 && y > 0 && FIELD2(x-1,y-1)->isAlive()) alive++; + if (x > 0 && y+1 < _height && FIELD2(x-1,y+1)->isAlive()) alive++; + if (y > 0 && x+1 < _width && FIELD2(x+1,y-1)->isAlive()) alive++; + if (x+1 < _width && y+1 < _height && FIELD2(x+1,y+1)->isAlive()) alive++; + // Check + if (alive < 2 || alive > 3) { + setField(x,y, &empty); + } else if (alive == 3) { + setField(x,y, &golBrick); + } else { + FIELD(x,y) = FIELD2(x,y); + } + } + } +endgol:; + } // End GOL }); } @@ -623,7 +676,7 @@ void GameCore::paint(QPaintEvent *event) if (x < 0) continue; const Cell *c = FIELD(x, y); - if (c->isFree()) + if (c == &empty) continue; p.setBrush(c->color); p.drawRect(x * SCALING, y * SCALING, SCALING-1, SCALING-1); -- cgit v1.2.3-55-g7522