#include "field.h" /* Fields: std::vector> field; Private methods: std::vector processLine(const std::vector &sourceLine); std::vector getRow(size_t idx); std::vector getColumn(size_t idx); void setRow(size_t idx); void setColumn(size_t idx); Public methods: void moveUp(); void moveDown(); void moveLeft(); void moveRight(); */ // PRIVATE Line& Field::getRow(size_t rowIndex) const { return this->field[rowIndex]; } Line& Field::getColumn(size_t columnIndex) const { // from top to bottom Line column; for (size_t i = 0; i < this->FieldSize; ++i) { column.push_back(this->field[i][columnIndex]); } return column; } void Field::setRow(size_t rowIndex, const Line &line) { this->field[rowIndex] = line; } void Field::setColumn(size_t columnIndex, const Line &line) { // from top to bottom (same) for (size_t i = 0; i < this->FieldSize; ++i) { this->field[i][columnIndex] = line[i]; } } void Field::reset() { this->field.resize(this->FieldSize); for (size_t i = 0; i < this->FieldSize; ++i) { this->field[i] = Line(this->FieldSize); } } // PUBLIC Field::Field(size_t fieldSize) : mt(std::random_device{}()), FieldSize(fieldSize) { this->reset(); } void printVector(const Line &arr) { for (size_t i = 0; i < arr.size(); ++i) { printf("%llu ", arr[i]); } printf("\n"); } bool Field::moveUp() { auto oldField = this->field; for (size_t i = 0; i < this->FieldSize; ++i) { Line column; column = getColumn(i); column.process(); setColumn(i, column); } return this->field != oldField; } bool Field::moveDown() { auto oldField = this->field; for (size_t i = 0; i < this->FieldSize; ++i) { Line column; column = getColumn(i); std::reverse(column.begin(), column.end()); column.process(); std::reverse(column.begin(), column.end()); setColumn(i, column); } return this->field != oldField; } bool Field::moveLeft() { auto oldField = this->field; Line row; for (size_t i = 0; i < this->FieldSize; ++i) { row = getRow(i); row.process(); setRow(i, row); } return this->field != oldField; } bool Field::moveRight() { auto oldField = this->field; Line row; for (size_t i = 0; i < this->FieldSize; ++i) { row = getRow(i); std::reverse(row.begin(), row.end()); row.process(); std::reverse(row.begin(), row.end()); setRow(i, row); } return this->field != oldField; } std::vector Field::getEmptyTiles() const { std::vector empty; for (size_t i = 0; i < this->FieldSize; ++i) { for (size_t j = 0; j < this->FieldSize; ++j) { if (this->field[i][j] == 0) { empty.push_back(Position(i, j)); } } } return empty; } bool Field::spawnTile(const std::vector &empty) { if (!empty.empty()) { std::uniform_int_distribution<> dist(0, static_cast(empty.size() - 1)); std::uniform_int_distribution<> chance(1, 10); int choice = dist(this->mt); Position spawnPoint = empty[choice]; this->field[spawnPoint.x][spawnPoint.y] = ((chance(this->mt) == 10) ? 4 : 2); return true; } return false; } void Field::debug() const { for (size_t i = 0; i < this->FieldSize; ++i) { for (size_t j = 0; j < this->FieldSize; ++j) { printf("%5llu ", this->field[i][j]); } printf("\n"); } }